blob: 8e41f61fde8543bdaf914e5e86aea8745520286e [file] [log] [blame]
From cc84e464e882528286dffb8cefb463478690c4e1 Mon Sep 17 00:00:00 2001
From: Nicolas Boichat <drinkcat@chromium.org>
Date: Thu, 7 Mar 2019 18:17:32 +0800
Subject: [PATCH 1/3] MTK-TOT 202
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1317245/202
Add regulators, change required DT entries.
BUG=b:124335972
TEST=Boot kukui P2
Change-Id: I9992bb3b1427a3baf20fe99c08e2252d9900d83d
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
Revert "FROMLIST: arm64: dts: add display nodes for mt8183"
This reverts commit a19d712b63adaa622bdb7b43ddb1323b81de5847.
BUG=b:130781510
TEST=boot to shell
Change-Id: I082ce8df0b38f35abb6605cda40058dd44174957
Signed-off-by: CK Hu <ck.hu@mediatek.com>
BACKPORT: FROMLIST: arm64: dts: add display nodes for mt8183
This patch add display nodes for mt8183
Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.com>
(am from https://patchwork.kernel.org/patch/10976719/)
BUG=b:130781510
TEST=boot to welcome screen
Change-Id: Ia099f934da5d1f762e6337e9f48667883518a3fa
Signed-off-by: CK Hu <ck.hu@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
CHROMIUM: drm/panel: panel-innolux: Allow 2 reset pins for panel
This is useful when there is a bridge between the SoC and the
panel.
BUG=b:123669273
TEST=Boot rev2
[rebase note: see b/124335972 for justification of CHROMIUM tag]
Change-Id: I487b27f858a262c9bfea16aab8b0321229846025
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
CHROMIUM: drm/panel: panel-innolux: Add support for P097PFZ behind SSD2858
Add commands to setup P097PFZ behing SSD2858 (4 to 8 lanes bridge).
For some unclear reasons, the initialization commands that P097PFZ
is supposed to require... don't seem to be required (and actually
break display if we sent them).
We also need to change the code that sends the MIPI commands to add
necessary delays.
BUG=b:123669273
TEST=Boot kukui rev2
[rebase note: see b/124335972 for justification of CHROMIUM tag.
To make this cleaner, we should probably use a proper DRM bridge to
setup the bridge (instead of hacking the panel driver).]
Change-Id: I0cbe84a496bfd029be4db1fe05e316659eab3468
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
DO-NOT-SUBMIT: QCA wifi patches SQUASH
SQUASH of kukui wifi tot #32
including:
basic functionality:
None
bug fix:
DO-NOT-SUBMIT: kukui: ath10k: move some warning msg to dbg(CL:1639747/1)
FROMLIST: ath10k: add report MIC error for sdio chip(CL:1630539/2)
FROMLIST: ath10k: change firmware file name for UTF mode of SDIO/USB(CL:1628527/2)
FROMLIST: ath10k: add missing error handling(CL:1627070/4)
FROMLIST: ath10k: acquire lock to fix lockdep's warning(CL:1594406/10)
FROMLIST: ath10k: remove mmc_hw_reset while hif power down(CL:1585667/14)
FROMLIST: ath10k: add support for firmware crash recovery on SDIO chip(CL:1568867/19)
BUG=b:121980879
TEST=1) checkout CL:1317245/195
2) revert 1b6091c(old suqash)
3) rebase on m/master
4) cherry-pick this one
5) build, boot and check wifi connection
Change-Id: Iaebb8cf6f4604ec52b6a0b8500aef5d2d20b182c
DO-NOT-SUBMIT: Kukui ToT
Minimal set of patches to boot kukui
BUG=b:109911488
TEST=Boot to shell
Change-Id: I4b8194d5cd0b31670bb2ed7310747bed38775545
FROMLIST: pinctrl: mediatek: Ignore interrupts that are wake only during resume
Before suspending, mtk-eint would set the interrupt mask to the
one in wake_mask. However, some of these interrupts may not have a
corresponding interrupt handler, or the interrupt may be disabled.
On resume, the eint irq handler would trigger nevertheless,
and irq/pm.c:irq_pm_check_wakeup would be called, which would
try to call irq_disable. However, if the interrupt is not enabled
(irqd_irq_disabled(&desc->irq_data) is true), the call does nothing,
and the interrupt is left enabled in the eint driver.
Especially for level-sensitive interrupts, this will lead to an
interrupt storm on resume.
If we detect that an interrupt is only in wake_mask, but not in
cur_mask, we can just mask it out immediately (as mtk_eint_resume
would do anyway at a later stage in the resume sequence, when
restoring cur_mask).
Fixes: bf22ff45bed ("genirq: Avoid unnecessary low level irq function calls")
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
(am from https://patchwork.kernel.org/patch/10921143/)
(also found at https://lkml.kernel.org/r/20190429035515.73611-2-drinkcat@chromium.org)
BUG=b:129240721
TEST=on kukui, EC can wake system from suspend
Change-Id: Ic38985aa7c4dd4a4c5ad6595809ac8a4bc320ace
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
FROMLIST: pinctrl: mediatek: Update cur_mask in mask/mask ops
During suspend/resume, mtk_eint_mask may be called while
wake_mask is active. For example, this happens if a wake-source
with an active interrupt handler wakes the system:
irq/pm.c:irq_pm_check_wakeup would disable the interrupt, so
that it can be handled later on in the resume flow.
However, this may happen before mtk_eint_do_resume is called:
in this case, wake_mask is loaded, and cur_mask is restored
from an older copy, re-enabling the interrupt, and causing
an interrupt storm (especially for level interrupts).
Instead, we just record mask/unmask changes in cur_mask. This
also avoids the need to read the current mask in eint_do_suspend,
and we can remove mtk_eint_chip_read_mask function.
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
(am from https://patchwork.kernel.org/patch/10921147/)
(also found at https://lkml.kernel.org/r/20190429035515.73611-3-drinkcat@chromium.org)
BUG=b:129240721
TEST=on kukui, EC can wake system from suspend
Change-Id: I77d55cfb9ad3a0a0078f931695d6aeb8a6e5c217
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
WIP: usb: mtu3: Modification for MTU3 dualrole mode switch
Usage:
to host:
echo host > /sys/kernel/debug/usb/11201000.usb/mode
to device:
echo device > /sys/kernel/debug/usb/11201000.usb/mode
BUG=b:109911488
TEST=Boot to shell and do host/device mode change
Change-Id: Ie6d5b864ea36a40b959df6d06d4e038b7c3d74ee
Signed-off-by: Jumin Li <jumin.li@mediatek.com>
CHROMIUM: arm64: dts: mt8183: Add manual switch property
Enable manual dual mode
Set maximum-speed as high-speed
BUG=b:109911488
TEST=build and boot to shell and do usb features test
Change-Id: Iea92b3d15823229cf9816275b22cc582ad470aa9
Signed-off-by: Jumin Li <jumin.li@mediatek.com>
DO-NOT-SUBMIT: Snapshot of CMDQ ToT
Snapshot of CMDQ ToT patch set 11 (FROMLIST v3)
BUG=b:109911488
TEST=Display UI
Change-Id: Ie936fd7f2c16875d16a1cb87402a23d2609fa303
Signed-off-by: CK Hu <ck.hu@mediatek.com>
BACKPORT: FROMLIST: arm64: dts: add gce node for mt8183
add gce device node for mt8183
(am from https://patchwork.kernel.org/patch/10932479/)
BUG=b:109911488
TEST=build and boot to shell
Change-Id: I1edbdd1be9db1f128d984adc81895cb80c61e4eb
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Signed-off-by: CK Hu <ck.hu@mediatek.com>
DO-NOT-SUBMIT: Snapshot of VPU patches
Snapshot of VPU patches.
BUG=b:109911488
TEST=Boot to shell
Change-Id: I47a3afb7edafea353eea566d3fe6468feeedf9cd
Signed-off-by: CK Hu <ck.hu@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
DO-NOT-SUBMIT: arm64: dts: mt8183: add vpu node
New add vpu node
BUG=b:109911488
TEST=build and boot to shell
Change-Id: I0868a628e8c9f30e550ad034fd786ea566ca044b
Signed-off-by: Erin Lo <erin.lo@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
FROMLIST: dt-bindings: soc: Add MT8183 emi dt-bindings
Add emi dt-bindings of MT8183 in binding document.
Signed-off-by: Xi Chen <xixi.chen@mediatek.com>
(am from https://patchwork.kernel.org/patch/10921319/)
[eddie.huang: remove change-id in commit message]
BUG=b:109911488
TEST=build pass and boot to shell
Change-Id: I7182f3eda5835af8bf081d1056228bf73cb63f61
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
BACKPORT: FROMLIST: arm64: dts: mt8183: add emi node
Add emi dts node.
(am from https://patchwork.kernel.org/patch/10921629/)
[eddie.huang: remove change-id in commit message.
Fix context confclit]
BUG=b:109911488
TEST=build pass and boot to shell
Change-Id: I0b84e566d20af6fcb33b91f69be2f14f40a6e540
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
BACKPORT: FROMLIST: mt8183: emi: add bandwidth driver support
EMI provides interface for get bandwidth on every 1 miliseconds.
Currently, just support GPU bandwidth info.
Signed-off-by: Xi Chen <xixi.chen@mediatek.com>
(am from https://patchwork.kernel.org/patch/10921627/)
[eddie.huang: fix context confclit. Remove change-id in commit message.
Add MTK_EMI_MBW description to let defconfig to select]
BUG=b:109911488
TEST=build pass and boot to shell
Change-Id: I10d8f36d78c1dca8d91bc0e242fe83209a6c8190
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
WIP: clk: mediatek: mt8183: Register 13MHz clock earlier for clocksource
The 13MHz clock should be registered before clocksource driver is
initialized. Use CLK_OF_DECLARE_DRIVER() to guarantee.
BUG=b:126007177
TEST=build and boot to shell
Change-Id: I63f1c881bb4053da4214ddb14d725b37fd108ffd
Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
Signed-off-by: Dehui Sun <dehui.sun@mediatek.com>
WIP: arm64: dts: mt8183: add systimer0 node
Add systimer0 node to the mt8183's devicetree.
BUG=b:109911488
BUG=None
TEST=build and boot to shell
Change-Id: I816152c47ad0aa86eb269b654d3a22d953f60c81
Signed-off-by: Dehui Sun <dehui.sun@mediatek.com>
WIP: serial: 8250-mtk: modify serial driver
modify serial power management function.
BUG=b:129106594
TEST=build and boot to shell
Change-Id: I23051b5f23ad314be518fce994d7affb2a8b1a27
Signed-off-by: Changqi Hu <changqi.hu@mediatek.com>
WIP: thermal: mtk_thermal: add suspend/resume callback
Added suspend/resume callback to disable/enable Mediatek thermal sensor
respectively. Since thermal power domain is off in suspend, thermal driver
needs re-initialization during resume.
BUG=none
TEST: boot to shell
Change-Id: I43f9af5c2d2b682f985eb570d6ed984243772e91
Signed-off-by: Louis Yu <louis.yu@mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
HACK: clkdbg: clkdbg support for 8183
Clkdbg provides commands to view clock info and operate clocks,
such as enable/disable clocks and change their rate. Use the
following command to see available clkdbg commands:
.
echo cmds > /proc/clkdbg ; cat /proc/clkdbg
.
BUG=b:109911488
TEST=build and boot to shell
Change-Id: Ieb6a05b7f5ee9330cd10a02fafbdfc6654163f5e
Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
HACK: clkchk: add clkchk support for 8183
dump the clocks those still ON during system suspend
BUG=b:109911488
TEST=build and boot to shell
Change-Id: Ifb7a0d683aed75b57161b27d76efd4318395dbca
Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
HACK: sdio: mediatek: add sdio debug driver
New add sdio debug driver
BUG=b:109911488
TEST=cmd test is ok
Change-Id: Id1f53eb395a035caffc03a3a6f0e6c554c63a9ad
Signed-off-by: jjian zhou <jjian.zhou@mediatek.com>
CHROMIUM: config: Enable MT8183 usb dualrole mode configs
Features be enabled as follow:
USB mtu3 dualrole mode
USB gadget configfs functions
USB gadget ACM/MASS_STORAGE/SERIAL features
The change is generated from the following commands:
cat <<EOF | tee -a \
chromeos/config/arm64/chromiumos-arm64.flavour.config \
chromeos/config/arm64/chromiumos-mediatek.flavour.config
CONFIG_USB_CONFIGFS=m
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_F_ACM=y
CONFIG_USB_F_FS=m
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_F_SERIAL=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_USB_MTU3_DUAL_ROLE=y
EOF
./chromeos/scripts/kernelconfig olddefconfig
BUG=b:109911488
TEST=build and boot to shell and test the function of these configs
Change-Id: Ie957cae98b3331668f4e29332c25714776e5fe80
Signed-off-by: Jumin Li <jumin.li@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
CHROMIUM: config: Enable MT8183 emi configs
The change is generated from the following commands:
cat <<EOF | tee -a \
chromeos/config/arm64/chromiumos-arm64.flavour.config \
chromeos/config/arm64/chromiumos-mediatek.flavour.config
CONFIG_MTK_EMI_MBW=y
EOF
./chromeos/scripts/kernelconfig olddefconfig
BUG=b:109911488
TEST=build and boot to shell
Change-Id: I9c92096719b72c077258a5d2b52b3ccec272af39
Signed-off-by: Xi Chen <xixi.chen@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
FROMLIST: PM / devfreq: Generic CPU frequency to device frequency mapping governor
Many CPU architectures have caches that can scale independent of the CPUs.
Frequency scaling of the caches is necessary to make sure the cache is not
a performance bottleneck that leads to poor performance and power. The same
idea applies for RAM/DDR.
To achieve this, this patch adds a generic devfreq governor that takes the
current frequency of each CPU frequency domain and then adjusts the
frequency of the cache (or any devfreq device) based on the frequency of
the CPUs. It listens to CPU frequency transition notifiers to keep itself
up to date on the current CPU frequency.
To decide the frequency of the device, the governor does one of the
following:
* Uses a CPU frequency to device frequency mapping table
- Either one mapping table used for all CPU freq policies (typically used
for system with homogeneous cores/clusters that have the same OPPs).
- One mapping table per CPU freq policy (typically used for ASMP systems
with heterogeneous CPUs with different OPPs)
OR
* Scales the device frequency in proportion to the CPU frequency. So, if
the CPUs are running at their max frequency, the device runs at its max
frequency. If the CPUs are running at their min frequency, the device
runs at its min frequency. And interpolated for frequencies in between.
Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
(am from https://patchwork.kernel.org/patch/10553171/)
BUG=b:122571050
TEST=boot to kukui
Change-Id: I299eecb1f1bb12679fcb394a28fb2655760568d2
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
CHROMIUM: config: Enable cpufreq-map governor for mtk-cci
cat <<EOF | tee -a \
chromeos/config/arm64/chromiumos-mediatek.flavour.config
CONFIG_DEVFREQ_GOV_CPUFREQ_MAP=y
EOF
./chromeos/scripts/kernelconfig olddefconfig
BUG=b:122571050
TEST=echo cpufreq-map > /sys/class/devfreq/devfreq0/governor;
observe /sys/class/devfreq/devfreq0/trans_stat
Change-Id: Ie822b0fc47dc04a9019383dd079854b73e8840e9
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
CHROMIUM: arm64: dts: mt8183: set devfreq-cpufreq-map for mt8183-cci
Set cpu frequency to cci frequency mapping table.
BUG=b:122571050
TEST=boot to kukui
Change-Id: I531cd70c98fc86155eb99a932737cb3ed0d02fb5
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
WIP: devfreq: mt8183-cci: using cpufreq-map governor in cci dvfs driver
1. remove mtk_cci_vmon governor, using cpufreq-map
2. SVS: TBD
BUG=b:122571050
TEST=cat /sys/class/devfreq/devfreq0/governor
TEST=run speedometer
Change-Id: I4c4da92dde5f369aaf07a55761f3f9cdc9e80f44
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
BACKPORT: FROMLIST: arm64: dts: mt8183: Enable CPU idle-states
Enable mcdi-cpu and mcdi-cluster on MT8183 CPUs.
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
(am from https://patchwork.kernel.org/patch/10966475/)
[eddie.huang: fix context conflicts]
BUG=b:109911488
TEST=build pass and boot to shell
Change-Id: Ic8c577b296ab4416cfb60267120c0da990dd49f7
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
FIXUP: arm64: dts: mediatek: Modify opp table for cpu big cluster for mt8183
Modify opp table for cpu big cluster for mt8183
BUG=b:129039370
TEST=build and boot to shell
Change-Id: I54569c513c36db0e08011d0a4f474b1e8808ae3a
Signed-off-by: Andrew-sh.Cheng <andrew-sh.cheng@mediatek.com>
DO-NOT-SUBMIT: Snapshot of iommu tot
Snapshot of iommu tot. (CL:1369894/26)
BUG=b:109911488
TEST=Boot to shell
Change-Id: Iec62b81c8e3162110723d7b6e6e759d3672b3af8
Signed-off-by: CK Hu <ck.hu@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
WIP: arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.
Change-Id: I3b4457af3df3bc51705af618cb09085953fbcd12
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
WIP: drm/panel: add panel driver for boe-tv101wum
BUG=b:129299873
TEST=build and boot to shell
Change-Id: I08d1ddb1a2d368ccbcd1e358cb5e302b8161328b
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
CHROMIUM: config: enable boe TV101WUM panel support
The change is generated from the following commands:
cat <<EOF | tee -a \
chromeos/config/arm64/chromiumos-arm64.flavour.config \
chromeos/config/arm64/chromiumos-mediatek.flavour.config
CONFIG_DRM_PANEL_BOE_TV101WUM=y
EOF
./chromeos/scripts/kernelconfig olddefconfig
BUG=b:129299873
TEST=build and boot to shell
Change-Id: Ice61a327f17e69bd2207a9033dda7460ec078765
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
CHROMIUM: arm64: dts: mt8183: add krane rev3 board dts and Makefile
add krane rev3 board dts and Makefile
BUG=b:131115073
TEST=build and boot to shell
Change-Id: I65906cf9a89353c3040e751b85bd2f9710f74802
Signed-off-by: Ben Ho <Ben.Ho@mediatek.com>
CHROMIUM: arm64: dts: mt8183-kukui: add wifi power controller
To comply with schematic design, remove gpio119 from
mmc1_fixed_power and add it back as wlan_en pin in
mmc1default. msdcpll is only for mmc module. Assign
msdcpll to mmc1 clk for avoiding unexpected changes.
BUG=b:131043339
TEST=Cherry-pick and update kernel with
https://crrev.com/c/1585667. Make sure SDIO clk
is running at 200MHz correctly by checking
/sys/kernel/debug/mmc1/ios
Change-Id: I325df93ae939e929618f7234f18c674cce4e4138
Signed-off-by: jjian zhou <jjian.zhou@mediatek.com>
Signed-off-by: Ayo Wu <ayowu@chromium.org>
DO-NOT-SUBMIT: Kukui MTK ToT
Collect MTK patches on chromeos-4.19
BUG=b:109911488
TEST=Boot to shell
Change-Id: Ifed5c7cb2dacf916c2ac41c4a70f07215f46f0d7
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
---
.../bindings/devfreq/devfreq-cpufreq-map.txt | 53 +
.../display/mediatek/mediatek,disp.txt | 9 -
.../devicetree/bindings/mailbox/mtk-gce.txt | 37 +-
.../bindings/media/mediatek-jpeg-decoder.txt | 4 -
.../bindings/media/mediatek-mdp.txt | 8 -
.../bindings/media/mediatek-vcodec.txt | 4 -
.../bindings/media/mediatek-vpu.txt | 2 +-
.../memory-controllers/mediatek,emi.txt | 19 +
Makefile | 1 +
README | 1 +
arch/arm64/boot/dts/mediatek/Makefile | 1 +
.../boot/dts/mediatek/mt8183-krane-rev3.dts | 325 +++
.../boot/dts/mediatek/mt8183-kukui-rev2.dts | 139 +
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 25 +-
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 152 +-
.../arm64/chromiumos-arm64.flavour.config | 7 +-
.../arm64/chromiumos-mediatek.flavour.config | 8 +-
drivers/clk/mediatek/Makefile | 2 +
drivers/clk/mediatek/clk-mt8183.c | 49 +-
drivers/clk/mediatek/clkchk-mt8183.c | 387 +++
drivers/clk/mediatek/clkchk.c | 188 ++
drivers/clk/mediatek/clkchk.h | 18 +
drivers/clk/mediatek/clkdbg-mt8183.c | 865 +++++++
drivers/clk/mediatek/clkdbg.c | 2242 +++++++++++++++++
drivers/clk/mediatek/clkdbg.h | 83 +
drivers/devfreq/Kconfig | 8 +
drivers/devfreq/Makefile | 1 +
drivers/devfreq/governor_cpufreq_map.c | 583 +++++
drivers/devfreq/mt8183-cci-devfreq.c | 194 +-
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 11 -
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 27 -
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 1 -
drivers/gpu/drm/panel/Kconfig | 9 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-boe-tv101wum.c | 708 ++++++
drivers/gpu/drm/panel/panel-innolux-p079zca.c | 139 +-
drivers/iommu/mtk_iommu.c | 40 +-
drivers/iommu/mtk_iommu_v1.c | 32 +-
drivers/mailbox/Kconfig | 18 +
drivers/mailbox/Makefile | 1 +
drivers/mailbox/mtk-cmdq-debug.c | 582 +++++
drivers/mailbox/mtk-cmdq-debug.h | 21 +
drivers/mailbox/mtk-cmdq-mailbox.c | 99 +-
.../media/platform/mtk-jpeg/mtk_jpeg_core.c | 22 -
.../media/platform/mtk-jpeg/mtk_jpeg_core.h | 2 -
drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 38 -
drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 -
drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 1 -
.../platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 19 -
.../platform/mtk-vcodec/mtk_vcodec_drv.h | 3 -
.../platform/mtk-vcodec/mtk_vcodec_enc.c | 1 -
.../platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 44 -
drivers/media/platform/mtk-vpu/mtk_vpu.c | 425 +++-
drivers/media/platform/mtk-vpu/mtk_vpu.h | 25 +
drivers/memory/Kconfig | 9 +
drivers/memory/Makefile | 1 +
drivers/memory/mtk-emi.c | 412 +++
drivers/memory/mtk-smi.c | 30 +-
drivers/mmc/host/Makefile | 2 +-
drivers/mmc/host/mtk-sd.c | 5 +
drivers/mmc/host/mtk-sdio-proc.c | 342 +++
drivers/mmc/host/mtk-sdio-proc.h | 48 +
drivers/net/wireless/ath/ath10k/htt_rx.c | 22 +-
drivers/net/wireless/ath/ath10k/hw.h | 3 +
drivers/net/wireless/ath/ath10k/sdio.c | 18 +-
drivers/net/wireless/ath/ath10k/testmode.c | 17 +-
drivers/pinctrl/mediatek/mtk-eint.c | 34 +-
drivers/soc/mediatek/mtk-cmdq-helper.c | 215 +-
drivers/thermal/mtk_thermal.c | 140 +-
drivers/tty/serial/8250/8250_mtk.c | 50 +-
drivers/usb/mtu3/mtu3_core.c | 14 +-
drivers/usb/mtu3/mtu3_dr.c | 2 +-
include/dt-bindings/gce/mt8183-gce.h | 177 ++
include/linux/mailbox/mtk-cmdq-mailbox.h | 5 +
include/linux/soc/mediatek/mtk-cmdq.h | 62 +-
include/soc/mediatek/emi.h | 116 +
include/soc/mediatek/smi.h | 20 -
77 files changed, 8709 insertions(+), 721 deletions(-)
create mode 100644 Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt
create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,emi.txt
create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-krane-rev3.dts
create mode 100644 drivers/clk/mediatek/clkchk-mt8183.c
create mode 100644 drivers/clk/mediatek/clkchk.c
create mode 100644 drivers/clk/mediatek/clkchk.h
create mode 100644 drivers/clk/mediatek/clkdbg-mt8183.c
create mode 100644 drivers/clk/mediatek/clkdbg.c
create mode 100644 drivers/clk/mediatek/clkdbg.h
create mode 100644 drivers/devfreq/governor_cpufreq_map.c
create mode 100644 drivers/gpu/drm/panel/panel-boe-tv101wum.c
create mode 100644 drivers/mailbox/mtk-cmdq-debug.c
create mode 100644 drivers/mailbox/mtk-cmdq-debug.h
create mode 100644 drivers/memory/mtk-emi.c
create mode 100644 drivers/mmc/host/mtk-sdio-proc.c
create mode 100644 drivers/mmc/host/mtk-sdio-proc.h
mode change 100644 => 100755 drivers/tty/serial/8250/8250_mtk.c
create mode 100644 include/dt-bindings/gce/mt8183-gce.h
create mode 100644 include/soc/mediatek/emi.h
diff --git a/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt b/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt
new file mode 100644
index 000000000000..982a30bcfc86
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/devfreq-cpufreq-map.txt
@@ -0,0 +1,53 @@
+Devfreq CPUfreq governor
+
+devfreq-cpufreq-map is a parent device that contains one or more child devices.
+Each child device provides CPU frequency to device frequency mapping for a
+specific device. Examples of devices that could use this are: DDR, cache and
+CCI.
+
+Parent device name shall be "devfreq-cpufreq-map".
+
+Required child device properties:
+- cpu-to-dev-map, or cpu-to-dev-map-<X>:
+ A list of tuples where each tuple consists of a
+ CPU frequency (KHz) and the corresponding device
+ frequency. CPU frequencies not listed in the table
+ will use the device frequency that corresponds to the
+ next rounded up CPU frequency.
+ Use "cpu-to-dev-map" if all CPUs in the system should
+ share same mapping.
+ Use cpu-to-dev-map-<cpuid> to describe different
+ mappings for different CPUs. The property should be
+ listed only for the first CPU if multiple CPUs are
+ synchronous.
+- target-dev: Phandle to device that this mapping applies to.
+
+Example:
+ devfreq-cpufreq-map {
+ cpubw-cpufreq {
+ target-dev = <&cpubw>;
+ cpu-to-dev-map =
+ < 300000 1144000 >,
+ < 422400 2288000 >,
+ < 652800 3051000 >,
+ < 883200 5996000 >,
+ < 1190400 8056000 >,
+ < 1497600 10101000 >,
+ < 1728000 12145000 >,
+ < 2649600 16250000 >;
+ };
+
+ cache-cpufreq {
+ target-dev = <&cache>;
+ cpu-to-dev-map =
+ < 300000 300000 >,
+ < 422400 422400 >,
+ < 652800 499200 >,
+ < 883200 576000 >,
+ < 960000 960000 >,
+ < 1497600 1036800 >,
+ < 1574400 1574400 >,
+ < 1728000 1651200 >,
+ < 2649600 1728000 >;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 5467470c7b8a..bc8e30c20c64 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -59,8 +59,6 @@ Required properties (DMA function blocks):
"mediatek,<chip>-disp-rdma"
"mediatek,<chip>-disp-wdma"
the supported chips are mt2701 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
- in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- iommus: Should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -87,7 +85,6 @@ ovl0: ovl@1400c000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};
ovl1: ovl@1400d000 {
@@ -97,7 +94,6 @@ ovl1: ovl@1400d000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_OVL1>;
iommus = <&iommu M4U_PORT_DISP_OVL1>;
- mediatek,larb = <&larb4>;
};
rdma0: rdma@1400e000 {
@@ -107,7 +103,6 @@ rdma0: rdma@1400e000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};
rdma1: rdma@1400f000 {
@@ -117,7 +112,6 @@ rdma1: rdma@1400f000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb4>;
};
rdma2: rdma@14010000 {
@@ -127,7 +121,6 @@ rdma2: rdma@14010000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_RDMA2>;
iommus = <&iommu M4U_PORT_DISP_RDMA2>;
- mediatek,larb = <&larb4>;
};
wdma0: wdma@14011000 {
@@ -137,7 +130,6 @@ wdma0: wdma@14011000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA0>;
iommus = <&iommu M4U_PORT_DISP_WDMA0>;
- mediatek,larb = <&larb0>;
};
wdma1: wdma@14012000 {
@@ -147,7 +139,6 @@ wdma1: wdma@14012000 {
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
clocks = <&mmsys CLK_MM_DISP_WDMA1>;
iommus = <&iommu M4U_PORT_DISP_WDMA1>;
- mediatek,larb = <&larb4>;
};
color0: color@14013000 {
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7d72b21c9e94..755b30fd6041 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,7 @@ CMDQ driver uses mailbox framework for communication. Please refer to
mailbox.txt for generic information about mailbox device-tree bindings.
Required properties:
-- compatible: Must be "mediatek,mt8173-gce"
+- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
- reg: Address range of the GCE unit
- interrupts: The interrupt signal from the GCE block
- clock: Clocks according to the common clock binding
@@ -21,15 +21,31 @@ Required properties:
priority: Priority of GCE thread.
atomic_exec: GCE processing continuous packets of commands in atomic
way.
+- #event-cells: Should be 1.
+ <&phandle event_number>
+ phandle: Label name of a gce node.
+ event_number: the event number defined in 'dt-bindings/gce/mt8173-gce.h'
+ or 'dt-binding/gce/mt8183-gce.h'.
+- #subsys-cells: Should be 3.
+ <&phandle subsys_number start_offset size>
+ phandle: Label name of a gce node.
+ subsys_number: specify the sub-system id which is corresponding
+ to the register address.
+ start_offset: the start offset of register address that GCE can access.
+ size: the total size of register address that GCE can access.
Required properties for a client device:
- mboxes: Client use mailbox to communicate with GCE, it should have this
property and list of phandle, mailbox specifiers.
-- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
+Optional propertier for a client device:
+- mediatek,gce-client-reg: u32, specify the sub-system id which is corresponding
to the register address.
+- mediatek,gce-event-names: the event name can be defined by user.
+- mediatek,gce-events: u32, the event number defined in
+ 'dt-bindings/gce/mt8173-gce.h' or 'dt-binding/gce/mt8183-gce.h'.
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such as
-sub-system ids, thread priority, event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
+or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, event ids.
Example:
@@ -39,8 +55,9 @@ Example:
interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
clocks = <&infracfg CLK_INFRA_GCE>;
clock-names = "gce";
- thread-num = CMDQ_THR_MAX_COUNT;
#mbox-cells = <3>;
+ #event-cells = <1>;
+ #subsys-cells = <2>;
};
Example for a client device:
@@ -49,9 +66,11 @@ Example for a client device:
compatible = "mediatek,mt8173-mmsys";
mboxes = <&gce 0 CMDQ_THR_PRIO_LOWEST 1>,
<&gce 1 CMDQ_THR_PRIO_LOWEST 1>;
- mediatek,gce-subsys = <SUBSYS_1400XXXX>;
- mutex-event-eof = <CMDQ_EVENT_MUTEX0_STREAM_EOF
- CMDQ_EVENT_MUTEX1_STREAM_EOF>;
-
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>,
+ <&gce SUBSYS_1401XXXX 0x2000 0x100>;
+ mediatek,gce-event-names = "rdma0_sof",
+ "rsz0_sof";
+ mediatek,gce-events = <&gce CMDQ_EVENT_MDP_RDMA0_SOF>,
+ <&gce CMDQ_EVENT_MDP_RSZ0_SOF>;
...
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
index 3813947b4d4f..c9f89132830c 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
@@ -14,9 +14,6 @@ Required properties:
- clock-names: must contain "jpgdec-smi" and "jpgdec".
- power-domains: a phandle to the power domain, see
Documentation/devicetree/bindings/power/power_domain.txt for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
@@ -31,7 +28,6 @@ Example:
clock-names = "jpgdec-smi",
"jpgdec";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
- mediatek,larb = <&larb2>;
iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
<&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index 0d03e3ae2be2..df69c5a06250 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,9 +27,6 @@ Required properties (DMA function blocks, child node):
- iommus: should point to the respective IOMMU block with master port as
argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
- Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- for details.
Example:
mdp_rdma0: rdma@14001000 {
@@ -40,7 +37,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
- mediatek,larb = <&larb0>;
mediatek,vpu = <&vpu>;
};
@@ -51,7 +47,6 @@ Example:
<&mmsys CLK_MM_MUTEX_32K>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_RDMA1>;
- mediatek,larb = <&larb4>;
};
mdp_rsz0: rsz@14003000 {
@@ -81,7 +76,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WDMA>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WDMA>;
- mediatek,larb = <&larb0>;
};
mdp_wrot0: wrot@14007000 {
@@ -90,7 +84,6 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT0>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT0>;
- mediatek,larb = <&larb0>;
};
mdp_wrot1: wrot@14008000 {
@@ -99,5 +92,4 @@ Example:
clocks = <&mmsys CLK_MM_MDP_WROT1>;
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
iommus = <&iommu M4U_PORT_MDP_WROT1>;
- mediatek,larb = <&larb4>;
};
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
index b6b5dde6abd8..5c9ee6af3cfa 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
@@ -9,7 +9,6 @@ Required properties:
- reg : Physical base address of the video codec registers and length of
memory mapped region.
- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
- clocks : list of clock specifiers, corresponding to entries in
the clock-names property.
- clock-names: encoder must contain "venc_sel_src", "venc_sel",,
@@ -39,7 +38,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x16027800 0 0x800>, /*VP8_VL*/
<0 0x16028400 0 0x400>; /*VP9_VD*/
interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb1>;
iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
<&iommu M4U_PORT_HW_VDEC_PP_EXT>,
<&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -83,8 +81,6 @@ vcodec_dec: vcodec@16000000 {
<0 0x19002000 0 0x1000>; /*VENC_LT_SYS*/
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
- mediatek,larb = <&larb3>,
- <&larb5>;
iommus = <&iommu M4U_PORT_VENC_RCPU>,
<&iommu M4U_PORT_VENC_REC>,
<&iommu M4U_PORT_VENC_BSDMA>,
diff --git a/Documentation/devicetree/bindings/media/mediatek-vpu.txt b/Documentation/devicetree/bindings/media/mediatek-vpu.txt
index 2a5bac37f9a2..015123250b82 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vpu.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vpu.txt
@@ -4,7 +4,7 @@ Video Processor Unit is a HW video controller. It controls HW Codec including
H.264/VP8/VP9 Decode, H.264/VP8 Encode and Image Processor (scale/rotate/color convert).
Required properties:
- - compatible: "mediatek,mt8173-vpu"
+ - compatible:"mediatek,mt8173-vpu", "mediatek,mt8183-vpu", "mediatek,reserve-memory-vpu_share"
- reg: Must contain an entry for each entry in reg-names.
- reg-names: Must include the following entries:
"tcm": tcm base
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,emi.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,emi.txt
new file mode 100644
index 000000000000..a19e3b39ba66
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,emi.txt
@@ -0,0 +1,19 @@
+EMI (External Memory Interface)
+
+Required properties:
+- compatible : must be one of :
+ "mediatek,mt8183-emi"
+- reg : the register and size of the EMI block.
+- interrupts : includes MPU, CGM, ELM.
+
+Example:
+ emi@10219000 {
+ compatible = "mediatek,mt8183-emi";
+ reg = <0 0x10219000 0 0x1000>, /* CEN EMI */
+ <0 0x10226000 0 0x1000>, /* EMI MPU */
+ <0 0x1022d000 0 0x1000>, /* CHA EMI */
+ <0 0x10235000 0 0x1000>; /* CHB EMI */
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_LOW>, /* MPU */
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, /* CGM */
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* ELM */
+};
diff --git a/Makefile b/Makefile
index 1241e0120740..434373aa4d87 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,4 @@
+# kukui ToT!
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 19
diff --git a/README b/README
index 2c927ccbd970..768caa3970ef 100644
--- a/README
+++ b/README
@@ -1,3 +1,4 @@
+MTK TOT
Linux kernel
============
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 3a55c454b65d..d09409979c84 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,5 +8,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-krane-rev3.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-rev1.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-rev2.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-krane-rev3.dts b/arch/arm64/boot/dts/mediatek/mt8183-krane-rev3.dts
new file mode 100644
index 000000000000..4c71b09e26a3
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-krane-rev3.dts
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8183-kukui.dtsi"
+
+/ {
+ model = "MediaTek krane rev3 board";
+ compatible = "google,krane-rev3", "google,krane", "google,kukui", "mediatek,mt8183";
+};
+
+&i2c0 {
+ status = "okay";
+
+ touchscreen4: touchscreen@5d {
+ compatible = "hid-over-i2c";
+ reg = <0x5d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&open_touch>;
+
+ interrupt-parent = <&pio>;
+ interrupts = <155 IRQ_TYPE_EDGE_FALLING>;
+
+ post-power-on-delay-ms = <10>;
+ hid-descr-addr = <0x0001>;
+ };
+};
+
+&pio {
+ /* 192 lines */
+ gpio-line-names =
+ "SPI_AP_EC_CS_L",
+ "SPI_AP_EC_MOSI",
+ "SPI_AP_EC_CLK",
+ "I2S3_DO",
+ "USB_PD_INT_ODL",
+ "",
+ "",
+ "",
+ "",
+ "IT6505_HPD_L",
+ "I2S3_TDM_D3",
+ "SOC_I2C6_1V8_SCL",
+ "SOC_I2C6_1V8_SDA",
+ "DPI_D0",
+ "DPI_D1",
+ "DPI_D2",
+ "DPI_D3",
+ "DPI_D4",
+ "DPI_D5",
+ "DPI_D6",
+ "DPI_D7",
+ "DPI_D8",
+ "DPI_D9",
+ "DPI_D10",
+ "DPI_D11",
+ "DPI_HSYNC",
+ "DPI_VSYNC",
+ "DPI_DE",
+ "DPI_CK",
+ "AP_MSDC1_CLK",
+ "AP_MSDC1_DAT3",
+ "AP_MSDC1_CMD",
+ "AP_MSDC1_DAT0",
+ "AP_MSDC1_DAT2",
+ "AP_MSDC1_DAT1",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "OTG_EN",
+ "DRVBUS",
+ "DISP_PWM",
+ "DSI_TE",
+ "LCM_RST_1V8",
+ "AP_CTS_WIFI_RTS",
+ "AP_RTS_WIFI_CTS",
+ "SOC_I2C5_1V8_SCL",
+ "SOC_I2C5_1V8_SDA",
+ "SOC_I2C3_1V8_SCL",
+ "SOC_I2C3_1V8_SDA",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "SOC_I2C1_1V8_SDA",
+ "SOC_I2C0_1V8_SDA",
+ "SOC_I2C0_1V8_SCL",
+ "SOC_I2C1_1V8_SCL",
+ "AP_SPI_H1_MISO",
+ "AP_SPI_H1_CS_L",
+ "AP_SPI_H1_MOSI",
+ "AP_SPI_H1_CLK",
+ "I2S5_BCK",
+ "I2S5_LRCK",
+ "I2S5_DO",
+ "BOOTBLOCK_EN_L",
+ "MT8183_KPCOL0",
+ "SPI_AP_EC_MISO",
+ "UART_DBG_TX_AP_RX",
+ "UART_AP_TX_DBG_RX",
+ "I2S2_MCK",
+ "I2S2_BCK",
+ "CLK_5M_WCAM",
+ "CLK_2M_UCAM",
+ "I2S2_LRCK",
+ "I2S2_DI",
+ "SOC_I2C2_1V8_SCL",
+ "SOC_I2C2_1V8_SDA",
+ "SOC_I2C4_1V8_SCL",
+ "SOC_I2C4_1V8_SDA",
+ "",
+ "SCL8",
+ "SDA8",
+ "FCAM_PWDN_L",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "I2S_PMIC",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ /*
+ * AP_FLASH_WP_L is crossystem ABI. Rev1 schematics
+ * call it BIOS_FLASH_WP_R_L.
+ */
+ "AP_FLASH_WP_L",
+ "EC_AP_INT_ODL",
+ "IT6505_INT_ODL",
+ "H1_INT_OD_L",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "AP_SPI_FLASH_MISO",
+ "AP_SPI_FLASH_CS_L",
+ "AP_SPI_FLASH_MOSI",
+ "AP_SPI_FLASH_CLK",
+ "DA7219_IRQ",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "";
+};
+
+/ {
+ ppvarn_lcd: ppvarn-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvarn_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ppvarn_lcd_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 66 GPIO_ACTIVE_HIGH>;
+ };
+
+ ppvarp_lcd: ppvarp-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvarp_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ppvarp_lcd_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 166 GPIO_ACTIVE_HIGH>;
+ };
+
+ pp1800_lcd: pp1800-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pp1800_lcm_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 36 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&panel {
+ status = "okay";
+ compatible = "boe,tv101wum";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_pins_default>;
+ avdd-supply = <&ppvarn_lcd>;
+ avee-supply = <&ppvarp_lcd>;
+ pp1800-supply = <&pp1800_lcd>;
+};
+
+&pio {
+ ppvarp_lcd_en: ppvarp-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO66__FUNC_GPIO66>;
+ output-low;
+ };
+ };
+
+ ppvarn_lcd_en: ppvarn-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO166__FUNC_GPIO166>;
+ output-low;
+ };
+ };
+
+ pp1800_lcm_en: pp1800-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO36__FUNC_GPIO36>;
+ output-low;
+ };
+ };
+
+ open_touch: open_touch {
+ irq_pin {
+ pinmux = <PINMUX_GPIO155__FUNC_GPIO155>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ rst_pin {
+ pinmux = <PINMUX_GPIO156__FUNC_GPIO156>;
+
+ /*
+ * The pen driver doesn't currently support driving
+ * this reset line. By specifying output-high here
+ * we're relying on the fact that this pin has a default
+ * pulldown at boot (which makes sure the pen was in
+ * reset if it was powered) and then we set it high here
+ * to take it out of reset. Better would be if the pen
+ * driver could control this and we could remove
+ * "output-high" here.
+ */
+ output-high;
+ };
+ };
+};
+
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-rev2.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-rev2.dts
index f950c87b1672..7ac53e3bbfff 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-rev2.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-rev2.dts
@@ -4,6 +4,7 @@
*/
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "mt8183-kukui.dtsi"
/ {
@@ -24,6 +25,72 @@
wakeup-source;
};
};
+
+ pp1200_mipibrdg: pp1200-mipibrdg {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1200_mipibrdg";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pp1200_mipibrdg_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 54 GPIO_ACTIVE_HIGH>;
+ };
+
+ pp1800_lcd: pp1800-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pp1800_lcm_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 36 GPIO_ACTIVE_HIGH>;
+ };
+
+ pp3300_lcd: pp3300-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pp3300_lcm_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 35 GPIO_ACTIVE_HIGH>;
+ };
+
+ ppvarn_lcd: ppvarn-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvarn_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ppvarn_lcd_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 66 GPIO_ACTIVE_HIGH>;
+ };
+
+ ppvarp_lcd: ppvarp-lcd {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvarp_lcd";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ppvarp_lcd_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 166 GPIO_ACTIVE_HIGH>;
+ };
+
+ vddio_mipibrdg: vddio-mipibrdg {
+ compatible = "regulator-fixed";
+ regulator-name = "vddio_mipibrdg";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vddio_mipibrdg_en>;
+
+ enable-active-high;
+
+ gpio = <&pio 37 GPIO_ACTIVE_HIGH>;
+ };
};
&i2c0 {
@@ -52,6 +119,36 @@
};
};
+&panel {
+ compatible = "innolux,p097pfg_ssd2858";
+ reg = <0>;
+ enable-gpios = <&pio 45 0 &pio 73 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&panel_pins_default>;
+ /delete-property/ power-supply;
+ avdd-supply = <&ppvarp_lcd>;
+ avee-supply = <&ppvarn_lcd>;
+ pp1800-supply = <&pp1800_lcd>;
+ pp3300-supply = <&pp3300_lcd>;
+ pp1200-bridge-supply = <&pp1200_mipibrdg>;
+ vddio-bridge-supply = <&vddio_mipibrdg>;
+ backlight = <&backlight_lcd0>;
+ status = "okay";
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+};
+
+&panel_pins_default {
+ bridge_reset {
+ pinmux = <PINMUX_GPIO73__FUNC_GPIO73>;
+ output-low;
+ bias-pull-up;
+ };
+};
+
&pio {
/* 192 lines */
gpio-line-names =
@@ -285,6 +382,41 @@
};
};
+ pp1200_mipibrdg_en: pp1200-mipibrdg-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO54__FUNC_GPIO54>;
+ output-low;
+ };
+ };
+
+ pp1800_lcm_en: pp1800-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO36__FUNC_GPIO36>;
+ output-low;
+ };
+ };
+
+ pp3300_lcm_en: pp3300-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO35__FUNC_GPIO35>;
+ output-low;
+ };
+ };
+
+ ppvarp_lcd_en: ppvarp-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO66__FUNC_GPIO66>;
+ output-low;
+ };
+ };
+
+ ppvarn_lcd_en: ppvarn-lcd-en {
+ pins1 {
+ pinmux = <PINMUX_GPIO166__FUNC_GPIO166>;
+ output-low;
+ };
+ };
+
touch_default: touchdefault {
pin_irq {
pinmux = <PINMUX_GPIO155__FUNC_GPIO155>;
@@ -297,6 +429,13 @@
output-low;
};
};
+
+ vddio_mipibrdg_en: vddio_mipibrdg_en {
+ pins1 {
+ pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
+ output-low;
+ };
+ };
};
&scp_pins {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index e30bc9517fbb..e93b0587cfbc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -59,6 +59,20 @@
regulator-boot-on;
};
+ mmc1_fixed_power: regulator@3 {
+ compatible = "regulator-fixed";
+ regulator-name = "mmc1_power";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ mmc1_fixed_io: regulator@4 {
+ compatible = "regulator-fixed";
+ regulator-name = "mmc1_io";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
reserved_memory: reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -294,8 +308,8 @@
pinctrl-names = "default", "state_uhs";
pinctrl-0 = <&mmc1_pins_default>;
pinctrl-1 = <&mmc1_pins_uhs>;
- vmmc-supply = <&mt6358_vmch_reg>;
- vqmmc-supply = <&mt6358_vmc_reg>;
+ vmmc-supply = <&mmc1_fixed_power>;
+ vqmmc-supply = <&mmc1_fixed_io>;
bus-width = <4>;
max-frequency = <200000000>;
drv-type = <2>;
@@ -308,6 +322,8 @@
non-removable;
no-mmc;
no-sd;
+ assigned-clocks = <&topckgen CLK_TOP_MUX_MSDC30_1>;
+ assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
};
&mt6358_vdram2_reg {
@@ -520,7 +536,7 @@
mediatek,pull-down-adv = <10>;
};
- pins_wifi {
+ pins_wlan_en {
pinmux = <PINMUX_GPIO119__FUNC_GPIO119>;
output-high;
};
@@ -801,7 +817,8 @@
};
&ssusb {
- dr_mode = "host";
+ maximum-speed = "high-speed";
+ enable-manual-drd;
vusb33-supply = <&mt6358_vusb_reg>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index ba43207e2ecc..ff9ce0f93a3e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -6,6 +6,7 @@
*/
#include <dt-bindings/clock/mt8183-clk.h>
+#include <dt-bindings/gce/mt8183-gce.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/memory/mt8183-larb-port.h>
@@ -22,11 +23,6 @@
#size-cells = <2>;
aliases {
- ovl0 = &ovl0;
- ovl_2l0 = &ovl0_2l;
- ovl_2l1 = &ovl1_2l;
- rdma0 = &rdma0;
- rdma1 = &rdma1;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
@@ -39,6 +35,11 @@
i2c9 = &i2c9;
i2c10 = &i2c10;
i2c11 = &i2c11;
+ ovl0 = &ovl0;
+ ovl_2l0 = &ovl_2l0;
+ ovl_2l1 = &ovl_2l1;
+ rdma0 = &rdma0;
+ rdma1 = &rdma1;
};
cluster0_opp: opp_table0 {
@@ -114,67 +115,67 @@
opp-shared;
opp00 {
opp-hz = /bits/ 64 <793000000>;
- opp-microvolt = <650000>;
+ opp-microvolt = <700000>;
};
opp01 {
opp-hz = /bits/ 64 <910000000>;
- opp-microvolt = <675000>;
+ opp-microvolt = <725000>;
};
opp02 {
opp-hz = /bits/ 64 <1014000000>;
- opp-microvolt = <700000>;
+ opp-microvolt = <750000>;
};
opp03 {
opp-hz = /bits/ 64 <1131000000>;
- opp-microvolt = <725000>;
+ opp-microvolt = <775000>;
};
opp04 {
opp-hz = /bits/ 64 <1248000000>;
- opp-microvolt = <750000>;
+ opp-microvolt = <800000>;
};
opp05 {
opp-hz = /bits/ 64 <1326000000>;
- opp-microvolt = <775000>;
+ opp-microvolt = <825000>;
};
opp06 {
opp-hz = /bits/ 64 <1417000000>;
- opp-microvolt = <800000>;
+ opp-microvolt = <850000>;
};
opp07 {
opp-hz = /bits/ 64 <1508000000>;
- opp-microvolt = <825000>;
+ opp-microvolt = <875000>;
};
opp08 {
opp-hz = /bits/ 64 <1586000000>;
- opp-microvolt = <850000>;
+ opp-microvolt = <900000>;
};
opp09 {
opp-hz = /bits/ 64 <1625000000>;
- opp-microvolt = <862500>;
+ opp-microvolt = <912500>;
};
opp10 {
opp-hz = /bits/ 64 <1677000000>;
- opp-microvolt = <881250>;
+ opp-microvolt = <931250>;
};
opp11 {
opp-hz = /bits/ 64 <1716000000>;
- opp-microvolt = <900000>;
+ opp-microvolt = <950000>;
};
opp12 {
opp-hz = /bits/ 64 <1781000000>;
- opp-microvolt = <925000>;
+ opp-microvolt = <975000>;
};
opp13 {
opp-hz = /bits/ 64 <1846000000>;
- opp-microvolt = <950000>;
+ opp-microvolt = <1000000>;
};
opp14 {
opp-hz = /bits/ 64 <1924000000>;
- opp-microvolt = <975000>;
+ opp-microvolt = <1025000>;
};
opp15 {
opp-hz = /bits/ 64 <1989000000>;
- opp-microvolt = <1000000>;
+ opp-microvolt = <1050000>;
};
};
@@ -254,6 +255,29 @@
operating-points-v2 = <&cci_opp>;
};
+ devfreq-cpufreq-map {
+ cci-cpufreq {
+ target-dev = <&cci>;
+ cpu-to-dev-map =
+ < 793000 273000000 >,
+ < 910000 403000000 >,
+ < 1014000 463000000 >,
+ < 1131000 546000000 >,
+ < 1248000 624000000 >,
+ < 1326000 689000000 >,
+ < 1417000 767000000 >,
+ < 1508000 871000000 >,
+ < 1586000 923000000 >,
+ < 1625000 962000000 >,
+ < 1677000 1027000000 >,
+ < 1716000 1092000000 >,
+ < 1781000 1144000000 >,
+ < 1846000 1196000000 >,
+ < 1924000 1196000000 >,
+ < 1989000 1196000000 >;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -302,6 +326,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster0_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu1: cpu@1 {
@@ -316,6 +341,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster0_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu2: cpu@2 {
@@ -330,6 +356,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster0_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu3: cpu@3 {
@@ -344,6 +371,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster0_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu4: cpu@100 {
@@ -358,6 +386,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster1_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu5: cpu@101 {
@@ -372,6 +401,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster1_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu6: cpu@102 {
@@ -386,6 +416,7 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster1_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
};
cpu7: cpu@103 {
@@ -400,6 +431,29 @@
<&topckgen CLK_TOP_ARMPLL_DIV_PLL1>;
clock-names = "cpu", "intermediate";
operating-points-v2 = <&cluster1_opp>;
+ cpu-idle-states = <&MCDI_CPU &MCDI_CLUSTER>;
+ };
+
+ idle-states {
+ entry-method = "arm,psci";
+
+ MCDI_CPU: mcdi-cpu {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ arm,psci-suspend-param = <0x00010001>;
+ entry-latency-us = <200>;
+ exit-latency-us = <200>;
+ min-residency-us = <800>;
+ };
+
+ MCDI_CLUSTER: mcdi-cluster {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ arm,psci-suspend-param = <0x01010001>;
+ entry-latency-us = <250>;
+ exit-latency-us = <400>;
+ min-residency-us = <1300>;
+ };
};
};
@@ -603,6 +657,14 @@
clock-names = "spi", "wrap";
};
+ systimer@10017000 {
+ compatible = "mediatek,mt8183-timer",
+ "mediatek,mt6765-timer";
+ reg = <0 0x10017000 0 0x1000>;
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_CLK13M>;
+ };
+
iommu: iommu@10205000 {
compatible = "mediatek,mt8183-m4u";
reg = <0 0x10205000 0 0x1000>;
@@ -612,6 +674,38 @@
#iommu-cells = <1>;
};
+ emi@10219000 {
+ compatible = "mediatek,mt8183-emi";
+ reg = <0 0x10219000 0 0x1000>, /* CEN EMI */
+ <0 0x10226000 0 0x1000>, /* EMI MPU */
+ <0 0x1022d000 0 0x1000>, /* CHA EMI */
+ <0 0x10235000 0 0x1000>; /* CHB EMI */
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_LOW>, /* MPU */
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, /* CGM */
+ <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* ELM */
+ };
+
+ gce: gce@10238000 {
+ compatible = "mediatek,mt8183-gce";
+ reg = <0 0x10238000 0 0x4000>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_LOW>;
+ #mbox-cells = <3>;
+ #subsys-cells = <3>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+ };
+
+ vpu: vpu@10500000 {
+ compatible = "mediatek,mt8183-vpu", "mediatek,mt8173-vpu";
+ reg = <0 0x10500000 0 0x80000>,
+ <0 0x105c0000 0 0x1000>;
+ reg-names = "tcm", "cfg_reg";
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_SCPSYS>;
+ clock-names = "main";
+ status = "disabled";
+ };
+
scp: scp@10500000 {
compatible = "mediatek,mt8183-scp";
reg = <0 0x10500000 0 0x80000>,
@@ -1436,27 +1530,24 @@
power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
clocks = <&mmsys CLK_MM_DISP_OVL0>;
iommus = <&iommu M4U_PORT_DISP_OVL0>;
- mediatek,larb = <&larb0>;
};
- ovl0_2l: ovl@14009000 {
+ ovl_2l0: ovl@14009000 {
compatible = "mediatek,mt8183-disp-ovl-2l";
reg = <0 0x14009000 0 0x1000>;
interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
- mediatek,larb = <&larb0>;
};
- ovl1_2l: ovl@1400a000 {
+ ovl_2l1: ovl@1400a000 {
compatible = "mediatek,mt8183-disp-ovl-2l";
reg = <0 0x1400a000 0 0x1000>;
interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
clocks = <&mmsys CLK_MM_DISP_OVL1_2L>;
iommus = <&iommu M4U_PORT_DISP_2L_OVL1_LARB0>;
- mediatek,larb = <&larb0>;
};
rdma0: rdma@1400b000 {
@@ -1466,7 +1557,6 @@
power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
clocks = <&mmsys CLK_MM_DISP_RDMA0>;
iommus = <&iommu M4U_PORT_DISP_RDMA0>;
- mediatek,larb = <&larb0>;
};
rdma1: rdma@1400c000 {
@@ -1476,7 +1566,6 @@
power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
clocks = <&mmsys CLK_MM_DISP_RDMA1>;
iommus = <&iommu M4U_PORT_DISP_RDMA1>;
- mediatek,larb = <&larb0>;
};
color0: color@1400e000 {
@@ -1536,6 +1625,13 @@
phy-names = "dphy";
};
+ mutex: mutex@14016000 {
+ compatible = "mediatek,mt8183-disp-mutex";
+ reg = <0 0x14016000 0 0x1000>;
+ interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
+ };
+
larb0: larb@14017000 {
compatible = "mediatek,mt8183-smi-larb";
reg = <0 0x14017000 0 0x1000>;
diff --git a/chromeos/config/arm64/chromiumos-arm64.flavour.config b/chromeos/config/arm64/chromiumos-arm64.flavour.config
index de753bd63ded..ba263ecb9cd9 100644
--- a/chromeos/config/arm64/chromiumos-arm64.flavour.config
+++ b/chromeos/config/arm64/chromiumos-arm64.flavour.config
@@ -40,6 +40,7 @@ CONFIG_DRM_ANALOGIX_ANX78XX=y
CONFIG_DRM_MEDIATEK=y
CONFIG_DRM_MEDIATEK_HDMI=y
# CONFIG_DRM_MSM_HDMI_HDCP is not set
+CONFIG_DRM_PANEL_BOE_TV101WUM=y
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y
CONFIG_DRM_TI_SN65DSI86=y
CONFIG_DRM_VIRTIO_GPU=y
@@ -75,6 +76,7 @@ CONFIG_MSM_GCC_8916=y
CONFIG_MTD_MT81xx_NOR=y
CONFIG_MTK_CMDQ=y
CONFIG_MTK_EFUSE=y
+CONFIG_MTK_EMI_MBW=y
CONFIG_MTK_IOMMU=y
CONFIG_MTK_PMIC_WRAP=y
CONFIG_MTK_SCP=m
@@ -183,8 +185,11 @@ CONFIG_SPI_QCOM_QSPI=y
CONFIG_SPI_ROCKCHIP=y
CONFIG_SPMI=y
CONFIG_TOUCHSCREEN_MELFAS_MIP4=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_MTU3=y
-CONFIG_USB_MTU3_HOST=y
+CONFIG_USB_MTU3_DEBUG=y
CONFIG_VIDEO_MEDIATEK_MDP=y
CONFIG_VIDEO_MEDIATEK_VCODEC=y
CONFIG_VIRTIO_BLK=y
diff --git a/chromeos/config/arm64/chromiumos-mediatek.flavour.config b/chromeos/config/arm64/chromiumos-mediatek.flavour.config
index e02669621c75..9a2ddb58a7d7 100644
--- a/chromeos/config/arm64/chromiumos-mediatek.flavour.config
+++ b/chromeos/config/arm64/chromiumos-mediatek.flavour.config
@@ -25,10 +25,12 @@ CONFIG_COMMON_CLK_MT8183_MMSYS=y
CONFIG_COMMON_CLK_MT8183_VDECSYS=y
CONFIG_COMMON_CLK_MT8183_VENCSYS=y
CONFIG_CROS_EC_RPMSG=m
+CONFIG_DEVFREQ_GOV_CPUFREQ_MAP=y
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DRM_ANALOGIX_ANX78XX=y
CONFIG_DRM_MEDIATEK=y
CONFIG_DRM_MEDIATEK_HDMI=y
+CONFIG_DRM_PANEL_BOE_TV101WUM=y
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y
# CONFIG_EFI is not set
CONFIG_ENERGY_MODEL=y
@@ -46,6 +48,7 @@ CONFIG_MMC_MTK=y
CONFIG_MTD_MT81xx_NOR=y
CONFIG_MTK_CMDQ=y
CONFIG_MTK_EFUSE=y
+CONFIG_MTK_EMI_MBW=y
CONFIG_MTK_IOMMU=y
CONFIG_MTK_PMIC_WRAP=y
CONFIG_MTK_SCP=m
@@ -77,7 +80,10 @@ CONFIG_STAGING_MEDIA=y
CONFIG_TCG_CR50_I2C=y
CONFIG_TMPFS=y
CONFIG_TOUCHSCREEN_MELFAS_MIP4=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_MTU3=y
-CONFIG_USB_MTU3_HOST=y
+CONFIG_USB_MTU3_DEBUG=y
CONFIG_VIDEO_MEDIATEK_MDP=y
CONFIG_VIDEO_MEDIATEK_VCODEC=y
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 3dc1b9f15ea2..5df0e476e94d 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -44,3 +44,5 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
+obj-$(CONFIG_COMMON_CLK_MT8183) += clkdbg.o clkdbg-mt8183.o
+obj-$(CONFIG_COMMON_CLK_MT8183) += clkchk.o clkchk-mt8183.o
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
index e8d7bebe2d7a..b35a3c742062 100644
--- a/drivers/clk/mediatek/clk-mt8183.c
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -25,9 +25,11 @@ static const struct mtk_fixed_clk top_fixed_clks[] = {
FIXED_CLK(CLK_TOP_UNIVP_192M, "univpll_192m", "univpll", 192000000),
};
+static const struct mtk_fixed_factor top_early_divs[] = {
+ FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1, 2),
+};
+
static const struct mtk_fixed_factor top_divs[] = {
- FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1,
- 2),
FACTOR(CLK_TOP_F26M_CK_D2, "csw_f26m_ck_d2", "clk26m", 1,
2),
FACTOR(CLK_TOP_SYSPLL_CK, "syspll_ck", "mainpll", 1,
@@ -1148,37 +1150,62 @@ static int clk_mt8183_apmixed_probe(struct platform_device *pdev)
return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
}
+static struct clk_onecell_data *top_clk_data;
+
+static void clk_mt8183_top_init_early(struct device_node *node)
+{
+ int i;
+
+ if (!top_clk_data) {
+ top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+
+ for (i = 0; i < CLK_TOP_NR_CLK; i++)
+ top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+ }
+
+ mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
+ top_clk_data);
+
+ of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+}
+
+CLK_OF_DECLARE_DRIVER(mt8183_topckgen, "mediatek,mt8183-topckgen",
+ clk_mt8183_top_init_early);
+
static int clk_mt8183_top_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
void __iomem *base;
- struct clk_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
- clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+ if (!top_clk_data)
+ top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
- clk_data);
+ top_clk_data);
+
+ mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
+ top_clk_data);
- mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes),
- node, &mt8183_clk_lock, clk_data);
+ node, &mt8183_clk_lock, top_clk_data);
mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes),
- base, &mt8183_clk_lock, clk_data);
+ base, &mt8183_clk_lock, top_clk_data);
mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
- base, &mt8183_clk_lock, clk_data);
+ base, &mt8183_clk_lock, top_clk_data);
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
- clk_data);
+ top_clk_data);
- return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
}
static int clk_mt8183_infra_probe(struct platform_device *pdev)
diff --git a/drivers/clk/mediatek/clkchk-mt8183.c b/drivers/clk/mediatek/clkchk-mt8183.c
new file mode 100644
index 000000000000..c7b081fbc44b
--- /dev/null
+++ b/drivers/clk/mediatek/clkchk-mt8183.c
@@ -0,0 +1,387 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+// Author: Weiyi Lu <weiyi.lu@mediatek.com>
+
+#include <linux/module.h>
+#include "clkchk.h"
+
+static const char * const off_pll_names[] = {
+ "univ2pll",
+ "msdcpll",
+ "mmpll",
+ "mfgpll",
+ "tvdpll",
+ "apll1",
+ "apll2",
+ NULL
+};
+
+static const char * const all_clk_names[] = {
+ "univ2pll",
+ "msdcpll",
+ "mmpll",
+ "mfgpll",
+ "tvdpll",
+ "apll1",
+ "apll2",
+ "apmixed_ssusb26m",
+ "apmixed_mipic026m",
+ "apmixed_mdpll26m",
+ "apmixed_mmsys26m",
+ "apmixed_ufs26m",
+ "apmixed_mipic126m",
+ "apmixed_mempll26m",
+ "apmixed_lvpll26m",
+ "apmixed_mipid026m",
+ "apmixed_mipid126m",
+ "syspll_d3",
+ "syspll_d5",
+ "syspll_d2_d2",
+ "syspll_d2_d4",
+ "syspll_d2_d16",
+ "syspll_d3_d2",
+ "syspll_d3_d4",
+ "syspll_d3_d8",
+ "syspll_d5_d2",
+ "syspll_d5_d4",
+ "syspll_d7_d2",
+ "syspll_d7_d4",
+ "univpll_ck",
+ "univpll_d2",
+ "univpll_d3",
+ "univpll_d5",
+ "univpll_d7",
+ "univpll_d2_d2",
+ "univpll_d2_d4",
+ "univpll_d2_d8",
+ "univpll_d3_d2",
+ "univpll_d3_d4",
+ "univpll_d3_d8",
+ "univpll_d5_d2",
+ "univpll_d5_d4",
+ "univpll_d5_d8",
+ "apll1_ck",
+ "apll1_d2",
+ "apll1_d4",
+ "apll1_d8",
+ "apll2_ck",
+ "apll2_d2",
+ "apll2_d4",
+ "apll2_d8",
+ "tvdpll_ck",
+ "tvdpll_d2",
+ "tvdpll_d4",
+ "tvdpll_d8",
+ "tvdpll_d16",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "msdcpll_d4",
+ "msdcpll_d8",
+ "msdcpll_d16",
+ "ad_osc_ck",
+ "osc_d2",
+ "osc_d4",
+ "osc_d8",
+ "osc_d16",
+ "csw_f26m_ck_d2",
+ "mfgpll_ck",
+ "univ_192m_ck",
+ "univ_192m_d2",
+ "univ_192m_d4",
+ "univ_192m_d8",
+ "univ_192m_d16",
+ "univ_192m_d32",
+ "mmpll_ck",
+ "mmpll_d4",
+ "mmpll_d4_d2",
+ "mmpll_d4_d4",
+ "mmpll_d5",
+ "mmpll_d5_d2",
+ "mmpll_d5_d4",
+ "mmpll_d6",
+ "mmpll_d7",
+ "osc",
+ "univpll_192m",
+ "apll_i2s0_sel",
+ "apll_i2s1_sel",
+ "apll_i2s2_sel",
+ "apll_i2s3_sel",
+ "apll_i2s4_sel",
+ "apll_i2s5_sel",
+ "apll12_div0",
+ "apll12_div1",
+ "apll12_div2",
+ "apll12_div3",
+ "apll12_div4",
+ "apll12_divb",
+ "univpll",
+ "armpll_div_pll2",
+ "mm_sel",
+ "cam_sel",
+ "mfg_sel",
+ "camtg_sel",
+ "spi_sel",
+ "msdc50_hclk_sel",
+ "msdc50_0_sel",
+ "msdc30_1_sel",
+ "msdc30_2_sel",
+ "audio_sel",
+ "aud_intbus_sel",
+ "fpwrap_ulposc_sel",
+ "scp_sel",
+ "atb_sel",
+ "sspm_sel",
+ "dpi0_sel",
+ "scam_sel",
+ "aud_1_sel",
+ "aud_2_sel",
+ "disppwm_sel",
+ "ssusb_top_xhci_sel",
+ "usb_top_sel",
+ "i2c_sel",
+ "f52m_mfg_sel",
+ "seninf_sel",
+ "dxcc_sel",
+ "camtg2_sel",
+ "aud_eng1_sel",
+ "aud_eng2_sel",
+ "faes_ufsfde_sel",
+ "fufs_sel",
+ "img_sel",
+ "dsp_sel",
+ "dsp1_sel",
+ "dsp2_sel",
+ "ipu_if_sel",
+ "camtg3_sel",
+ "camtg4_sel",
+ "mcu_mp0_sel",
+ "mcu_mp2_sel",
+ "mcu_bus_sel",
+ "infra_pmic_tmr",
+ "infra_pmic_md",
+ "infra_pmic_conn",
+ "infra_scp",
+ "infra_sej",
+ "infra_apxgpt",
+ "infra_icusb",
+ "infra_gce",
+ "infra_therm",
+ "infra_i2c0",
+ "infra_i2c1",
+ "infra_i2c2",
+ "infra_i2c3",
+ "infra_pwm_hclk",
+ "infra_pwm1",
+ "infra_pwm2",
+ "infra_pwm3",
+ "infra_pwm4",
+ "infra_pwm",
+ "infra_uart1",
+ "infra_uart2",
+ "infra_uart3",
+ "infra_gce_26m",
+ "infra_cqdma_fpc",
+ "infra_btif",
+ "infra_spi0",
+ "infra_msdc0",
+ "infra_msdc1",
+ "infra_msdc2",
+ "infra_msdc0_sck",
+ "infra_dvfsrc",
+ "infra_gcpu",
+ "infra_trng",
+ "infra_auxadc",
+ "infra_cpum",
+ "infra_ccif1_ap",
+ "infra_ccif1_md",
+ "infra_auxadc_md",
+ "infra_msdc1_sck",
+ "infra_msdc2_sck",
+ "infra_apdma",
+ "infra_xiu",
+ "infra_device_apc",
+ "infra_ccif_ap",
+ "infra_debugsys",
+ "infra_audio",
+ "infra_ccif_md",
+ "infra_dxcc_sec_core",
+ "infra_dxcc_ao",
+ "infra_dramc_f26m",
+ "infra_irtx",
+ "infra_disppwm",
+ "infra_cldma_bclk",
+ "infra_audio_26m_bclk",
+ "infra_spi1",
+ "infra_i2c4",
+ "infra_md_tmp_share",
+ "infra_spi2",
+ "infra_spi3",
+ "infra_unipro_sck",
+ "infra_unipro_tick",
+ "infra_ufs_mp_sap_bck",
+ "infra_md32_bclk",
+ "infra_sspm",
+ "infra_unipro_mbist",
+ "infra_sspm_bus_hclk",
+ "infra_i2c5",
+ "infra_i2c5_arbiter",
+ "infra_i2c5_imm",
+ "infra_i2c1_arbiter",
+ "infra_i2c1_imm",
+ "infra_i2c2_arbiter",
+ "infra_i2c2_imm",
+ "infra_spi4",
+ "infra_spi5",
+ "infra_cqdma",
+ "infra_ufs",
+ "infra_aes_ufsfde",
+ "infra_ufs_tick",
+ "infra_msdc0_self",
+ "infra_msdc1_self",
+ "infra_msdc2_self",
+ "infra_sspm_26m_self",
+ "infra_sspm_32k_self",
+ "infra_ufs_axi",
+ "infra_i2c6",
+ "infra_ap_msdc0",
+ "infra_md_msdc0",
+ "infra_usb",
+ "infra_devmpu_bclk",
+ "infra_ccif2_ap",
+ "infra_ccif2_md",
+ "infra_ccif3_ap",
+ "infra_ccif3_md",
+ "infra_sej_f13m",
+ "infra_aes_bclk",
+ "infra_i2c7",
+ "infra_i2c8",
+ "infra_fbist2fpc",
+ "aud_tml",
+ "aud_dac_predis",
+ "aud_dac",
+ "aud_adc",
+ "aud_apll_tuner",
+ "aud_apll2_tuner",
+ "aud_24m",
+ "aud_22m",
+ "aud_afe",
+ "aud_i2s4",
+ "aud_i2s3",
+ "aud_i2s2",
+ "aud_i2s1",
+ "aud_pdn_adda6_adc",
+ "aud_tdm",
+ "mfg_bg3d",
+ "mm_smi_common",
+ "mm_smi_larb0",
+ "mm_smi_larb1",
+ "mm_gals_comm0",
+ "mm_gals_comm1",
+ "mm_gals_ccu2mm",
+ "mm_gals_ipu12mm",
+ "mm_gals_img2mm",
+ "mm_gals_cam2mm",
+ "mm_gals_ipu2mm",
+ "mm_mdp_dl_txck",
+ "mm_ipu_dl_txck",
+ "mm_mdp_rdma0",
+ "mm_mdp_rdma1",
+ "mm_mdp_rsz0",
+ "mm_mdp_rsz1",
+ "mm_mdp_tdshp",
+ "mm_mdp_wrot0",
+ "mm_fake_eng",
+ "mm_disp_ovl0",
+ "mm_disp_ovl0_2l",
+ "mm_disp_ovl1_2l",
+ "mm_disp_rdma0",
+ "mm_disp_rdma1",
+ "mm_disp_wdma0",
+ "mm_disp_color0",
+ "mm_disp_ccorr0",
+ "mm_disp_aal0",
+ "mm_disp_gamma0",
+ "mm_disp_dither0",
+ "mm_disp_split",
+ "mm_dsi0_mm",
+ "mm_dsi0_if",
+ "mm_dpi_mm",
+ "mm_dpi_if",
+ "mm_fake_eng2",
+ "mm_mdp_dl_rx",
+ "mm_ipu_dl_rx",
+ "mm_26m",
+ "mm_mmsys_r2y",
+ "mm_disp_rsz",
+ "mm_mdp_wdma0",
+ "mm_mdp_aal",
+ "mm_mdp_ccorr",
+ "mm_dbi_mm",
+ "mm_dbi_if",
+ "vdec_vdec",
+ "vdec_larb1",
+ "venc_larb",
+ "venc_venc",
+ "venc_jpgenc",
+ "img_owe",
+ "img_wpe_b",
+ "img_wpe_a",
+ "img_mfb",
+ "img_rsc",
+ "img_dpe",
+ "img_fdvt",
+ "img_dip",
+ "img_larb2",
+ "img_larb5",
+ "cam_larb6",
+ "cam_dfp_vad",
+ "cam_cam",
+ "cam_camtg",
+ "cam_seninf",
+ "cam_camsv0",
+ "cam_camsv1",
+ "cam_camsv2",
+ "cam_ccu",
+ "cam_larb3",
+ "ipu_conn_ipu",
+ "ipu_conn_ahb",
+ "ipu_conn_axi",
+ "ipu_conn_isp",
+ "ipu_conn_cam_adl",
+ "ipu_conn_img_adl",
+ "ipu_conn_dap_rx",
+ "ipu_conn_apb2axi",
+ "ipu_conn_apb2ahb",
+ "ipu_conn_ipu_cab1to2",
+ "ipu_conn_ipu1_cab1to2",
+ "ipu_conn_ipu2_cab1to2",
+ "ipu_conn_cab3to3",
+ "ipu_conn_cab2to1",
+ "ipu_conn_cab3to1_slice",
+ "ipu_adl_cabgen",
+ "ipu_core0_jtag",
+ "ipu_core0_axi",
+ "ipu_core0_ipu",
+ "ipu_core1_jtag",
+ "ipu_core1_axi",
+ "ipu_core1_ipu",
+ /* end */
+ NULL
+};
+
+static const char * const compatible[] = {"mediatek,mt8183", NULL};
+
+static struct clkchk_cfg_t cfg = {
+ .aee_excp_on_fail = false,
+ .warn_on_fail = true,
+ .compatible = compatible,
+ .off_pll_names = off_pll_names,
+ .all_clk_names = all_clk_names,
+};
+
+static int __init clkchk_platform_init(void)
+{
+ return clkchk_init(&cfg);
+}
+subsys_initcall(clkchk_platform_init);
diff --git a/drivers/clk/mediatek/clkchk.c b/drivers/clk/mediatek/clkchk.c
new file mode 100644
index 000000000000..d50110a0d538
--- /dev/null
+++ b/drivers/clk/mediatek/clkchk.c
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+// Author: Weiyi Lu <weiyi.lu@mediatek.com>
+
+#define pr_fmt(fmt) "[clkchk] " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/syscore_ops.h>
+#include "clkchk.h"
+
+#define AEE_EXCP_CHECK_PLL_FAIL 0
+#define CLKDBG_CCF_API_4_4 1
+#define MAX_PLLS 32
+
+#if AEE_EXCP_CHECK_PLL_FAIL
+#include <mt-plat/aee.h>
+#endif
+
+#if !CLKDBG_CCF_API_4_4
+
+/* backward compatible */
+
+static const char *clk_hw_get_name(const struct clk_hw *hw)
+{
+ return __clk_get_name(hw->clk);
+}
+
+static bool clk_hw_is_prepared(const struct clk_hw *hw)
+{
+ return __clk_is_prepared(hw->clk);
+}
+
+static bool clk_hw_is_enabled(const struct clk_hw *hw)
+{
+ return __clk_is_enabled(hw->clk);
+}
+
+static unsigned long clk_hw_get_rate(const struct clk_hw *hw)
+{
+ return __clk_get_rate(hw->clk);
+}
+
+static struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw)
+{
+ return __clk_get_hw(clk_get_parent(hw->clk));
+}
+
+#endif /* !CLKDBG_CCF_API_4_4 */
+
+static struct clkchk_cfg_t *clkchk_cfg;
+
+static const char *ccf_state(struct clk_hw *hw)
+{
+ if (__clk_get_enable_count(hw->clk))
+ return "enabled";
+
+ if (clk_hw_is_prepared(hw))
+ return "prepared";
+
+ return "disabled";
+}
+
+static void print_enabled_clks(void)
+{
+ const char * const *cn = clkchk_cfg->all_clk_names;
+
+ pr_warn("enabled clks:\n");
+
+ for (; *cn != NULL; cn++) {
+ struct clk *c = __clk_lookup(*cn);
+ struct clk_hw *c_hw = __clk_get_hw(c);
+ struct clk_hw *p_hw;
+
+ if (IS_ERR_OR_NULL(c) || c_hw == NULL)
+ continue;
+
+ p_hw = clk_hw_get_parent(c_hw);
+
+ if (p_hw == NULL)
+ continue;
+
+ if (!clk_hw_is_prepared(c_hw) &&
+ __clk_get_enable_count(c) <= 0U)
+ continue;
+
+ pr_warn("[%-17s: %8s, %3d, %3d, %10ld, %17s]\n",
+ clk_hw_get_name(c_hw),
+ ccf_state(c_hw),
+ clk_hw_is_prepared(c_hw),
+ __clk_get_enable_count(c),
+ clk_hw_get_rate(c_hw),
+ p_hw != NULL ? clk_hw_get_name(p_hw) : "- ");
+ }
+}
+
+static void check_pll_off(void)
+{
+ static struct clk *off_plls[MAX_PLLS];
+
+ struct clk **c;
+ int invalid = 0;
+ char buf[128] = {0};
+ int n = 0;
+
+ if (off_plls[0] == NULL) {
+ const char * const *pn = clkchk_cfg->off_pll_names;
+ struct clk **end = off_plls + MAX_PLLS - 1;
+
+ for (c = off_plls; *pn != NULL && c < end; pn++, c++)
+ *c = __clk_lookup(*pn);
+ }
+
+ for (c = off_plls; *c != NULL; c++) {
+ struct clk_hw *c_hw = __clk_get_hw(*c);
+
+ if (c_hw == NULL)
+ continue;
+
+ if (!clk_hw_is_prepared(c_hw) && !clk_hw_is_enabled(c_hw))
+ continue;
+
+ n += snprintf(buf + n, sizeof(buf) - (size_t)n, "%s ",
+ clk_hw_get_name(c_hw));
+
+ invalid++;
+ }
+
+ if (invalid == 0)
+ return;
+
+ /* invalid. output debug info */
+
+ pr_warn("unexpected unclosed PLL: %s\n", buf);
+ print_enabled_clks();
+
+#if AEE_EXCP_CHECK_PLL_FAIL
+ if (clkchk_cfg->aee_excp_on_fail)
+ aee_kernel_exception("clkchk", "unclosed PLL: %s\n", buf);
+#endif
+
+ if (clkchk_cfg->warn_on_fail)
+ WARN_ON(true);
+}
+
+static int clkchk_syscore_suspend(void)
+{
+ check_pll_off();
+
+ return 0;
+}
+
+static void clkchk_syscore_resume(void)
+{
+}
+
+static struct syscore_ops clkchk_syscore_ops = {
+ .suspend = clkchk_syscore_suspend,
+ .resume = clkchk_syscore_resume,
+};
+
+int clkchk_init(struct clkchk_cfg_t *cfg)
+{
+ const char * const *c;
+ bool match = false;
+
+ if (cfg == NULL || cfg->compatible == NULL
+ || cfg->all_clk_names == NULL || cfg->off_pll_names == NULL) {
+ pr_warn("Invalid clkchk_cfg.\n");
+ return -EINVAL;
+ }
+
+ clkchk_cfg = cfg;
+
+ for (c = cfg->compatible; *c != NULL; c++) {
+ if (of_machine_is_compatible(*c) != 0) {
+ match = true;
+ break;
+ }
+ }
+
+ if (!match)
+ return -ENODEV;
+
+ register_syscore_ops(&clkchk_syscore_ops);
+
+ return 0;
+}
diff --git a/drivers/clk/mediatek/clkchk.h b/drivers/clk/mediatek/clkchk.h
new file mode 100644
index 000000000000..d99e1acb6477
--- /dev/null
+++ b/drivers/clk/mediatek/clkchk.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Weiyi Lu <weiyi.lu@mediatek.com>
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+
+struct clkchk_cfg_t {
+ bool aee_excp_on_fail;
+ bool warn_on_fail;
+ const char * const *compatible;
+ const char * const *off_pll_names;
+ const char * const *all_clk_names;
+};
+
+int clkchk_init(struct clkchk_cfg_t *cfg);
diff --git a/drivers/clk/mediatek/clkdbg-mt8183.c b/drivers/clk/mediatek/clkdbg-mt8183.c
new file mode 100644
index 000000000000..7b82ef2bce81
--- /dev/null
+++ b/drivers/clk/mediatek/clkdbg-mt8183.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+// Author: Weiyi Lu <weiyi.lu@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+
+#include "clkdbg.h"
+
+#define DUMP_INIT_STATE 0
+
+/*
+ * clkdbg dump_regs
+ */
+
+enum {
+ topckgen,
+ infracfg,
+ scpsys,
+ apmixedsys,
+ audiosys,
+ mfgsys,
+ mmsys,
+ imgsys,
+ camsys,
+ vencsys,
+};
+
+#define REGBASE_V(_phys, _id_name) { .phys = _phys, .name = #_id_name }
+
+/*
+ * checkpatch.pl ERROR:COMPLEX_MACRO
+ *
+ * #define REGBASE(_phys, _id_name) [_id_name] = REGBASE_V(_phys, _id_name)
+ */
+
+static struct regbase rb[] = {
+ [topckgen] = REGBASE_V(0x10000000, topckgen),
+ [infracfg] = REGBASE_V(0x10001000, infracfg),
+ [scpsys] = REGBASE_V(0x10006000, scpsys),
+ [apmixedsys] = REGBASE_V(0x1000c000, apmixedsys),
+ [audiosys] = REGBASE_V(0x11220000, audiosys),
+ [mfgsys] = REGBASE_V(0x13000000, mfgsys),
+ [mmsys] = REGBASE_V(0x14000000, mmsys),
+ [imgsys] = REGBASE_V(0x15020000, imgsys),
+ [camsys] = REGBASE_V(0x1a000000, camsys),
+ [vencsys] = REGBASE_V(0x17000000, vencsys),
+};
+
+#define REGNAME(_base, _ofs, _name) \
+ { .base = &rb[_base], .ofs = _ofs, .name = #_name }
+
+static struct regname rn[] = {
+ REGNAME(topckgen, 0x040, CLK_CFG_0),
+ REGNAME(topckgen, 0x050, CLK_CFG_1),
+ REGNAME(topckgen, 0x060, CLK_CFG_2),
+ REGNAME(topckgen, 0x070, CLK_CFG_3),
+ REGNAME(topckgen, 0x080, CLK_CFG_4),
+ REGNAME(topckgen, 0x090, CLK_CFG_5),
+ REGNAME(topckgen, 0x0a0, CLK_CFG_6),
+ REGNAME(topckgen, 0x0b0, CLK_CFG_7),
+ REGNAME(topckgen, 0x0c0, CLK_CFG_8),
+ REGNAME(topckgen, 0x0d0, CLK_CFG_9),
+ REGNAME(topckgen, 0x0e0, CLK_CFG_10),
+ REGNAME(audiosys, 0x000, AUDIO_TOP_CON0),
+ REGNAME(audiosys, 0x004, AUDIO_TOP_CON1),
+ REGNAME(camsys, 0x000, CAMSYS_CG),
+ REGNAME(imgsys, 0x000, IMG_CG),
+ REGNAME(infracfg, 0x090, MODULE_SW_CG_0),
+ REGNAME(infracfg, 0x094, MODULE_SW_CG_1),
+ REGNAME(infracfg, 0x0ac, MODULE_SW_CG_2),
+ REGNAME(infracfg, 0x0c8, MODULE_SW_CG_3),
+ REGNAME(mfgsys, 0x000, MFG_CG),
+ REGNAME(mmsys, 0x100, MMSYS_CG_CON0),
+ REGNAME(mmsys, 0x110, MMSYS_CG_CON1),
+ REGNAME(vencsys, 0x000, VENCSYS_CG),
+ REGNAME(apmixedsys, 0x200, ARMPLL_LL_CON0),
+ REGNAME(apmixedsys, 0x204, ARMPLL_LL_CON1),
+ REGNAME(apmixedsys, 0x20C, ARMPLL_LL_PWR_CON0),
+ REGNAME(apmixedsys, 0x210, ARMPLL_L_CON0),
+ REGNAME(apmixedsys, 0x214, ARMPLL_L_CON1),
+ REGNAME(apmixedsys, 0x21C, ARMPLL_L_PWR_CON0),
+ REGNAME(apmixedsys, 0x220, MAINPLL_CON0),
+ REGNAME(apmixedsys, 0x224, MAINPLL_CON1),
+ REGNAME(apmixedsys, 0x22C, MAINPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x230, UNIVPLL_CON0),
+ REGNAME(apmixedsys, 0x234, UNIVPLL_CON1),
+ REGNAME(apmixedsys, 0x23C, UNIVPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x240, MFGPLL_CON0),
+ REGNAME(apmixedsys, 0x244, MFGPLL_CON1),
+ REGNAME(apmixedsys, 0x24C, MFGPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x250, MSDCPLL_CON0),
+ REGNAME(apmixedsys, 0x254, MSDCPLL_CON1),
+ REGNAME(apmixedsys, 0x25C, MSDCPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x260, TVDPLL_CON0),
+ REGNAME(apmixedsys, 0x264, TVDPLL_CON1),
+ REGNAME(apmixedsys, 0x26C, TVDPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x270, MMPLL_CON0),
+ REGNAME(apmixedsys, 0x274, MMPLL_CON1),
+ REGNAME(apmixedsys, 0x27C, MMPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x280, MPLL_CON0),
+ REGNAME(apmixedsys, 0x284, MPLL_CON1),
+ REGNAME(apmixedsys, 0x28C, MPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x290, CCIPLL_CON0),
+ REGNAME(apmixedsys, 0x294, CCIPLL_CON1),
+ REGNAME(apmixedsys, 0x29C, CCIPLL_PWR_CON0),
+ REGNAME(apmixedsys, 0x2A0, APLL1_CON0),
+ REGNAME(apmixedsys, 0x2A4, APLL1_CON1),
+ REGNAME(apmixedsys, 0x2B0, APLL1_PWR_CON0),
+ REGNAME(apmixedsys, 0x2B4, APLL2_CON0),
+ REGNAME(apmixedsys, 0x2B8, APLL2_CON1),
+ REGNAME(apmixedsys, 0x2C4, APLL2_PWR_CON0),
+ REGNAME(scpsys, 0x0180, PWR_STATUS),
+ REGNAME(scpsys, 0x0184, PWR_STATUS_2ND),
+ REGNAME(scpsys, 0x0334, MFG_ASYNC_PWR_CON),
+ REGNAME(scpsys, 0x0338, MFG_PWR_CON),
+ REGNAME(scpsys, 0x033C, MFG_CORE0_PWR_CON),
+ REGNAME(scpsys, 0x0340, MFG_CORE1_PWR_CON),
+ REGNAME(scpsys, 0x0320, MD1_PWR_CON),
+ REGNAME(scpsys, 0x032C, CONN_PWR_CON),
+ REGNAME(scpsys, 0x0314, AUD_PWR_CON),
+ REGNAME(scpsys, 0x030C, DIS_PWR_CON),
+ REGNAME(scpsys, 0x0344, CAM_PWR_CON),
+ REGNAME(scpsys, 0x0308, ISP_PWR_CON),
+ REGNAME(scpsys, 0x0304, VEN_PWR_CON),
+ {}
+};
+
+static const struct regname *get_all_regnames(void)
+{
+ return rn;
+}
+
+static void __init init_regbase(void)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(rb); i++)
+ rb[i].virt = ioremap(rb[i].phys, PAGE_SIZE);
+}
+
+/*
+ * clkdbg fmeter
+ */
+
+#include <linux/delay.h>
+
+#define clk_readl(addr) readl(addr)
+#define clk_writel(addr, val) \
+ do { writel(val, addr); wmb(); } while (0) /* sync write */
+
+#define FMCLK(_t, _i, _n) { .type = _t, .id = _i, .name = _n }
+
+static const struct fmeter_clk fclks[] = {
+ FMCLK(CKGEN, 1, "hd_faxi_ck"),
+ FMCLK(CKGEN, 2, "hf_fmm_ck"),
+ FMCLK(CKGEN, 3, "hf_fimg_ck"),
+ FMCLK(CKGEN, 4, "hf_fcam_ck"),
+ FMCLK(CKGEN, 5, "hf_fdsp_ck"),
+ FMCLK(CKGEN, 6, "hf_fdsp1_ck"),
+ FMCLK(CKGEN, 7, "hf_fdsp2_ck"),
+ FMCLK(CKGEN, 8, "hf_fipu_if_ck"),
+ FMCLK(CKGEN, 9, "hf_fmfg_ck"),
+ FMCLK(CKGEN, 10, "f52m_mfg_ck"),
+ FMCLK(CKGEN, 11, "f_fcamtg_ck"),
+ FMCLK(CKGEN, 12, "f_fcamtg2_ck"),
+ FMCLK(CKGEN, 13, "f_fcamtg3_ck"),
+ FMCLK(CKGEN, 14, "f_fcamtg4_ck"),
+ FMCLK(CKGEN, 15, "f_fuart_ck"),
+ FMCLK(CKGEN, 16, "hf_fspi_ck"),
+ FMCLK(CKGEN, 17, "hf_fmsdc50_0_hclk_ck"),
+ FMCLK(CKGEN, 18, "hf_fmsdc50_0_ck"),
+ FMCLK(CKGEN, 19, "hf_fmsdc30_1_ck"),
+ FMCLK(CKGEN, 20, "hf_fmsdc30_2_ck"),
+ FMCLK(CKGEN, 21, "hf_faudio_ck"),
+ FMCLK(CKGEN, 22, "hf_faud_intbus_ck"),
+ FMCLK(CKGEN, 23, "hf_fpmicspi_ck"),
+ FMCLK(CKGEN, 24, "f_fpwrap_ulposc_ck"),
+ FMCLK(CKGEN, 25, "hf_fatb_ck"),
+ FMCLK(CKGEN, 26, "hf_fsspm_ck"),
+ FMCLK(CKGEN, 27, "hf_fdpi0_ck"),
+ FMCLK(CKGEN, 28, "hf_fscam_ck"),
+ FMCLK(CKGEN, 29, "f_fdisp_pwm_ck"),
+ FMCLK(CKGEN, 30, "f_fusb_top_ck"),
+ FMCLK(CKGEN, 31, "f_fssusb_xhci_ck"),
+ FMCLK(CKGEN, 32, "hg_fspm_ck"),
+ FMCLK(CKGEN, 33, "f_fi2c_ck"),
+ FMCLK(CKGEN, 34, "hf_fscp_ck"),
+ FMCLK(CKGEN, 35, "f_fseninf_ck"),
+ FMCLK(CKGEN, 36, "f_fdxcc_ck"),
+ FMCLK(CKGEN, 37, "hf_faud_engin1_ck"),
+ FMCLK(CKGEN, 38, "hf_faud_engin2_ck"),
+ FMCLK(CKGEN, 39, "hf_faes_ufsfde_ck"),
+ FMCLK(CKGEN, 40, "hf_fufs_ck"),
+ FMCLK(CKGEN, 41, "hf_faud_1_ck"),
+ FMCLK(CKGEN, 42, "hf_faud_2_ck"),
+ FMCLK(CKGEN, 49, "hf_fref_mm_ck"),
+ FMCLK(CKGEN, 50, "hf_fref_cam_ck"),
+ FMCLK(CKGEN, 51, "hf_hddrphycfg_ck"),
+ FMCLK(CKGEN, 52, "f_ufs_mp_sap_cfg_ck"),
+ FMCLK(CKGEN, 53, "f_ufs_tick1us_ck"),
+ FMCLK(CKGEN, 54, "hd_faxi_east_ck"),
+ FMCLK(CKGEN, 55, "hd_faxi_west_ck"),
+ FMCLK(CKGEN, 56, "hd_faxi_north_ck"),
+ FMCLK(CKGEN, 57, "hd_faxi_south_ck"),
+ FMCLK(CKGEN, 58, "hg_fmipicfg_tx_ck"),
+ FMCLK(CKGEN, 59, "fmem_ck_bfe_dcm_ch0"),
+ FMCLK(CKGEN, 60, "fmem_ck_aft_dcm_ch0"),
+ FMCLK(CKGEN, 61, "fmem_ck_bfe_dcm_ch1"),
+ FMCLK(CKGEN, 62, "fmem_ck_aft_dcm_ch1"),
+ FMCLK(CKGEN, 63, "dramc_pll104m_ck"),
+ FMCLK(ABIST, 1, "AD_WBG_DIG_CK_832M"),
+ FMCLK(ABIST, 2, "AD_WBG_DIG_CK_960M"),
+ FMCLK(ABIST, 3, "UFS_MP_CLK2FREQ"),
+ FMCLK(ABIST, 4, "AD_CSI0A_CDPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 5, "AD_CSI0B_CDPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 6, "AD_CSI1A_DPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 7, "AD_CSI1B_DPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 8, "AD_CSI2A_DPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 9, "AD_CSI2B_DPHY_DELAYCAL_CK"),
+ FMCLK(ABIST, 10, "AD_MDBPIPLL_CK"),
+ FMCLK(ABIST, 11, "AD_MDBRPPLL_CK"),
+ FMCLK(ABIST, 12, "AD_MDMCUPLL_CK"),
+ FMCLK(ABIST, 13, "AD_MDTXPLL_CK"),
+ FMCLK(ABIST, 14, "AD_MDVDSPPLL_CK"),
+ FMCLK(ABIST, 16, "AD_MDPLL_FS26M_CK"),
+ FMCLK(ABIST, 20, "AD_ARMPLL_L_CK"),
+ FMCLK(ABIST, 22, "AD_ARMPLL_LL_CK"),
+ FMCLK(ABIST, 23, "AD_MAINPLL_1092M_CK"),
+ FMCLK(ABIST, 24, "AD_UNIVPLL_1248M_CK"),
+ FMCLK(ABIST, 25, "AD_MFGPLL_CK"),
+ FMCLK(ABIST, 26, "AD_MSDCPLL_CK"),
+ FMCLK(ABIST, 27, "AD_MMPLL_CK"),
+ FMCLK(ABIST, 28, "AD_APLL1_CK"),
+ FMCLK(ABIST, 29, "AD_APLL2_CK"),
+ FMCLK(ABIST, 30, "AD_APPLLGP_TST_CK"),
+ FMCLK(ABIST, 32, "AD_UNIV_192M_CK"),
+ FMCLK(ABIST, 34, "AD_TVDPLL_CK"),
+ FMCLK(ABIST, 35, "AD_DSI0_MPPLL_TST_CK"),
+ FMCLK(ABIST, 36, "AD_DSI0_LNTC_DSICLK"),
+ FMCLK(ABIST, 37, "AD_OSC_CK_2"),
+ FMCLK(ABIST, 38, "AD_OSC_CK"),
+ FMCLK(ABIST, 39, "rtc32k_ck_i"),
+ FMCLK(ABIST, 40, "mcusys_arm_clk_out_all"),
+ FMCLK(ABIST, 41, "AD_OSC_SYNC_CK"),
+ FMCLK(ABIST, 42, "AD_OSC_SYNC_CK_2"),
+ FMCLK(ABIST, 43, "msdc01_in_ck"),
+ FMCLK(ABIST, 44, "msdc02_in_ck"),
+ FMCLK(ABIST, 45, "msdc11_in_ck"),
+ FMCLK(ABIST, 46, "msdc12_in_ck"),
+ FMCLK(ABIST, 49, "AD_CCIPLL_CK"),
+ FMCLK(ABIST, 50, "AD_MPLL_208M_CK"),
+ FMCLK(ABIST, 51, "AD_WBG_DIG_CK_CK_416M"),
+ FMCLK(ABIST, 52, "AD_WBG_B_DIG_CK_64M"),
+ FMCLK(ABIST, 53, "AD_WBG_W_DIG_CK_160M"),
+ FMCLK(ABIST, 55, "DA_UNIV_48M_DIV_CK"),
+ FMCLK(ABIST, 57, "DA_MPLL_52M_DIV_CK"),
+ FMCLK(ABIST, 60, "ckmon1_ck"),
+ FMCLK(ABIST, 61, "ckmon2_ck"),
+ FMCLK(ABIST, 62, "ckmon3_ck"),
+ FMCLK(ABIST, 63, "ckmon4_ck"),
+ {}
+};
+
+#define CLK_MISC_CFG_0 (rb[topckgen].virt + 0x104)
+#define CLK_DBG_CFG (rb[topckgen].virt + 0x10C)
+#define CLK26CALI_0 (rb[topckgen].virt + 0x220)
+#define CLK26CALI_1 (rb[topckgen].virt + 0x224)
+
+static unsigned int mt_get_ckgen_freq(unsigned int ID)
+{
+ int output = 0, i = 0;
+ unsigned int temp, clk_dbg_cfg, clk_misc_cfg_0;
+
+ clk_dbg_cfg = clk_readl(CLK_DBG_CFG);
+ clk_writel(CLK_DBG_CFG, (clk_dbg_cfg & 0xFFFFC0FC)|(ID << 8)|(0x1));
+
+ clk_misc_cfg_0 = clk_readl(CLK_MISC_CFG_0);
+ clk_writel(CLK_MISC_CFG_0, (clk_misc_cfg_0 & 0x00FFFFFF));
+
+ clk_writel(CLK26CALI_0, 0x1000);
+ clk_writel(CLK26CALI_0, 0x1010);
+
+ while (clk_readl(CLK26CALI_0) & 0x10) {
+ mdelay(10);
+ i++;
+ if (i > 10)
+ break;
+ }
+
+ temp = clk_readl(CLK26CALI_1) & 0xFFFF;
+
+ output = (temp * 26000) / 1024;
+
+ clk_writel(CLK_DBG_CFG, clk_dbg_cfg);
+ clk_writel(CLK_MISC_CFG_0, clk_misc_cfg_0);
+
+ if (i > 10)
+ return 0;
+ else
+ return output;
+
+}
+
+static unsigned int mt_get_abist_freq(unsigned int ID)
+{
+ int output = 0, i = 0;
+ unsigned int temp, clk_dbg_cfg, clk_misc_cfg_0;
+
+ clk_dbg_cfg = clk_readl(CLK_DBG_CFG);
+ clk_writel(CLK_DBG_CFG, (clk_dbg_cfg & 0xFFC0FFFC)|(ID << 16));
+
+ clk_misc_cfg_0 = clk_readl(CLK_MISC_CFG_0);
+ clk_writel(CLK_MISC_CFG_0, (clk_misc_cfg_0 & 0x00FFFFFF) | (1 << 24));
+
+ clk_writel(CLK26CALI_0, 0x1000);
+ clk_writel(CLK26CALI_0, 0x1010);
+
+ while (clk_readl(CLK26CALI_0) & 0x10) {
+ mdelay(10);
+ i++;
+ if (i > 10)
+ break;
+ }
+
+ temp = clk_readl(CLK26CALI_1) & 0xFFFF;
+
+ output = (temp * 26000) / 1024;
+
+ clk_writel(CLK_DBG_CFG, clk_dbg_cfg);
+ clk_writel(CLK_MISC_CFG_0, clk_misc_cfg_0);
+
+ if (i > 10)
+ return 0;
+ else
+ return (output * 2);
+}
+
+static u32 fmeter_freq_op(const struct fmeter_clk *fclk)
+{
+ if (fclk->type == ABIST)
+ return mt_get_abist_freq(fclk->id);
+ else if (fclk->type == CKGEN)
+ return mt_get_ckgen_freq(fclk->id);
+ return 0;
+}
+
+static const struct fmeter_clk *get_all_fmeter_clks(void)
+{
+ return fclks;
+}
+
+/*
+ * clkdbg dump_state
+ */
+
+static const char * const *get_all_clk_names(void)
+{
+ static const char * const clks[] = {
+ "armpll_ll",
+ "armpll_l",
+ "ccipll",
+ "mainpll",
+ "univ2pll",
+ "msdcpll",
+ "mmpll",
+ "mfgpll",
+ "tvdpll",
+ "apll1",
+ "apll2",
+ "apmixed_ssusb26m",
+ "apmixed_appll26m",
+ "apmixed_mipic026m",
+ "apmixed_mdpll26m",
+ "apmixed_mmsys26m",
+ "apmixed_ufs26m",
+ "apmixed_mipic126m",
+ "apmixed_mempll26m",
+ "apmixed_lvpll26m",
+ "apmixed_mipid026m",
+ "apmixed_mipid126m",
+ "syspll_ck",
+ "syspll_d2",
+ "syspll_d3",
+ "syspll_d5",
+ "syspll_d7",
+ "syspll_d2_d2",
+ "syspll_d2_d4",
+ "syspll_d2_d8",
+ "syspll_d2_d16",
+ "syspll_d3_d2",
+ "syspll_d3_d4",
+ "syspll_d3_d8",
+ "syspll_d5_d2",
+ "syspll_d5_d4",
+ "syspll_d7_d2",
+ "syspll_d7_d4",
+ "univpll_ck",
+ "univpll_d2",
+ "univpll_d3",
+ "univpll_d5",
+ "univpll_d7",
+ "univpll_d2_d2",
+ "univpll_d2_d4",
+ "univpll_d2_d8",
+ "univpll_d3_d2",
+ "univpll_d3_d4",
+ "univpll_d3_d8",
+ "univpll_d5_d2",
+ "univpll_d5_d4",
+ "univpll_d5_d8",
+ "apll1_ck",
+ "apll1_d2",
+ "apll1_d4",
+ "apll1_d8",
+ "apll2_ck",
+ "apll2_d2",
+ "apll2_d4",
+ "apll2_d8",
+ "tvdpll_ck",
+ "tvdpll_d2",
+ "tvdpll_d4",
+ "tvdpll_d8",
+ "tvdpll_d16",
+ "msdcpll_ck",
+ "msdcpll_d2",
+ "msdcpll_d4",
+ "msdcpll_d8",
+ "msdcpll_d16",
+ "ad_osc_ck",
+ "osc_d2",
+ "osc_d4",
+ "osc_d8",
+ "osc_d16",
+ "csw_f26m_ck_d2",
+ "mfgpll_ck",
+ "univ_192m_ck",
+ "univ_192m_d2",
+ "univ_192m_d4",
+ "univ_192m_d8",
+ "univ_192m_d16",
+ "univ_192m_d32",
+ "mmpll_ck",
+ "mmpll_d4",
+ "mmpll_d4_d2",
+ "mmpll_d4_d4",
+ "mmpll_d5",
+ "mmpll_d5_d2",
+ "mmpll_d5_d4",
+ "mmpll_d6",
+ "mmpll_d7",
+ "f_f26m_ck",
+ "clk13m",
+ "osc",
+ "univpll_192m",
+ "apll_i2s0_sel",
+ "apll_i2s1_sel",
+ "apll_i2s2_sel",
+ "apll_i2s3_sel",
+ "apll_i2s4_sel",
+ "apll_i2s5_sel",
+ "apll12_div0",
+ "apll12_div1",
+ "apll12_div2",
+ "apll12_div3",
+ "apll12_div4",
+ "apll12_divb",
+ "univpll",
+ "armpll_div_pll1",
+ "armpll_div_pll2",
+ "axi_sel",
+ "mm_sel",
+ "cam_sel",
+ "mfg_sel",
+ "camtg_sel",
+ "uart_sel",
+ "spi_sel",
+ "msdc50_hclk_sel",
+ "msdc50_0_sel",
+ "msdc30_1_sel",
+ "msdc30_2_sel",
+ "audio_sel",
+ "aud_intbus_sel",
+ "fpwrap_ulposc_sel",
+ "scp_sel",
+ "atb_sel",
+ "sspm_sel",
+ "dpi0_sel",
+ "scam_sel",
+ "aud_1_sel",
+ "aud_2_sel",
+ "disppwm_sel",
+ "ssusb_top_xhci_sel",
+ "usb_top_sel",
+ "spm_sel",
+ "i2c_sel",
+ "f52m_mfg_sel",
+ "seninf_sel",
+ "dxcc_sel",
+ "camtg2_sel",
+ "aud_eng1_sel",
+ "aud_eng2_sel",
+ "faes_ufsfde_sel",
+ "fufs_sel",
+ "img_sel",
+ "dsp_sel",
+ "dsp1_sel",
+ "dsp2_sel",
+ "ipu_if_sel",
+ "camtg3_sel",
+ "camtg4_sel",
+ "pmicspi_sel",
+ "mcu_mp0_sel",
+ "mcu_mp2_sel",
+ "mcu_bus_sel",
+ "infra_pmic_tmr",
+ "infra_pmic_ap",
+ "infra_pmic_md",
+ "infra_pmic_conn",
+ "infra_scp",
+ "infra_sej",
+ "infra_apxgpt",
+ "infra_icusb",
+ "infra_gce",
+ "infra_therm",
+ "infra_i2c0",
+ "infra_i2c1",
+ "infra_i2c2",
+ "infra_i2c3",
+ "infra_pwm_hclk",
+ "infra_pwm1",
+ "infra_pwm2",
+ "infra_pwm3",
+ "infra_pwm4",
+ "infra_pwm",
+ "infra_uart0",
+ "infra_uart1",
+ "infra_uart2",
+ "infra_uart3",
+ "infra_gce_26m",
+ "infra_cqdma_fpc",
+ "infra_btif",
+ "infra_spi0",
+ "infra_msdc0",
+ "infra_msdc1",
+ "infra_msdc2",
+ "infra_msdc0_sck",
+ "infra_dvfsrc",
+ "infra_gcpu",
+ "infra_trng",
+ "infra_auxadc",
+ "infra_cpum",
+ "infra_ccif1_ap",
+ "infra_ccif1_md",
+ "infra_auxadc_md",
+ "infra_msdc1_sck",
+ "infra_msdc2_sck",
+ "infra_apdma",
+ "infra_xiu",
+ "infra_device_apc",
+ "infra_ccif_ap",
+ "infra_debugsys",
+ "infra_audio",
+ "infra_ccif_md",
+ "infra_dxcc_sec_core",
+ "infra_dxcc_ao",
+ "infra_dramc_f26m",
+ "infra_irtx",
+ "infra_disppwm",
+ "infra_cldma_bclk",
+ "infra_audio_26m_bclk",
+ "infra_spi1",
+ "infra_i2c4",
+ "infra_md_tmp_share",
+ "infra_spi2",
+ "infra_spi3",
+ "infra_unipro_sck",
+ "infra_unipro_tick",
+ "infra_ufs_mp_sap_bck",
+ "infra_md32_bclk",
+ "infra_sspm",
+ "infra_unipro_mbist",
+ "infra_sspm_bus_hclk",
+ "infra_i2c5",
+ "infra_i2c5_arbiter",
+ "infra_i2c5_imm",
+ "infra_i2c1_arbiter",
+ "infra_i2c1_imm",
+ "infra_i2c2_arbiter",
+ "infra_i2c2_imm",
+ "infra_spi4",
+ "infra_spi5",
+ "infra_cqdma",
+ "infra_ufs",
+ "infra_aes_ufsfde",
+ "infra_ufs_tick",
+ "infra_msdc0_self",
+ "infra_msdc1_self",
+ "infra_msdc2_self",
+ "infra_sspm_26m_self",
+ "infra_sspm_32k_self",
+ "infra_ufs_axi",
+ "infra_i2c6",
+ "infra_ap_msdc0",
+ "infra_md_msdc0",
+ "infra_usb",
+ "infra_devmpu_bclk",
+ "infra_ccif2_ap",
+ "infra_ccif2_md",
+ "infra_ccif3_ap",
+ "infra_ccif3_md",
+ "infra_sej_f13m",
+ "infra_aes_bclk",
+ "infra_i2c7",
+ "infra_i2c8",
+ "infra_fbist2fpc",
+ "aud_tml",
+ "aud_dac_predis",
+ "aud_dac",
+ "aud_adc",
+ "aud_apll_tuner",
+ "aud_apll2_tuner",
+ "aud_24m",
+ "aud_22m",
+ "aud_afe",
+ "aud_i2s4",
+ "aud_i2s3",
+ "aud_i2s2",
+ "aud_i2s1",
+ "aud_pdn_adda6_adc",
+ "aud_tdm",
+ "mfg_bg3d",
+ "mm_smi_common",
+ "mm_smi_larb0",
+ "mm_smi_larb1",
+ "mm_gals_comm0",
+ "mm_gals_comm1",
+ "mm_gals_ccu2mm",
+ "mm_gals_ipu12mm",
+ "mm_gals_img2mm",
+ "mm_gals_cam2mm",
+ "mm_gals_ipu2mm",
+ "mm_mdp_dl_txck",
+ "mm_ipu_dl_txck",
+ "mm_mdp_rdma0",
+ "mm_mdp_rdma1",
+ "mm_mdp_rsz0",
+ "mm_mdp_rsz1",
+ "mm_mdp_tdshp",
+ "mm_mdp_wrot0",
+ "mm_fake_eng",
+ "mm_disp_ovl0",
+ "mm_disp_ovl0_2l",
+ "mm_disp_ovl1_2l",
+ "mm_disp_rdma0",
+ "mm_disp_rdma1",
+ "mm_disp_wdma0",
+ "mm_disp_color0",
+ "mm_disp_ccorr0",
+ "mm_disp_aal0",
+ "mm_disp_gamma0",
+ "mm_disp_dither0",
+ "mm_disp_split",
+ "mm_dsi0_mm",
+ "mm_dsi0_if",
+ "mm_dpi_mm",
+ "mm_dpi_if",
+ "mm_fake_eng2",
+ "mm_mdp_dl_rx",
+ "mm_ipu_dl_rx",
+ "mm_26m",
+ "mm_mmsys_r2y",
+ "mm_disp_rsz",
+ "mm_mdp_wdma0",
+ "mm_mdp_aal",
+ "mm_mdp_ccorr",
+ "mm_dbi_mm",
+ "mm_dbi_if",
+ "vdec_vdec",
+ "vdec_larb1",
+ "venc_larb",
+ "venc_venc",
+ "venc_jpgenc",
+ "img_owe",
+ "img_wpe_b",
+ "img_wpe_a",
+ "img_mfb",
+ "img_rsc",
+ "img_dpe",
+ "img_fdvt",
+ "img_dip",
+ "img_larb2",
+ "img_larb5",
+ "cam_larb6",
+ "cam_dfp_vad",
+ "cam_cam",
+ "cam_camtg",
+ "cam_seninf",
+ "cam_camsv0",
+ "cam_camsv1",
+ "cam_camsv2",
+ "cam_ccu",
+ "cam_larb3",
+ "ipu_conn_ipu",
+ "ipu_conn_ahb",
+ "ipu_conn_axi",
+ "ipu_conn_isp",
+ "ipu_conn_cam_adl",
+ "ipu_conn_img_adl",
+ "ipu_conn_dap_rx",
+ "ipu_conn_apb2axi",
+ "ipu_conn_apb2ahb",
+ "ipu_conn_ipu_cab1to2",
+ "ipu_conn_ipu1_cab1to2",
+ "ipu_conn_ipu2_cab1to2",
+ "ipu_conn_cab3to3",
+ "ipu_conn_cab2to1",
+ "ipu_conn_cab3to1_slice",
+ "ipu_adl_cabgen",
+ "ipu_core0_jtag",
+ "ipu_core0_axi",
+ "ipu_core0_ipu",
+ "ipu_core1_jtag",
+ "ipu_core1_axi",
+ "ipu_core1_ipu",
+ /* end */
+ NULL
+ };
+
+ return clks;
+}
+
+/*
+ * clkdbg pwr_status
+ */
+
+static const char * const *get_pwr_names(void)
+{
+ static const char * const pwr_names[] = {
+ [0] = "MD1",
+ [1] = "CONN",
+ [2] = "DDRPHY",
+ [3] = "DISP",
+ [4] = "MFG",
+ [5] = "ISP",
+ [6] = "INFRA",
+ [7] = "MFG_CORE0",
+ [8] = "MP0_CPUTOP",
+ [9] = "MP0_CPU0",
+ [10] = "MP0_CPU1",
+ [11] = "MP0_CPU2",
+ [12] = "MP0_CPU3",
+ [13] = "",
+ [14] = "",
+ [15] = "",
+ [16] = "",
+ [17] = "",
+ [18] = "",
+ [19] = "",
+ [20] = "MFG_CORE1",
+ [21] = "VENC",
+ [22] = "MFG_2D",
+ [23] = "MFG_ASYNC",
+ [24] = "AUDIO",
+ [25] = "CAM",
+ [26] = "VPU_TOP",
+ [27] = "VPU_CORE0",
+ [28] = "VPU_CORE1",
+ [29] = "VPU_CORE2",
+ [30] = "",
+ [31] = "VDEC",
+ };
+
+ return pwr_names;
+}
+
+u32 get_spm_pwr_status(void)
+{
+ static void __iomem *scpsys_base, *pwr_sta, *pwr_sta_2nd;
+
+ if (scpsys_base == NULL || pwr_sta == NULL || pwr_sta_2nd == NULL) {
+ scpsys_base = ioremap(0x10006000, PAGE_SIZE);
+ pwr_sta = scpsys_base + 0x180;
+ pwr_sta_2nd = scpsys_base + 0x184;
+ }
+
+ return clk_readl(pwr_sta) & clk_readl(pwr_sta_2nd);
+}
+
+/*
+ * clkdbg dump_clks
+ */
+
+static void setup_provider_clk(struct provider_clk *pvdck)
+{
+ static const struct {
+ const char *pvdname;
+ u32 pwr_mask;
+ } pvd_pwr_mask[] = {
+ {"mmsys", BIT(3)},
+ {"imgsys", BIT(5)},
+ {"camsys", BIT(25)},
+ {"ipu_conn", BIT(26)},
+ {"ipu_core0", BIT(27)},
+ {"ipu_core1", BIT(28)},
+ {"audiosys", BIT(24)},
+ {"mfgcfg", BIT(22)},
+ };
+
+ size_t i;
+ const char *pvdname = pvdck->provider_name;
+
+ if (pvdname == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(pvd_pwr_mask); i++) {
+ if (strcmp(pvdname, pvd_pwr_mask[i].pvdname) == 0) {
+ pvdck->pwr_mask = pvd_pwr_mask[i].pwr_mask;
+ return;
+ }
+ }
+}
+
+/*
+ * init functions
+ */
+
+static struct clkdbg_ops clkdbg_mt8183_ops = {
+ .get_all_fmeter_clks = get_all_fmeter_clks,
+ .fmeter_freq = fmeter_freq_op,
+ .get_all_regnames = get_all_regnames,
+ .get_all_clk_names = get_all_clk_names,
+ .get_pwr_names = get_pwr_names,
+ .setup_provider_clk = setup_provider_clk,
+ .get_spm_pwr_status = get_spm_pwr_status,
+};
+
+static void __init init_custom_cmds(void)
+{
+ static const struct cmd_fn cmds[] = {
+ {}
+ };
+
+ set_custom_cmds(cmds);
+}
+
+static int __init clkdbg_mt8183_init(void)
+{
+ if (of_machine_is_compatible("mediatek,mt8183") == 0)
+ return -ENODEV;
+
+ init_regbase();
+
+ init_custom_cmds();
+ set_clkdbg_ops(&clkdbg_mt8183_ops);
+
+#if DUMP_INIT_STATE
+ print_regs();
+ print_fmeter_all();
+#endif /* DUMP_INIT_STATE */
+
+ return 0;
+}
+device_initcall(clkdbg_mt8183_init);
diff --git a/drivers/clk/mediatek/clkdbg.c b/drivers/clk/mediatek/clkdbg.c
new file mode 100644
index 000000000000..8c9f67968160
--- /dev/null
+++ b/drivers/clk/mediatek/clkdbg.c
@@ -0,0 +1,2242 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 MediaTek Inc.
+// Author: Weiyi Lu <weiyi.lu@mediatek.com>
+
+#define pr_fmt(fmt) "[clkdbg] " fmt
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/proc_fs.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include "clkdbg.h"
+
+#if defined(CONFIG_PM_DEBUG)
+#define CLKDBG_PM_DOMAIN 1
+#else
+#define CLKDBG_PM_DOMAIN 0
+#endif
+#define CLKDBG_PM_DOMAIN_API_4_9 1
+#define CLKDBG_CCF_API_4_4 1
+#define CLKDBG_HACK_CLK 0
+#define CLKDBG_HACK_CLK_CORE 1
+#define CLKDBG_DROP_GENPD_AS_IN_PARAM 1
+
+#if !CLKDBG_CCF_API_4_4
+
+/* backward compatible */
+
+static const char *clk_hw_get_name(const struct clk_hw *hw)
+{
+ return __clk_get_name(hw->clk);
+}
+
+static bool clk_hw_is_prepared(const struct clk_hw *hw)
+{
+ return __clk_is_prepared(hw->clk);
+}
+
+static bool clk_hw_is_enabled(const struct clk_hw *hw)
+{
+ return __clk_is_enabled(hw->clk);
+}
+
+static unsigned long clk_hw_get_rate(const struct clk_hw *hw)
+{
+ return __clk_get_rate(hw->clk);
+}
+
+static unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
+{
+ return __clk_get_num_parents(hw->clk);
+}
+
+static struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
+ unsigned int index)
+{
+ return __clk_get_hw(clk_get_parent_by_index(hw->clk, index));
+}
+
+#endif /* !CLKDBG_CCF_API_4_4 */
+
+#if CLKDBG_HACK_CLK
+
+#include <linux/clk-private.h>
+
+static bool clk_hw_is_on(struct clk_hw *hw)
+{
+ const struct clk_ops *ops = hw->clk->ops;
+
+ if (ops->is_enabled)
+ return clk_hw_is_enabled(hw);
+ else if (ops->is_prepared)
+ return clk_hw_is_prepared(hw);
+ return clk_hw_is_enabled(hw) || clk_hw_is_prepared(hw);
+}
+
+#elif CLKDBG_HACK_CLK_CORE
+
+struct clk_core {
+ const char *name;
+ const struct clk_ops *ops;
+ struct clk_hw *hw;
+};
+
+static bool clk_hw_is_on(struct clk_hw *hw)
+{
+ const struct clk_ops *ops = hw->core->ops;
+
+ if (ops->is_enabled)
+ return clk_hw_is_enabled(hw);
+ else if (ops->is_prepared)
+ return clk_hw_is_prepared(hw);
+ return clk_hw_is_enabled(hw) || clk_hw_is_prepared(hw);
+}
+
+#else
+
+static bool clk_hw_is_on(struct clk_hw *hw)
+{
+ return __clk_get_enable_count(hw->clk) || clk_hw_is_prepared(hw);
+}
+
+#endif /* !CLKDBG_HACK_CLK && !CLKDBG_HACK_CLK_CORE */
+
+static const struct clkdbg_ops *clkdbg_ops;
+
+void set_clkdbg_ops(const struct clkdbg_ops *ops)
+{
+ clkdbg_ops = ops;
+}
+
+static const struct fmeter_clk *get_all_fmeter_clks(void)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->get_all_fmeter_clks == NULL)
+ return NULL;
+
+ return clkdbg_ops->get_all_fmeter_clks();
+}
+
+static void *prepare_fmeter(void)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->prepare_fmeter == NULL)
+ return NULL;
+
+ return clkdbg_ops->prepare_fmeter();
+}
+
+static void unprepare_fmeter(void *data)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->unprepare_fmeter == NULL)
+ return;
+
+ clkdbg_ops->unprepare_fmeter(data);
+}
+
+static u32 fmeter_freq(const struct fmeter_clk *fclk)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->fmeter_freq == NULL)
+ return 0;
+
+ return clkdbg_ops->fmeter_freq(fclk);
+}
+
+static const struct regname *get_all_regnames(void)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->get_all_regnames == NULL)
+ return NULL;
+
+ return clkdbg_ops->get_all_regnames();
+}
+
+static const char * const *get_all_clk_names(void)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->get_all_clk_names == NULL)
+ return NULL;
+
+ return clkdbg_ops->get_all_clk_names();
+}
+
+static const char * const *get_pwr_names(void)
+{
+ static const char * const default_pwr_names[] = {
+ [0] = "(MD)",
+ [1] = "(CONN)",
+ [2] = "(DDRPHY)",
+ [3] = "(DISP)",
+ [4] = "(MFG)",
+ [5] = "(ISP)",
+ [6] = "(INFRA)",
+ [7] = "(VDEC)",
+ [8] = "(CPU, CA7_CPUTOP)",
+ [9] = "(FC3, CA7_CPU0, CPUTOP)",
+ [10] = "(FC2, CA7_CPU1, CPU3)",
+ [11] = "(FC1, CA7_CPU2, CPU2)",
+ [12] = "(FC0, CA7_CPU3, CPU1)",
+ [13] = "(MCUSYS, CA7_DBG, CPU0)",
+ [14] = "(MCUSYS, VEN, BDP)",
+ [15] = "(CA15_CPUTOP, ETH, MCUSYS)",
+ [16] = "(CA15_CPU0, HIF)",
+ [17] = "(CA15_CPU1, CA15-CX0, INFRA_MISC)",
+ [18] = "(CA15_CPU2, CA15-CX1)",
+ [19] = "(CA15_CPU3, CA15-CPU0)",
+ [20] = "(VEN2, MJC, CA15-CPU1)",
+ [21] = "(VEN, CA15-CPUTOP)",
+ [22] = "(MFG_2D)",
+ [23] = "(MFG_ASYNC, DBG)",
+ [24] = "(AUDIO, MFG_2D)",
+ [25] = "(USB, VCORE_PDN, MFG_ASYNC)",
+ [26] = "(ARMPLL_DIV, CPUTOP_SRM_SLPB)",
+ [27] = "(MD2, CPUTOP_SRM_PDN)",
+ [28] = "(CPU3_SRM_PDN)",
+ [29] = "(CPU2_SRM_PDN)",
+ [30] = "(CPU1_SRM_PDN)",
+ [31] = "(CPU0_SRM_PDN)",
+ };
+
+ if (clkdbg_ops == NULL || clkdbg_ops->get_pwr_names == NULL)
+ return default_pwr_names;
+
+ return clkdbg_ops->get_pwr_names();
+}
+
+static void setup_provider_clk(struct provider_clk *pvdck)
+{
+ if (clkdbg_ops == NULL || clkdbg_ops->setup_provider_clk == NULL)
+ return;
+
+ clkdbg_ops->setup_provider_clk(pvdck);
+}
+
+static bool is_valid_reg(void __iomem *addr)
+{
+#ifdef CONFIG_64BIT
+ return ((u64)addr & 0xf0000000) != 0UL ||
+ (((u64)addr >> 32U) & 0xf0000000) != 0UL;
+#else
+ return ((u32)addr & 0xf0000000) != 0U;
+#endif
+}
+
+enum clkdbg_opt {
+ CLKDBG_EN_SUSPEND_SAVE_1,
+ CLKDBG_EN_SUSPEND_SAVE_2,
+ CLKDBG_EN_SUSPEND_SAVE_3,
+ CLKDBG_EN_LOG_SAVE_POINTS,
+};
+
+static u32 clkdbg_flags;
+
+static void set_clkdbg_flag(enum clkdbg_opt opt)
+{
+ clkdbg_flags |= BIT(opt);
+}
+
+static void clr_clkdbg_flag(enum clkdbg_opt opt)
+{
+ clkdbg_flags &= ~BIT(opt);
+}
+
+static bool has_clkdbg_flag(enum clkdbg_opt opt)
+{
+ return (clkdbg_flags & BIT(opt)) != 0U;
+}
+
+typedef void (*fn_fclk_freq_proc)(const struct fmeter_clk *fclk,
+ u32 freq, void *data);
+
+static void proc_all_fclk_freq(fn_fclk_freq_proc proc, void *data)
+{
+ void *fmeter_data;
+ const struct fmeter_clk *fclk;
+
+ fclk = get_all_fmeter_clks();
+
+ if (fclk == NULL || proc == NULL)
+ return;
+
+ fmeter_data = prepare_fmeter();
+
+ for (; fclk->type != FT_NULL; fclk++) {
+ u32 freq;
+
+ freq = fmeter_freq(fclk);
+ proc(fclk, freq, data);
+ }
+
+ unprepare_fmeter(fmeter_data);
+}
+
+static void print_fclk_freq(const struct fmeter_clk *fclk, u32 freq, void *data)
+{
+ pr_info("%2d: %-29s: %u\n", fclk->id, fclk->name, freq);
+}
+
+void print_fmeter_all(void)
+{
+ proc_all_fclk_freq(print_fclk_freq, NULL);
+}
+
+static void seq_print_fclk_freq(const struct fmeter_clk *fclk,
+ u32 freq, void *data)
+{
+ struct seq_file *s = data;
+
+ seq_printf(s, "%2d: %-29s: %u\n", fclk->id, fclk->name, freq);
+}
+
+static int seq_print_fmeter_all(struct seq_file *s, void *v)
+{
+ proc_all_fclk_freq(seq_print_fclk_freq, s);
+
+ return 0;
+}
+
+typedef void (*fn_regname_proc)(const struct regname *rn, void *data);
+
+static void proc_all_regname(fn_regname_proc proc, void *data)
+{
+ const struct regname *rn = get_all_regnames();
+
+ if (rn == NULL)
+ return;
+
+ for (; rn->base != NULL; rn++)
+ proc(rn, data);
+}
+
+static void print_reg(const struct regname *rn, void *data)
+{
+ if (!is_valid_reg(ADDR(rn)))
+ return;
+
+ pr_info("%-21s: [0x%08x][0x%p] = 0x%08x\n",
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn)));
+}
+
+void print_regs(void)
+{
+ proc_all_regname(print_reg, NULL);
+}
+
+static void seq_print_reg(const struct regname *rn, void *data)
+{
+ struct seq_file *s = data;
+
+ if (!is_valid_reg(ADDR(rn)))
+ return;
+
+ seq_printf(s, "%-21s: [0x%08x][0x%p] = 0x%08x\n",
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn)));
+}
+
+static int seq_print_regs(struct seq_file *s, void *v)
+{
+ proc_all_regname(seq_print_reg, s);
+
+ return 0;
+}
+
+static void print_reg2(const struct regname *rn, void *data)
+{
+ if (!is_valid_reg(ADDR(rn)))
+ return;
+
+ pr_info("%-21s: [0x%08x][0x%p] = 0x%08x\n",
+ rn->name, PHYSADDR(rn), ADDR(rn), clk_readl(ADDR(rn)));
+
+ msleep(20);
+}
+
+static int clkdbg_dump_regs2(struct seq_file *s, void *v)
+{
+ proc_all_regname(print_reg2, s);
+
+ return 0;
+}
+
+static u32 read_spm_pwr_status(void)
+{
+ static void __iomem *scpsys_base, *pwr_sta, *pwr_sta_2nd;
+
+ if (clkdbg_ops == NULL || clkdbg_ops->get_spm_pwr_status == NULL) {
+ if (scpsys_base == NULL ||
+ pwr_sta == NULL || pwr_sta_2nd == NULL) {
+ scpsys_base = ioremap(0x10006000, PAGE_SIZE);
+ pwr_sta = scpsys_base + 0x60c;
+ pwr_sta_2nd = scpsys_base + 0x610;
+ }
+
+ return clk_readl(pwr_sta) & clk_readl(pwr_sta_2nd);
+ } else
+ return clkdbg_ops->get_spm_pwr_status();
+}
+
+static bool clk_hw_pwr_is_on(struct clk_hw *c_hw,
+ u32 spm_pwr_status, u32 pwr_mask)
+{
+ if ((spm_pwr_status & pwr_mask) != pwr_mask)
+ return false;
+
+ return clk_hw_is_on(c_hw);
+}
+
+static bool pvdck_pwr_is_on(struct provider_clk *pvdck, u32 spm_pwr_status)
+{
+ struct clk *c = pvdck->ck;
+ struct clk_hw *c_hw = __clk_get_hw(c);
+
+ return clk_hw_pwr_is_on(c_hw, spm_pwr_status, pvdck->pwr_mask);
+}
+
+static bool pvdck_is_on(struct provider_clk *pvdck)
+{
+ u32 spm_pwr_status = 0;
+
+ if (pvdck->pwr_mask != 0U)
+ spm_pwr_status = read_spm_pwr_status();
+
+ return pvdck_pwr_is_on(pvdck, spm_pwr_status);
+}
+
+static const char *ccf_state(struct clk_hw *hw)
+{
+ if (__clk_get_enable_count(hw->clk))
+ return "enabled";
+
+ if (clk_hw_is_prepared(hw))
+ return "prepared";
+
+ return "disabled";
+}
+
+static void dump_clk_state(const char *clkname, struct seq_file *s)
+{
+ struct clk *c = __clk_lookup(clkname);
+ struct clk *p = IS_ERR_OR_NULL(c) ? NULL : clk_get_parent(c);
+ struct clk_hw *c_hw = __clk_get_hw(c);
+ struct clk_hw *p_hw = __clk_get_hw(p);
+
+ if (IS_ERR_OR_NULL(c)) {
+ seq_printf(s, "[%17s: NULL]\n", clkname);
+ return;
+ }
+
+ seq_printf(s, "[%-17s: %8s, %3d, %3d, %10ld, %17s]\n",
+ clk_hw_get_name(c_hw),
+ ccf_state(c_hw),
+ clk_hw_is_prepared(c_hw),
+ __clk_get_enable_count(c),
+ clk_hw_get_rate(c_hw),
+ p != NULL ? clk_hw_get_name(p_hw) : "- ");
+}
+
+static int clkdbg_dump_state_all(struct seq_file *s, void *v)
+{
+ const char * const *ckn = get_all_clk_names();
+
+ if (ckn == NULL)
+ return 0;
+
+ for (; *ckn != NULL; ckn++)
+ dump_clk_state(*ckn, s);
+
+ return 0;
+}
+
+static const char *get_provider_name(struct device_node *node, u32 *cells)
+{
+ const char *name;
+ const char *p;
+ u32 cc;
+
+ if (of_property_read_u32(node, "#clock-cells", &cc) != 0)
+ cc = 0;
+
+ if (cells != NULL)
+ *cells = cc;
+
+ if (cc == 0U) {
+ if (of_property_read_string(node,
+ "clock-output-names", &name) < 0)
+ name = node->name;
+
+ return name;
+ }
+
+ if (of_property_read_string(node, "compatible", &name) < 0)
+ name = node->name;
+
+ p = strchr(name, (int)'-');
+
+ if (p != NULL)
+ return p + 1;
+ else
+ return name;
+}
+
+struct provider_clk *get_all_provider_clks(void)
+{
+ static struct provider_clk provider_clks[512];
+ struct device_node *node = NULL;
+ int n = 0;
+
+ if (provider_clks[0].ck != NULL)
+ return provider_clks;
+
+ do {
+ const char *node_name;
+ u32 cells;
+
+ node = of_find_node_with_property(node, "#clock-cells");
+
+ if (node == NULL)
+ break;
+
+ node_name = get_provider_name(node, &cells);
+
+ if (cells == 0U) {
+ struct clk *ck = __clk_lookup(node_name);
+
+ if (IS_ERR_OR_NULL(ck))
+ continue;
+
+ provider_clks[n].ck = ck;
+ setup_provider_clk(&provider_clks[n]);
+ ++n;
+ } else {
+ unsigned int i;
+
+ for (i = 0; i < 256; i++) {
+ struct of_phandle_args pa;
+ struct clk *ck;
+
+ pa.np = node;
+ pa.args[0] = i;
+ pa.args_count = 1;
+ ck = of_clk_get_from_provider(&pa);
+
+ if (PTR_ERR(ck) == -EINVAL)
+ break;
+ else if (IS_ERR_OR_NULL(ck))
+ continue;
+
+ provider_clks[n].ck = ck;
+ provider_clks[n].idx = i;
+ provider_clks[n].provider_name = node_name;
+ setup_provider_clk(&provider_clks[n]);
+ ++n;
+ }
+ }
+ } while (node != NULL);
+
+ return provider_clks;
+}
+
+static void dump_provider_clk(struct provider_clk *pvdck, struct seq_file *s)
+{
+ struct clk *c = pvdck->ck;
+ struct clk *p = IS_ERR_OR_NULL(c) ? NULL : clk_get_parent(c);
+ struct clk_hw *c_hw = __clk_get_hw(c);
+ struct clk_hw *p_hw = __clk_get_hw(p);
+
+ seq_printf(s, "[%10s: %-17s: %3s, %3d, %3d, %10ld, %17s]\n",
+ pvdck->provider_name != NULL ? pvdck->provider_name : "/ ",
+ clk_hw_get_name(c_hw),
+ pvdck_is_on(pvdck) ? "ON" : "off",
+ clk_hw_is_prepared(c_hw),
+ __clk_get_enable_count(c),
+ clk_hw_get_rate(c_hw),
+ p != NULL ? clk_hw_get_name(p_hw) : "- ");
+}
+
+static int clkdbg_dump_provider_clks(struct seq_file *s, void *v)
+{
+ struct provider_clk *pvdck = get_all_provider_clks();
+
+ for (; pvdck->ck != NULL; pvdck++)
+ dump_provider_clk(pvdck, s);
+
+ return 0;
+}
+
+static void dump_provider_mux(struct provider_clk *pvdck, struct seq_file *s)
+{
+ unsigned int i;
+ struct clk *c = pvdck->ck;
+ struct clk_hw *c_hw = __clk_get_hw(c);
+ unsigned int np = clk_hw_get_num_parents(c_hw);
+
+ if (np <= 1U)
+ return;
+
+ dump_provider_clk(pvdck, s);
+
+ for (i = 0; i < np; i++) {
+ struct clk_hw *p_hw = clk_hw_get_parent_by_index(c_hw, i);
+
+ if (IS_ERR_OR_NULL(p_hw))
+ continue;
+
+ seq_printf(s, "\t\t\t(%2d: %-17s: %8s, %10ld)\n",
+ i,
+ clk_hw_get_name(p_hw),
+ ccf_state(p_hw),
+ clk_hw_get_rate(p_hw));
+ }
+}
+
+static int clkdbg_dump_muxes(struct seq_file *s, void *v)
+{
+ struct provider_clk *pvdck = get_all_provider_clks();
+
+ for (; pvdck->ck != NULL; pvdck++)
+ dump_provider_mux(pvdck, s);
+
+ return 0;
+}
+
+static void show_pwr_status(u32 spm_pwr_status)
+{
+ unsigned int i;
+ const char * const *pwr_name = get_pwr_names();
+
+ pr_info("SPM_PWR_STATUS: 0x%08x\n\n", spm_pwr_status);
+
+ for (i = 0; i < 32; i++) {
+ const char *st = (spm_pwr_status & BIT(i)) != 0U ? "ON" : "off";
+
+ pr_info("[%2d]: %3s: %s\n", i, st, pwr_name[i]);
+ mdelay(20);
+ }
+}
+
+static int dump_pwr_status(u32 spm_pwr_status, struct seq_file *s)
+{
+ unsigned int i;
+ const char * const *pwr_name = get_pwr_names();
+
+ seq_printf(s, "SPM_PWR_STATUS: 0x%08x\n\n", spm_pwr_status);
+
+ for (i = 0; i < 32; i++) {
+ const char *st = (spm_pwr_status & BIT(i)) != 0U ? "ON" : "off";
+
+ seq_printf(s, "[%2d]: %3s: %s\n", i, st, pwr_name[i]);
+ }
+
+ return 0;
+}
+
+static int clkdbg_pwr_status(struct seq_file *s, void *v)
+{
+ return dump_pwr_status(read_spm_pwr_status(), s);
+}
+
+static char last_cmd[128] = "null";
+
+const char *get_last_cmd(void)
+{
+ return last_cmd;
+}
+
+static int clkop_int_ckname(int (*clkop)(struct clk *clk),
+ const char *clkop_name, const char *clk_name,
+ struct clk *ck, struct seq_file *s)
+{
+ struct clk *clk;
+
+ if (!IS_ERR_OR_NULL(ck)) {
+ clk = ck;
+ } else {
+ clk = __clk_lookup(clk_name);
+ if (IS_ERR_OR_NULL(clk)) {
+ seq_printf(s, "clk_lookup(%s): 0x%p\n", clk_name, clk);
+ return PTR_ERR(clk);
+ }
+ }
+
+ return clkop(clk);
+}
+
+static int clkdbg_clkop_int_ckname(int (*clkop)(struct clk *