blob: d9a49df685a63b5d6537e8eedfaaf415966c98fc [file] [log] [blame]
<
From a7fcd02e6c1392a72f79d6173d56d65aafd9c3ae Mon Sep 17 00:00:00 2001
From: Nicolas Boichat <drinkcat@chromium.org>
Date: Thu, 7 Mar 2019 18:17:32 +0800
Subject: [PATCH 2/3] HQ-TOT 40
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1475596/40
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>
FIXUP: FROMLIST: arm64: dts: add display nodes for mt8183
This patch add display nodes for mt8183
BUG=b:126008314
TEST=Boot to shell
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>
FROMLIST: gpu/drm: mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable()
mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), which needs
ovl irq for drm_crtc_wait_one_vblank(), since after mtk_dsi_stop() is called,
ovl irq will be disabled. If drm_crtc_wait_one_vblank() is called after last
irq, it will timeout with this message: "vblank wait timed out on crtc 0". This
happens sometimes when turning off the screen.
In drm_atomic_helper.c#disable_outputs(),
the calling sequence when turning off the screen is:
1. mtk_dsi_encoder_disable()
--> mtk_output_dsi_disable()
--> mtk_dsi_stop(); // sometimes make vblank timeout in atomic_disable
--> mtk_dsi_poweroff();
2. mtk_drm_crtc_atomic_disable()
--> drm_crtc_wait_one_vblank();
...
--> mtk_dsi_ddp_stop()
--> mtk_dsi_poweroff();
Change to make mtk_dsi_stop() called in mtk_dsi_ddp_stop() instead of
mtk_output_dsi_disable().
(am from https://patchwork.kernel.org/patch/10856865/)
TEST=suspend_stress_test 182 iteration no timeout warning
BUG=b:124486047
Fixes: 0707632b5bac ("drm/mediatek: update DSI sub driver flow for sending commands to panel")
Change-Id: I0916976b27877ed700e339c31022b393ca9e91a4
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
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>
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>
CHROMIUM: config: enable BOE HIMAX8279D config
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_HIMAX8279D=y
EOF
./chromeos/scripts/kernelconfig olddefconfig
BUG=b:128652504
TEST=None
Change-Id: Idc9444ee10a99a994839cc686c8ec1d0e05a9130
WIP: CHROMIUM: arm64: dts: mt8183: add flapjack board rev3 dts and Makefile
Add flapjack board rev3 dts and Makefile.
1. Board ID of P0C and P1 is 3.
2. SKU ID Map:
0: CBI is blank
1: 8 inch flapjack
3: 10 inch flapjack
3. Display Panel Info
hwconfig0: boe,himax8279d10p
hwconfig1: boe,himax8279d8p
TO-DO: The hwconfig may changes in future.
BUG=b:124634888
TEST=build and boot to shell
Change-Id: Iee95096bf8ddabe0747b5d8adc735c4bae209c3d
Signed-off-by: Kaka Ni <nigang@huaqin.corp-partner.google.com>
CHROMIUM: arm64: dts: mt8183: Support Wacom W9015A for flapjack
Enable Stylus Wacom W9015A for flapjack
BUG=b:124639007
TEST=1). Boot to shell
2). Run "evtest" in console and get results :
Available devices:
/dev/input/event0: hid-over-i2c 2D1F:490C
/dev/input/event1: hid-over-i2c 2D1F:490C Pen
Change-Id: I3d9ae8fd61350f0e73c8b5f5d4ebcba9d851acd4
Signed-off-by: Kaka Ni <nigang@huaqin.corp-partner.google.com>
DO-NOT-SUBMIT:ASoC: mt8183: machine driver support da7219
Cherry-picks CL:1520431
Only for Huaqin Flapjack ToT
BUG=b:124717947
TEST=build pass and boot to shell
Change-Id: Idbdc9bb99f7d4b3ce1d5ff1ff4c344a53b939295
WIP: CHROMIUM: config: enable SND_SOC_MT8183_DA7219_MAX98357A
Cherry-picks CL:1424761
Only for Huaqin Flapjack ToT
BUG=None
TEST=None
Change-Id: I94c3b3b229c7dda4124dbc42895b2ae78ed6cdee
WIP: CHROMIUM: arm64: dts: mt8183: Support DA7219
Cherry-picks CL:1424761
Only for Huaqin Flapjack ToT
BUG=None
TEST=None
Change-Id: I8683080325dae35133a9981b3af10d68b5412345
DO-NOT-SUBMIT:max98357a:add dai without triggered by pcm
Cherry-picks CL:1520429
Only for Huaqin Flapjack ToT
max98357a's enable pin need setting independently
when max98357a is shared I2S with other codec.
add dai "max98357a-hifi" without pcm trigger,
and use "Spk PA Switch" to set the enable pin.
BRANCH=none
BUG=b:124721198
TEST= build flapjack ok, and can boot up to shell.
Change-Id: I81e4c091f501d10315b829eb78e7c18cecbfac9f
WIP:flapjack:separate speaker control from pcm
use dai "max98357a-hifi" to separate speaker control from pcm
BRANCH=none
BUG=b:124721198
TEST=local build test ok.
Change-Id: I5dc7c5932b9331dd395adcdad0d3aacb740a72fc
DO-NOT-SUBMIT: CHROMIUM: iio: Add SEMTECH SX9311 sensor driver
Add SEMTECH SX9311 driver. just include it in Flapjack ToT Tree.
BUG=b:124858024
BRANCH=None
TEST=On Nocturne, check:
- that the device is correctly probed and instantiated;
- that it is possible to enable events on all channels and read from /dev
- can test with toolkit
Change-Id: Id7d38b30d2a66dfdbe78a1c86e4428e5f2207f7d
DO-NOT-SUBMIT: thermal: mediatek: mt8183: fix bank number settings
Cherry-picked from CL:1510928 to Huaqin ToT
mt8183 does not have bank.
The micro of MT8183_NUM_ZONES should set to 1.
Fixes: a4ffe6b52d27 ("thermal: mediatek: add support for MT8183")
Change-Id: I6c4d6e37dd40ff9129d0c43eb697afa60c94309a
Signed-off-by: Michael Kao <michael.kao@mediatek.com>
TEST-ONLY: drm/bridge: add it6505 driver
This CL is only for Flapjack debug to fix re-plug in can't be recognized
issue.
Please DO-NOT-SUBMIT.
support it6505
BUG=b:109911488
TEST= no
Change-Id: I3014cd5db5a0efe1edbd4d5c158d1b010015550c
DO-NOT-SUBMIT: Add Auo nt51021d and Inx ota7290d MIPI-DSI LCD panel
BUG=None
TEST=build and boot to shell
Change-Id: I1e8cc7f39d62fc29bd0561968cd453b2c20abc99
DO-NOT-SUBMIT: Change 8inch 1st panel boe-tv080wum-ng0 to normal scan
BUG=None
TEST=build and boot to shell
Change-Id: I189e19cb4ea128b3b0eb271ab760bf87f5bd3474
DO-NOT-SUBMIT: Change 10inch 1st panel boe-tv101wum-ng0 to normal scan
BUG=None
TEST=build and boot to shell
Change-Id: I6761fb2d49f53888206f1ab56007ff4638da93d9
CHROMIUM: arm64: dts: mt8183: Modify flapjack panel config
SKU_ID w/o LCM_ID 0x1:
8inch boe,tv080wum_ng0: mt8183-flapjack-rev4-sku1-hwconfig2
8inch auo,nt51021d8p: mt8183-flapjack-rev4-sku1-hwconfig4
SKU_ID w/o LCM_ID 0x3:
10inch boe,tv101wum_ng0: mt8183-flapjack-rev4-sku3-hwconfig1
10inch inx,ota7290d10p: mt8183-flapjack-rev4-sku3-hwconfig3
BUG=None
TEST=build and boot to shell
Change-Id: I43120b7feb54cd6b11463174b5fa2e54e87f660a
CHROMIUM: drm/panel: Add helper for reading DT rotation
This adds a helper function for reading the rotation (panel
orientation) from the device tree.
BUG=b:121173026
TEST=emerge-flapjack chromeos-kernel-4_14
Change-Id: I5a195c3aa23346aff4629967b891b89357056544
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
CHROMIUM: drm/panel: Add attach/detach callbacks
This adds the attach/detach callbacks. These are for setting up
internal state for the connector/panel pair that can't be done at
probe (since the connector doesn't exist) and which don't need to be
repeatedly done for every get/modes, prepare, or enable callback.
Values such as the panel orientation, and display size can be filled
in for the connector.
BUG=b:121173026
TEST=emerge-flapjack chromeos-kernel-4_19
Change-Id: I9d1f56ce585a561e82068cc373a8f636643c1e33
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
CHROMIUM: drm/panel: add boe himax8279d orientation
This adds reading the panel orientation from the device tree to the
boe himax8279d panel driver. This is done by adding the drm_panel
attach callback. The width_mm, heigh_mm, and bpc values are also
updated for the connector display info in this function since it makes
more sense there than in get_modes (which is called multiple times).
BUG=b:121173026
TEST=boot flapjack
Change-Id: I2b75f22c101aedc986d6d086657965e3f3e4615b
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
CHROMIUM: drm/mtk: add panel orientation property
This inits the panel orientation property for the mediatek dsi driver
if the panel orientation (connector.display_info.panel_orientation) is
not DRM_MODE_PANEL_ORIENTATION_UNKNOWN.
BUG=b:121173026
TEST=boot Flapjack
Change-Id: I3955e2ff0d633586cc77b34a649b385cf9c3aa19
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
HACK: drm/mtk: set plane rotation based on panel orientation
This sets a 180 degree rotation if there's an upside down panel. This
is only a temporary solution until userspace handles this properly by
specifying the rotation itself when the panel is upside down.
BUG=b:121173026
TEST=boot flapjack
Change-Id: I8f2d3c154610ee1837d1f2af6e6c22f85e790fc2
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
DO NOT COMMIT: dts: mediatek: add rotation property for flapjack
This adds the default rotation property for flapjack panels.
BUG=b:121173026
TEST=boot flapjack and check that the display isn't flipped
Change-Id: I7d29173f4e159dc6fac1bd2263483325e09980bc
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
WIP: CHROMIUM: arm64: dts: mt8183: add flapjack board rev5 compatible
Currently, LCM_ID are pulled up to 1800 mV. This causes inaccurate
reading by ADC.
We change the pull-up to 3300 mV. This patch adjusts the thresholds
accordingly.
we add new board version for this change
Change-Id: I1dfb38f58f1affd99a0f9fbb5cca9aa5c1f029f9
DO-NOT-SUBMIT: WIFI FTM patch
BUG=b:124327202
BRANCH=none
TEST=build pass and support the FTM mode
Change-Id: I43280a12cebe088a91e7ef96c2ba2d688efe614b
TEST-ONLY: set dpi pins as gpio and output low when dpi disabled
Pull dpi pins low when dpi has nothing to display. Or theree will be
Some dpi pins (Hsync Vsync DE ... ) keeping high voltage. And will
cause leadage.
Please DO-NOT-SUBMIT.
BUG=b:132674731
TEST=build and boot to shell
Change-Id: I6b6cfab647cb05357d717590140346a5a746ab9c
DO-NOT-SUBMIT: Flapjack Huaqin ToT
Collect Huaqin patches on chromeos-4.19
Rely On MTK's Tot Tree: CL:1317245
BUG=b:124595117
TEST=Boot to shell
Change-Id: Iaec249f694c9a1aaff3236bdfd098194e8d64a4a
---
.../bindings/iio/proximity/sx9311.txt | 19 +
README | 3 +-
arch/arm64/boot/dts/mediatek/Makefile | 4 +
arch/arm64/boot/dts/mediatek/mt6358.dtsi | 4 +-
.../mt8183-flapjack-rev4-sku1-hwconfig2.dts | 278 ++
.../mt8183-flapjack-rev4-sku1-hwconfig4.dts | 267 ++
.../mt8183-flapjack-rev4-sku3-hwconfig1.dts | 280 ++
.../mt8183-flapjack-rev4-sku3-hwconfig3.dts | 268 ++
.../boot/dts/mediatek/mt8183-flapjack.dtsi | 140 +
.../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 111 +
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 11 +
.../arm64/chromiumos-arm64.flavour.config | 1 +
.../arm64/chromiumos-mediatek.flavour.config | 15 +
drivers/gpu/drm/bridge/Makefile | 1 +
drivers/gpu/drm/bridge/ite-it6505.c | 2948 +++++++++++++++++
drivers/gpu/drm/drm_panel.c | 38 +-
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 14 +
drivers/gpu/drm/mediatek/mtk_dpi.c | 13 +-
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 28 +
drivers/gpu/drm/mediatek/mtk_dsi.c | 18 +
drivers/gpu/drm/panel/panel-boe-himax8279d.c | 954 +++++-
drivers/iio/proximity/Kconfig | 13 +
drivers/iio/proximity/Makefile | 1 +
drivers/iio/proximity/sx9311.c | 1144 +++++++
drivers/net/wireless/ath/ath10k/core.c | 2 +-
drivers/net/wireless/ath/ath10k/hif.h | 6 +-
drivers/net/wireless/ath/ath10k/sdio.c | 5 +-
drivers/thermal/mtk_thermal.c | 2 -
include/drm/drm_panel.h | 11 +
sound/soc/codecs/max98357a.c | 96 +-
.../mediatek/mt8183/mt8183-da7219-max98357.c | 2 +-
31 files changed, 6656 insertions(+), 41 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/proximity/sx9311.txt
create mode 100755 arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig2.dts
create mode 100755 arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig4.dts
create mode 100755 arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig1.dts
create mode 100755 arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig3.dts
create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-flapjack.dtsi
create mode 100755 drivers/gpu/drm/bridge/ite-it6505.c
create mode 100644 drivers/iio/proximity/sx9311.c
mode change 100644 => 100755 sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
diff --git a/Documentation/devicetree/bindings/iio/proximity/sx9311.txt b/Documentation/devicetree/bindings/iio/proximity/sx9311.txt
new file mode 100644
index 000000000000..65a1114e4147
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/proximity/sx9311.txt
@@ -0,0 +1,19 @@
+Semtech's SX9311 capacitive proximity device driver
+
+Required properties:
+ - compatible: must be "semtech,sx9311"
+ - reg: i2c address where to find the device
+ - interrupts : the sole interrupt generated by the device
+
+ Refer to interrupt-controller/interrupts.txt for generic
+ interrupt client node bindings.
+
+Example:
+
+sx9311@28 {
+ compatible = "semtech,sx9311";
+ reg = <0x28>;
+ interrupt-parent = <&pio>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW 5 0>;
+ int-gpio = <&pio 5 0>;
+ };
diff --git a/README b/README
index 768caa3970ef..5f0f9bcd9863 100644
--- a/README
+++ b/README
@@ -1,6 +1,5 @@
+HUAQIN FLAPJACK TOT
MTK TOT
-Linux kernel
-============
There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index d09409979c84..95c7896b6d19 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -11,3 +11,7 @@ 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
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-flapjack-rev4-sku1-hwconfig2.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-flapjack-rev4-sku1-hwconfig4.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-flapjack-rev4-sku3-hwconfig1.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-flapjack-rev4-sku3-hwconfig3.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
index a7e655c42a54..f31345ef16b3 100644
--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -349,8 +349,8 @@
mt6358_vsim2_reg: ldo_vsim2 {
regulator-name = "vsim2";
- regulator-min-microvolt = <1700000>;
- regulator-max-microvolt = <3100000>;
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
regulator-enable-ramp-delay = <540>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig2.dts b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig2.dts
new file mode 100755
index 000000000000..baec567d4975
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig2.dts
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/dts-v1/;
+#include "mt8183-flapjack.dtsi"
+
+/ {
+ model = "MediaTek Flapjack Rev 4 board Sku 1 BOE TV080WUM NG0";
+
+ /* SKU_ID: 0x20001 BOE_TV080WUM_NG0 for REV >=3 */
+ compatible = "google,flapjack-rev3-sku131073",
+ "google,flapjack-rev4-sku131073",
+ "google,flapjack-rev5-sku131073",
+ "google,flapjack-sku131073",
+
+ /* SKU_ID: 0x1 for Rev 2 */
+ "google,flapjack-rev2-sku1",
+
+ /* SKU_ID: 0x50001 Panel Unknown */
+ "google,flapjack-rev2-sku327681",
+ "google,flapjack-rev3-sku327681",
+ "google,flapjack-rev4-sku327681",
+ "google,flapjack-rev5-sku327681",
+ "google,flapjack-sku327681",
+
+ "google,flapjack-rev2",
+ "google,flapjack-rev3",
+ "google,flapjack-rev4",
+ "google,flapjack",
+ "google,kukui", "mediatek,mt8183";
+};
+
+&dsi0 {
+ /delete-node/ panel@0;
+ panel: panel@0 {
+ compatible = "boe,tv080wum_ng0";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ pp33-gpios = <&pio 35 0>;
+ pp18-gpios = <&pio 36 0>;
+ pinctrl-names = "default", "state_3300mv", "state_1800mv";
+ pinctrl-0 = <&panel_pins_default>;
+ pinctrl-1 = <&panel_pins_3300mv>;
+ pinctrl-2 = <&panel_pins_1800mv>;
+ backlight = <&backlight_lcd0>;
+ rotation = <180>;
+ status = "okay";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+
+&it6505dptx{
+ ovdd-supply = <&mt6358_vsim2_reg>;
+};
+
+&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",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "";
+};
+
+&scp_pins {
+ /* EINT pins are used for other purpose on rev2. */
+ /delete-node/ pins_eint;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig4.dts b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig4.dts
new file mode 100755
index 000000000000..f341993d584a
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku1-hwconfig4.dts
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/dts-v1/;
+#include "mt8183-flapjack.dtsi"
+
+/ {
+ model = "MediaTek Flapjack Rev 4 board Sku 1 AUO NT51021D8P";
+
+ /* SKU_ID: 0x40001 AUO_NT51021D8P for REV >=3 */
+ compatible = "google,flapjack-rev3-sku262145",
+ "google,flapjack-rev4-sku262145",
+ "google,flapjack-rev5-sku262145",
+ "google,flapjack-sku262145",
+
+ "google,flapjack-rev3",
+ "google,flapjack-rev4",
+ "google,flapjack",
+ "google,kukui", "mediatek,mt8183";
+};
+
+&dsi0 {
+ /delete-node/ panel@0;
+ panel: panel@0 {
+ compatible = "auo,nt51021d8p";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ pp33-gpios = <&pio 35 0>;
+ pp18-gpios = <&pio 36 0>;
+ pinctrl-names = "default", "state_3300mv", "state_1800mv";
+ pinctrl-0 = <&panel_pins_default>;
+ pinctrl-1 = <&panel_pins_3300mv>;
+ pinctrl-2 = <&panel_pins_1800mv>;
+ backlight = <&backlight_lcd0>;
+ rotation = <180>;
+ status = "okay";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+
+&it6505dptx{
+ ovdd-supply = <&mt6358_vsim2_reg>;
+};
+
+&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",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "";
+};
+
+&scp_pins {
+ /* EINT pins are used for other purpose on rev2. */
+ /delete-node/ pins_eint;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig1.dts b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig1.dts
new file mode 100755
index 000000000000..7d4e3c4e3b60
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig1.dts
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Device Tree Source for the Google flapjack board
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/dts-v1/;
+#include "mt8183-flapjack.dtsi"
+
+/ {
+ model = "MediaTek Flapjack Rev 4 board Sku 3 BOE TV101WUM NG0";
+
+ /* SKU_ID: 0x10003 BOE_TV101WUM_NG0 for REV >=3 */
+ compatible = "google,flapjack-rev3-sku65539",
+ "google,flapjack-rev4-sku65539",
+ "google,flapjack-rev5-sku65539",
+ "google,flapjack-sku65539",
+
+ /* SKU_ID: 0x3 for Rev 2 */
+ "google,flapjack-rev2-sku3",
+
+ /* SKU_ID: 0x50003 Panel Unknown */
+ "google,flapjack-rev2-sku327683",
+ "google,flapjack-rev3-sku327683",
+ "google,flapjack-rev4-sku327683",
+ "google,flapjack-rev5-sku327683",
+ "google,flapjack-sku327683",
+
+ "google,flapjack-rev2",
+ "google,flapjack-rev3",
+ "google,flapjack-rev4",
+ "google,flapjack",
+ "google,kukui", "mediatek,mt8183";
+};
+
+&dsi0 {
+ /delete-node/ panel@0;
+ panel: panel@0 {
+ compatible = "boe,tv101wum_ng0";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ pp33-gpios = <&pio 35 0>;
+ pp18-gpios = <&pio 36 0>;
+ pinctrl-names = "default", "state_3300mv", "state_1800mv";
+ pinctrl-0 = <&panel_pins_default>;
+ pinctrl-1 = <&panel_pins_3300mv>;
+ pinctrl-2 = <&panel_pins_1800mv>;
+ backlight = <&backlight_lcd0>;
+ rotation = <180>;
+ status = "okay";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+
+&it6505dptx{
+ ovdd-supply = <&mt6358_vsim2_reg>;
+};
+
+&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",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "";
+};
+
+&scp_pins {
+ /* EINT pins are used for other purpose on rev2. */
+ /delete-node/ pins_eint;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig3.dts b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig3.dts
new file mode 100755
index 000000000000..2a77a3f521b4
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-flapjack-rev4-sku3-hwconfig3.dts
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Device Tree Source for the Google flapjack board
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/dts-v1/;
+#include "mt8183-flapjack.dtsi"
+
+/ {
+ model = "MediaTek Flapjack Rev 3 board Sku 3 INX OTA7290D10P";
+ /* SKU_ID: 0x30003 INX OTA7290D10 for REV >=3 */
+ compatible = "google,flapjack-rev3-sku196611",
+ "google,flapjack-rev4-sku196611",
+ "google,flapjack-rev5-sku196611",
+ "google,flapjack-sku196611",
+
+
+ "google,flapjack-rev3",
+ "google,flapjack-rev4",
+ "google,flapjack",
+ "google,kukui", "mediatek,mt8183";
+};
+
+&dsi0 {
+ /delete-node/ panel@0;
+ panel: panel@0 {
+ compatible = "inx,ota7290d10p";
+ reg = <0>;
+ enable-gpios = <&pio 45 0>;
+ pp33-gpios = <&pio 35 0>;
+ pp18-gpios = <&pio 36 0>;
+ pinctrl-names = "default", "state_3300mv", "state_1800mv";
+ pinctrl-0 = <&panel_pins_default>;
+ pinctrl-1 = <&panel_pins_3300mv>;
+ pinctrl-2 = <&panel_pins_1800mv>;
+ backlight = <&backlight_lcd0>;
+ rotation = <180>;
+ status = "okay";
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
+&it6505dptx{
+ ovdd-supply = <&mt6358_vsim2_reg>;
+};
+
+&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",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "";
+};
+
+&scp_pins {
+ /* EINT pins are used for other purpose on rev2. */
+ /delete-node/ pins_eint;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-flapjack.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-flapjack.dtsi
new file mode 100644
index 000000000000..7bcc6d8e5b62
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8183-flapjack.dtsi
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Device Tree Source for the Google flapjack board
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "mt8183-kukui.dtsi"
+
+/ {
+ /delete-node/ mt8183-mt6358-ts3a227e-max98357a;
+
+ sound: mt8183-da7219-max98357a {
+ compatible = "mediatek,mt8183_da7219_max98357";
+ mediatek,platform = <&afe>;
+ mediatek,headset-codec = <&da7219>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&aud_pins>;
+ status = "okay";
+ };
+};
+
+&i2c0 {
+ /delete-node/ digitizer@9;
+ /delete-node/ touchscreen@10;
+
+ touchscreen@0a {
+ compatible = "hid-over-i2c";
+ reg = <0x0a>;
+ interrupt-parent = <&pio>;
+ interrupts = <155 IRQ_TYPE_LEVEL_LOW 155>;
+ int-gpio = <&pio 155 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touch_default>;
+ hid-descr-addr = <0x1>;
+ wakeup-source;
+ };
+};
+
+&i2c1 {
+ sx9311@28 {
+ compatible = "semtech,sx9311";
+ reg = <0x28>;
+ interrupt-parent = <&pio>;
+ interrupts = <5 IRQ_TYPE_LEVEL_LOW 5>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sx9311_pins>;
+ };
+};
+
+&i2c5 {
+ /delete-node/ ts3a227e@3b;
+ da7219: da7219@1a {
+ pinctrl-names = "default";
+ pinctrl-0 = <&da7219_pins>;
+ compatible = "dlg,da7219";
+ reg = <0x1a>;
+ interrupt-parent = <&pio>;
+ interrupts = <165 IRQ_TYPE_LEVEL_LOW 165>;
+
+ dlg,micbias-lvl = <2600>;
+ dlg,mic-amp-in-sel = "diff";
+
+ da7219_aad {
+ dlg,adc-1bit-rpt = <1>;
+ dlg,btn-avg = <4>;
+ dlg,btn-cfg = <50>;
+ dlg,mic-det-thr = <500>;
+ dlg,jack-ins-deb = <20>;
+ dlg,jack-det-rate = "32ms_64ms";
+ dlg,jack-rem-deb = <1>;
+
+ dlg,a-d-btn-thr = <0xa>;
+ dlg,d-b-btn-thr = <0x16>;
+ dlg,b-c-btn-thr = <0x21>;
+ dlg,c-mic-btn-thr = <0x3E>;
+ };
+ };
+};
+
+&pio {
+ /delete-node/ ts3a227e_pins;
+
+ da7219_pins: da7219_pins {
+ pins1 {
+ pinmux = <PINMUX_GPIO165__FUNC_GPIO165>;
+ input-enable;
+ bias-enable;
+ bias-pull-up;
+ };
+ };
+
+ panel_pins_1800mv: panel_pins_1800mv {
+ pins_cmd_dat {
+ pinmux = <PINMUX_GPIO36__FUNC_GPIO36>;
+ output-low;
+ bias-pull-up;
+ };
+ };
+
+ panel_pins_3300mv: panel_pins_3300mv {
+ pins_cmd_dat {
+ pinmux = <PINMUX_GPIO35__FUNC_GPIO35>;
+ output-low;
+ bias-pull-up;
+ };
+ };
+
+ /delete-node/ touchdefault;
+ touch_default: touchdefault {
+ pin_irq {
+ pinmux = <PINMUX_GPIO155__FUNC_GPIO155>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ touch_pin_reset: pin_reset {
+ pinmux = <PINMUX_GPIO156__FUNC_GPIO156>;
+ output-low;
+ };
+ };
+
+ sx9311_pins: sx9311_pins {
+ pins_eint {
+ pinmux = <PINMUX_GPIO5__FUNC_GPIO5>;
+ input-enable;
+ };
+ };
+};
+
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index e93b0587cfbc..aa67bb4cedcf 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -73,6 +73,15 @@
regulator-max-microvolt = <1800000>;
};
+ it6505_pp18_reg: regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "it6505_pp18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&pio 178 0>;
+ enable-active-high;
+ };
+
reserved_memory: reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -162,6 +171,18 @@
proc-supply = <&mt6358_vproc11_reg>;
};
+&dpi0 {
+ pinctrl-names = "default", "dpimode";
+ pinctrl-0 = <&dpi_pin_default>;
+ pinctrl-1 = <&dpi_pin_func>;
+ status = "okay";
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&it6505_in>;
+ };
+ };
+};
+
&dsi0 {
status = "okay";
#address-cells = <1>;
@@ -237,6 +258,29 @@
pinctrl-0 = <&i2c3_pins>;
status = "okay";
clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ it6505dptx: it6505dptx@5c {
+ compatible = "ite,it6505";
+ status = "okay";
+ interrupt-parent = <&pio>;
+ interrupts = <152 IRQ_TYPE_EDGE_RISING 152 0>;
+ reg = <0x5c>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&it6505_pins>;
+ ovdd-supply = <&mt6358_vsim1_reg>;
+ pwr18-supply = <&it6505_pp18_reg>;
+ reset-gpios = <&pio 179 1>;
+ hpd-gpios = <&pio 9 0>;
+ cros-ec = <&cros_ec>;
+ extcon = <&usbc_extcon0>;
+ port {
+ it6505_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
};
&i2c4 {
@@ -370,6 +414,51 @@
};
};
+ dpi_pin_default: dpi_pin_default{
+ pins_cmd_dat {
+ pinmux = <PINMUX_GPIO13__FUNC_GPIO13>,
+ <PINMUX_GPIO14__FUNC_GPIO14>,
+ <PINMUX_GPIO15__FUNC_GPIO15>,
+ <PINMUX_GPIO16__FUNC_GPIO16>,
+ <PINMUX_GPIO17__FUNC_GPIO17>,
+ <PINMUX_GPIO18__FUNC_GPIO18>,
+ <PINMUX_GPIO19__FUNC_GPIO19>,
+ <PINMUX_GPIO20__FUNC_GPIO20>,
+ <PINMUX_GPIO21__FUNC_GPIO21>,
+ <PINMUX_GPIO22__FUNC_GPIO22>,
+ <PINMUX_GPIO23__FUNC_GPIO23>,
+ <PINMUX_GPIO24__FUNC_GPIO24>,
+ <PINMUX_GPIO25__FUNC_GPIO25>,
+ <PINMUX_GPIO26__FUNC_GPIO26>,
+ <PINMUX_GPIO27__FUNC_GPIO27>,
+ <PINMUX_GPIO28__FUNC_GPIO28>;
+ drive-strength = <MTK_DRIVE_6mA>;
+ output-low;
+ };
+ };
+
+ dpi_pin_func: dpi_pin_func {
+ pins_cmd_dat {
+ pinmux = <PINMUX_GPIO13__FUNC_DBPI_D0>,
+ <PINMUX_GPIO14__FUNC_DBPI_D1>,
+ <PINMUX_GPIO15__FUNC_DBPI_D2>,
+ <PINMUX_GPIO16__FUNC_DBPI_D3>,
+ <PINMUX_GPIO17__FUNC_DBPI_D4>,
+ <PINMUX_GPIO18__FUNC_DBPI_D5>,
+ <PINMUX_GPIO19__FUNC_DBPI_D6>,
+ <PINMUX_GPIO20__FUNC_DBPI_D7>,
+ <PINMUX_GPIO21__FUNC_DBPI_D8>,
+ <PINMUX_GPIO22__FUNC_DBPI_D9>,
+ <PINMUX_GPIO23__FUNC_DBPI_D10>,
+ <PINMUX_GPIO24__FUNC_DBPI_D11>,
+ <PINMUX_GPIO25__FUNC_DBPI_HSYNC>,
+ <PINMUX_GPIO26__FUNC_DBPI_VSYNC>,
+ <PINMUX_GPIO27__FUNC_DBPI_DE>,
+ <PINMUX_GPIO28__FUNC_DBPI_CK>;
+ drive-strength = <MTK_DRIVE_6mA>;
+ };
+ };
+
ec_ap_int_odl: ec_ap_int_odl {
pins1 {
pinmux = <PINMUX_GPIO151__FUNC_GPIO151>;
@@ -455,6 +544,22 @@
};
};
+ it6505_pins: it6505_pins{
+ pins_cmd_dat {
+ pinmux = <PINMUX_GPIO178__FUNC_GPIO178>,
+ <PINMUX_GPIO179__FUNC_GPIO179>;
+ output-low;
+ bias-pull-up;
+ };
+
+ pins_cmd_dat1 {
+ pinmux = <PINMUX_GPIO9__FUNC_GPIO9>,
+ <PINMUX_GPIO152__FUNC_GPIO152>;
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
mmc0_pins_default: mmc0default {
pins_cmd_dat {
pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>,
@@ -774,6 +879,12 @@
#address-cells = <1>;
#size-cells = <0>;
};
+
+ usbc_extcon0: extcon@0 {
+ compatible = "google,extcon-usbc-cros-ec";
+ google,usb-port-id = <0>;
+ #extcon-cells = <0>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index ff9ce0f93a3e..93b78344925d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1625,6 +1625,17 @@
phy-names = "dphy";
};
+ dpi0: dpi@14015000 {
+ compatible = "mediatek,mt8183-dpi";
+ reg = <0 0x14015000 0 0x1000>;
+ interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW 0>;
+ power-domains = <&scpsys MT8183_POWER_DOMAIN_DISP>;
+ clocks = <&mmsys CLK_MM_DPI_IF>,
+ <&mmsys CLK_MM_DPI_MM>,
+ <&apmixedsys CLK_APMIXED_TVDPLL>;
+ clock-names = "pixel", "engine", "pll";
+ };
+
mutex: mutex@14016000 {
compatible = "mediatek,mt8183-disp-mutex";
reg = <0 0x14016000 0 0x1000>;
diff --git a/chromeos/config/arm64/chromiumos-arm64.flavour.config b/chromeos/config/arm64/chromiumos-arm64.flavour.config
index ba263ecb9cd9..8b791d78b328 100644
--- a/chromeos/config/arm64/chromiumos-arm64.flavour.config
+++ b/chromeos/config/arm64/chromiumos-arm64.flavour.config
@@ -173,6 +173,7 @@ CONFIG_SND_SOC_MT8173_RT5650=y
CONFIG_SND_SOC_MT8173_RT5650_RT5514=y
CONFIG_SND_SOC_MT8173_RT5650_RT5676=y
CONFIG_SND_SOC_MT8183=y
+CONFIG_SND_SOC_MT8183_DA7219_MAX98357A=y
CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A=y
CONFIG_SND_SOC_RK3399_GRU_SOUND=y
CONFIG_SND_SOC_ROCKCHIP=y
diff --git a/chromeos/config/arm64/chromiumos-mediatek.flavour.config b/chromeos/config/arm64/chromiumos-mediatek.flavour.config
index 9a2ddb58a7d7..cac227d1cf69 100644
--- a/chromeos/config/arm64/chromiumos-mediatek.flavour.config
+++ b/chromeos/config/arm64/chromiumos-mediatek.flavour.config
@@ -31,6 +31,9 @@ CONFIG_DRM_ANALOGIX_ANX78XX=y
CONFIG_DRM_MEDIATEK=y
CONFIG_DRM_MEDIATEK_HDMI=y
CONFIG_DRM_PANEL_BOE_TV101WUM=y
+CONFIG_DRM_MIPI_DSI=y
+CONFIG_DRM_PANEL_BOE_HIMAX8279D=y
+# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
CONFIG_DRM_PANEL_INNOLUX_P079ZCA=y
# CONFIG_EFI is not set
CONFIG_ENERGY_MODEL=y
@@ -73,6 +76,7 @@ CONFIG_SND_SOC_MT8173_RT5650=y
CONFIG_SND_SOC_MT8173_RT5650_RT5514=y
CONFIG_SND_SOC_MT8173_RT5650_RT5676=y
CONFIG_SND_SOC_MT8183=y
+CONFIG_SND_SOC_MT8183_DA7219_MAX98357A=y
CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MT65XX=y
@@ -87,3 +91,14 @@ CONFIG_USB_MTU3=y
CONFIG_USB_MTU3_DEBUG=y
CONFIG_VIDEO_MEDIATEK_MDP=y
CONFIG_VIDEO_MEDIATEK_VCODEC=y
+CONFIG_VIDEO_MEDIATEK_VPU=y
+# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
+CONFIG_VIRTIO=y
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_VIRTIO_CONSOLE is not set
+# CONFIG_VIRTIO_INPUT is not set
+# CONFIG_VIRTIO_MMIO is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_VIRTIO_WL is not set
+CONFIG_SX9311=y
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 4934fcf5a6f8..a83507bf6300 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -16,4 +16,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
+obj-y += ite-it6505.o
obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
new file mode 100755
index 000000000000..35f0bede1ace
--- /dev/null
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -0,0 +1,2948 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/extcon.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/spi/spi.h>
+#include <linux/fs.h>
+#include <linux/bits.h>
+#include <linux/of_platform.h>
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <crypto/sha.h>
+#include <crypto/hash.h>
+
+#define AX 0
+#define BX 1
+#define ENAUD 1
+#define AUDSEL I2S
+#define AUDTYPE LPCM
+#define AUDFS AUD48K
+#define AUDCH 2
+/* 0: Standard I2S;1: 32bit I2S */
+#define I2SINPUTFMT 1
+/* 0: Left-justified;1: Right-justified */
+#define I2SJUSTIFIED 0
+/* 0: Data delay 1T correspond to WS;1: No data delay correspond to WS */
+#define I2SDATADELAY 0
+/* 0: is left channel;1: is right channel */
+#define I2SWSCHANNEL 0
+/* 0: MSB shift first;1: LSB shift first */
+#define I2SDATASEQ 0
+
+#define LANESWAP 0
+#define LANE 4
+#define _HBR 1
+#define ENHFRAME 1
+#define ENSSC 1
+
+#define FLAGTRAINDOWN 100
+#define TRAINFAILCNT 5
+#define AUX_WAIT_TIMEOUT_MS 15
+#define PCLK_DELAY 1
+#define PCLK_INV 0
+#define EDIDRETRYTIME 5
+#define SHOWVIDEOTIMING 2
+#define PWROFFRETRYTIME 5
+
+/* AX or BX */
+#define CHIP_VERSION BX
+#define ENHDCP 1
+
+/* if use this define will enable power on/off option */
+#define ENPWRONOFF
+
+/* if use this define will power on in probe */
+/* #define TEST_MODE */
+
+/* if use this define will enable AUX debug option */
+/* #define ENAUX_TRANSFER_DEBUG */
+
+/* if use this define will enable SHA debug */
+/* #define SHA_DEBUG */
+
+/* register char device for it6505 */
+#define IT6505_CLASS_NAME "it6505_class"
+#define IT6505_DEVICE_NAME "it6505_device"
+#define IT6505_MAX_DEV 128
+/* The device-driver class struct pointer */
+static int it6505_major_num;
+
+enum sys_status {
+ SYS_UNPLUG = 0,
+ SYS_HPD,
+ SYS_AUTOTRAIN,
+ SYS_WAIT,
+ SYS_TRAINFAIL,
+ SYS_ReHDCP,
+ SYS_PWRDN,
+ SYS_NOROP,
+ SYS_Unknown,
+};
+
+enum it6505_aud_sel {
+ I2S = 0,
+ SPDIF,
+};
+
+enum it6505_aud_fs {
+ AUD24K = 0x6,
+ AUD32K = 0x3,
+ AUD48K = 0x2,
+ AUD96K = 0xA,
+ AUD192K = 0xE,
+ AUD44P1K = 0x0,
+ AUD88P2K = 0x8,
+ AUD176P4K = 0xC,
+};
+
+enum it6505_aud_type {
+ LPCM = 0,
+ NLPCM,
+ DSS,
+ HBR,
+};
+
+enum aud_word_length {
+ AUD16BIT = 0,
+ AUD18BIT,
+ AUD20BIT,
+ AUD24BIT,
+};
+
+/* Audio Sample Word Length: AUD16BIT, AUD18BIT, AUD20BIT, AUD24BIT */
+#define AUDWORDLENGTH AUD24BIT
+
+enum SWITCH {
+ Off = 0,
+ On
+};
+
+struct it6505_platform_data {
+ struct regulator *pwr18;
+ struct regulator *ovdd;
+ struct gpio_desc *gpiod_hpd;
+ struct gpio_desc *gpiod_pd;
+ struct gpio_desc *gpiod_reset;
+
+ int hpd_irq;
+ int intp_irq;
+};
+
+struct it6505_dp_port {
+ struct it6505 *it6505_dp;
+ struct notifier_block event_nb;
+ struct extcon_dev *extcon;
+ struct work_struct extcon_wq;
+ u8 id;
+};
+
+struct it6505 {
+ struct cros_ec_device *cros_ec;
+ struct drm_dp_aux aux;
+ struct drm_bridge bridge;
+ struct i2c_client *client;
+ struct edid *edid;
+ struct drm_connector connector;
+ struct drm_dp_link link;
+ struct it6505_platform_data pdata;
+ struct mutex lock;
+ struct regmap *regmap;
+ struct cdev cdev;
+ struct device class_dev;
+ struct it6505_dp_port *port;
+
+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
+ enum sys_status status;
+ u8 dumpdpcd[30];
+ u8 dpcd_rev;
+ bool hbr;
+ u8 lane;
+ u8 en_ssc;
+ bool en_hframe;
+ bool laneswap;
+ u8 hpd_status;
+
+ enum it6505_aud_sel aud_sel;
+ enum it6505_aud_fs aud_fs;
+ enum it6505_aud_type aud_type;
+ u8 aud_ch;
+ u8 i2s_input_fmt;
+ u8 i2s_justified;
+ u8 i2s_data_delay;
+ u8 i2s_ws_channel;
+ u8 i2s_data_seq;
+ u8 vidstable_done;
+ enum aud_word_length audwordlength;
+ u8 cntfsm;
+ u8 enhdcp;
+ bool cp_ready;
+ unsigned int bstatus;
+ bool cp_done;
+ u8 downstreamrepeater;
+ u8 am0[8];
+ u8 binfo[2];
+ u8 ksvlist[5*12];
+ unsigned int sha[5];
+ unsigned int w[80];
+ u8 shainput[64];
+ u8 av[5][4];
+ u8 bv[5][4];
+ u8 passsha;
+ bool powered;
+ /* it6505 driver hold option */
+ unsigned int it6505_drv_hold;
+};
+
+static int it6505_poweron(struct it6505 *it6505);
+#ifdef ENPWRONOFF
+static int it6505_poweroff(struct it6505 *it6505);
+#endif
+
+static const struct regmap_range it6505_bridge_volatile_ranges[] = {
+ { .range_min = 0, .range_max = 0xFF },
+};
+
+static const struct regmap_access_table it6505_bridge_volatile_table = {
+ .yes_ranges = it6505_bridge_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(it6505_bridge_volatile_ranges),
+};
+
+static const struct regmap_config it6505_bridge_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_table = &it6505_bridge_volatile_table,
+ .cache_type = REGCACHE_NONE,
+};
+
+static int dptxrd(struct it6505 *it6505,
+ unsigned int reg_addr, unsigned int *value)
+{
+ int err;
+
+ err = regmap_read(it6505->regmap, reg_addr, value);
+ if (err < 0) {
+ DRM_ERROR("%s read fail err reg_addr[0x%x] err:%d\n",
+ __func__, reg_addr, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void it6505_dump(struct it6505 *it6505)
+{
+ unsigned int value, i;
+
+ DRM_DEBUG_DRIVER("\n----------%s start----------\n", __func__);
+ for (i = 0; i <= 0xff; i++) {
+ dptxrd(it6505, i, &value);
+ DRM_DEBUG_DRIVER("%s[0x%x] = 0x%x\n", __func__, i, value);
+ }
+ DRM_DEBUG_DRIVER("\n----------%s end----------\n\n", __func__);
+}
+
+static int dptxwr(struct it6505 *it6505,
+ unsigned int reg_addr, unsigned int reg_val)
+{
+ int err;
+
+ err = regmap_write(it6505->regmap, reg_addr, reg_val);
+
+ if (err < 0) {
+ DRM_ERROR(
+ "%s write fail err reg_addr[0x%x] = 0x%x err = %d\n",
+ __func__, reg_addr, reg_val, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int dptxset(struct it6505 *it6505, unsigned int reg,
+ unsigned int mask, unsigned int setvalue)
+{
+ int err;
+
+ err = regmap_update_bits(it6505->regmap, reg, mask, setvalue);
+ if (err < 0) {
+ DRM_ERROR("%s write fail err %d\n", __func__, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static inline struct it6505 *connector_to_it6505(struct drm_connector *c)
+{
+ return container_of(c, struct it6505, connector);
+}
+
+static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge)
+{
+ return container_of(bridge, struct it6505, bridge);
+}
+
+
+void it6505_initfsm(struct it6505 *it6505)
+{
+ it6505->aud_sel = AUDSEL;
+ it6505->aud_fs = AUDFS;
+ it6505->aud_ch = AUDCH;
+ it6505->aud_type = AUDTYPE;
+ it6505->i2s_input_fmt = I2SINPUTFMT;
+ it6505->i2s_justified = I2SJUSTIFIED;
+ it6505->i2s_data_delay = I2SDATADELAY;
+ it6505->i2s_ws_channel = I2SWSCHANNEL;
+ it6505->i2s_data_seq = I2SDATASEQ;
+ it6505->audwordlength = AUDWORDLENGTH;
+
+ it6505->status = SYS_Unknown;
+ it6505->enhdcp = ENHDCP;
+ it6505->hbr = _HBR;
+ it6505->lane = LANE;
+ it6505->en_ssc = ENSSC;
+ it6505->en_hframe = ENHFRAME;
+ it6505->laneswap = LANESWAP;
+ it6505->vidstable_done = 0;
+}
+
+#if (CHIP_VERSION == BX)
+void iTE6505_termination(struct it6505 *it6505, enum SWITCH s)
+{
+ DRM_DEBUG_DRIVER("%s switch!!\n", __func__);
+ if (s) {
+ dptxset(it6505, 0x5D, 0x80, 0x00);
+ dptxset(it6505, 0x5E, 0x02, 0x02);
+ DRM_DEBUG_DRIVER("%s ON!!\n", __func__);
+ } else {
+ dptxset(it6505, 0x5D, 0x80, 0x80);
+ dptxset(it6505, 0x5E, 0x02, 0x00);
+ dptxset(it6505, 0x5C, 0xF0, 0x00);
+ DRM_DEBUG_DRIVER("%s OFF!!\n", __func__);
+ }
+}
+#endif
+
+static bool dptx_getsinkhpd(struct it6505 *it6505)
+{
+ unsigned int value;
+ int ret;
+
+ ret = dptxrd(it6505, 0x0D, &value);
+
+ if (ret < 0)
+ return false;
+
+ return (value & 2) == 2;
+}
+
+void show_vid_info(struct it6505 *it6505)
+{
+ int HSyncPol, VSyncPol, InterLaced;
+ int HTotal, HDES, HDEW, HFPH, HSYNCW;
+ int VTotal, VDES, VDEW, VFPH, VSYNCW;
+ int rddata, rddata1, i;
+ int PCLK, sum;
+
+ usleep_range(10000, 15000);
+ dptxwr(it6505, 0x0F, 0x00);
+ dptxrd(it6505, 0xa0, &rddata);
+ HSyncPol = rddata & BIT(0);
+ VSyncPol = (rddata & BIT(2)) >> 2;
+ InterLaced = (rddata & BIT(4)) >> 4;
+
+ dptxrd(it6505, 0xa1, &rddata);
+ dptxrd(it6505, 0xa2, &rddata1);
+ HTotal = ((rddata1 & 0x1F) << 8) + rddata;
+
+ dptxrd(it6505, 0xa3, &rddata);
+ dptxrd(it6505, 0xa4, &rddata1);
+
+ HDES = ((rddata1 & 0x1F) << 8) + rddata;
+
+ dptxrd(it6505, 0xa5, &rddata);
+ dptxrd(it6505, 0xa6, &rddata1);
+
+ HDEW = ((rddata1 & 0x1F) << 8) + rddata;
+
+ dptxrd(it6505, 0xa7, &rddata);
+ dptxrd(it6505, 0xa8, &rddata1);
+
+ HFPH = ((rddata1 & 0x1F) << 8) + rddata;
+
+ dptxrd(it6505, 0xa9, &rddata);
+ dptxrd(it6505, 0xaa, &rddata1);
+
+ HSYNCW = ((rddata1 & 0x1F) << 8) + rddata;
+
+ dptxrd(it6505, 0xab, &rddata);
+ dptxrd(it6505, 0xac, &rddata1);
+ VTotal = ((rddata1 & 0x0F) << 8) + rddata;
+
+ dptxrd(it6505, 0xad, &rddata);
+ dptxrd(it6505, 0xae, &rddata1);
+ VDES = ((rddata1 & 0x0F) << 8) + rddata;
+
+ dptxrd(it6505, 0xaf, &rddata);
+ dptxrd(it6505, 0xb0, &rddata1);
+ VDEW = ((rddata1 & 0x0F) << 8) + rddata;
+
+ dptxrd(it6505, 0xb1, &rddata);
+ dptxrd(it6505, 0xb2, &rddata1);
+ VFPH = ((rddata1 & 0x0F) << 8) + rddata;
+
+ dptxrd(it6505, 0xb3, &rddata);
+ dptxrd(it6505, 0xb4, &rddata1);
+ VSYNCW = ((rddata1 & 0x0F) << 8) + rddata;
+
+ sum = 0;
+ for (i = 0; i < 100; i++) {
+ dptxset(it6505, 0x12, 0x80, 0x80);
+ usleep_range(10000, 15000);
+ dptxset(it6505, 0x12, 0x80, 0x00);
+
+ dptxrd(it6505, 0x13, &rddata);
+ dptxrd(it6505, 0x14, &rddata1);
+ rddata = ((rddata1 & 0x0F) << 8)+rddata;
+
+ sum += rddata;
+ }
+
+ sum /= 100;
+ PCLK = 13500 * 2048 / sum;
+
+ DRM_DEBUG_DRIVER("\n----------Video Input Timing----------\n");
+ DRM_DEBUG_DRIVER("PCLK = %d.%dMHz\n", PCLK / 1000, PCLK % 1000);
+ DRM_DEBUG_DRIVER("HTotal = %d\n", HTotal);
+ DRM_DEBUG_DRIVER("HActive = %d\n", HDEW);
+ DRM_DEBUG_DRIVER("HFrontPorch = %d\n", HFPH);
+ DRM_DEBUG_DRIVER("HSyncWidth = %d\n", HSYNCW);
+ DRM_DEBUG_DRIVER("HBackPorch = %d\n", HTotal - HDEW - HFPH - HSYNCW);
+ DRM_DEBUG_DRIVER("VTotal = %d\n", VTotal);
+ DRM_DEBUG_DRIVER("VActive = %d\n", VDEW);
+ DRM_DEBUG_DRIVER("VFrontPorch = %d\n", VFPH);
+ DRM_DEBUG_DRIVER("VSyncWidth = %d\n", VSYNCW);
+ DRM_DEBUG_DRIVER("VBackPorch = %d\n", VTotal - VDEW - VFPH - VSYNCW);
+}
+
+void dptx_sys_chg(struct it6505 *it6505, enum sys_status newstate)
+{
+ unsigned int i = 0;
+ unsigned int reg06, reg07, reg08, reg0d, reg0e;
+
+ dptxrd(it6505, 0x06, &reg06);
+ dptxrd(it6505, 0x07, &reg07);
+ dptxrd(it6505, 0x08, &reg08);
+ dptxrd(it6505, 0x0d, &reg0d);
+ dptxrd(it6505, 0x0e, &reg0e);
+
+ DRM_DEBUG_DRIVER("%s reg06 = 0x%x\n", __func__, reg06);
+ DRM_DEBUG_DRIVER("%s reg07 = 0x%x\n", __func__, reg07);
+ DRM_DEBUG_DRIVER("%s reg08 = 0x%x\n", __func__, reg08);
+ DRM_DEBUG_DRIVER("%s reg0d = 0x%x\n", __func__, reg0d);
+ DRM_DEBUG_DRIVER("%s reg0e = 0x%x\n", __func__, reg0e);
+
+ if (newstate != SYS_UNPLUG) {
+ if (!dptx_getsinkhpd(it6505))
+ newstate = SYS_UNPLUG;
+ }
+
+ it6505->status = newstate;
+
+ switch (it6505->status) {
+ case SYS_UNPLUG:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNPLUG!!\n");
+ kfree(it6505->edid);
+ it6505->edid = NULL;
+ DRM_DEBUG_DRIVER("Free it6505 EDID memory!!\n");
+#if (CHIP_VERSION == BX)
+ iTE6505_termination(it6505, Off);
+#endif
+ break;
+ case SYS_HPD:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_HPD!!\n");
+#if (CHIP_VERSION == BX)
+ iTE6505_termination(it6505, On);
+#endif
+ break;
+ case SYS_AUTOTRAIN:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_AUTOTRAIN!!\n");
+ break;
+ case SYS_WAIT:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_WAIT!!\n");
+ break;
+#if ENHDCP
+ case SYS_ReHDCP:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_ReHDCP!!\n");
+ break;
+#endif
+ case SYS_NOROP:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_NOROP!!\n");
+ for (i = 0; i < SHOWVIDEOTIMING; i++)
+ show_vid_info(it6505);
+#ifdef TEST_MODE
+ it6505->it6505_drv_hold = 1;
+ DRM_DEBUG_DRIVER("set it6505_drv_hold:%d",
+ it6505->it6505_drv_hold);
+#endif
+ break;
+ case SYS_PWRDN:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_PWRDN!!\n");
+ /* Reset and PwrDn AFE */
+ break;
+ default:
+ DRM_DEBUG_DRIVER("sys_state is changing to SYS_UNKNOWN!!\n");
+ break;
+ }
+}
+
+static bool it6505_aux_op_finished(struct it6505 *it6505)
+{
+ unsigned int value;
+ int err;
+
+ err = regmap_read(it6505->regmap, 0x2b, &value);
+ if (err < 0)
+ return false;
+
+ return (value & BIT(5)) == 0;
+}
+
+
+static int dptx_auxwait(struct it6505 *it6505)
+{
+ unsigned int status;
+ unsigned long timeout;
+ int err;
+
+ timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;
+
+ while (!it6505_aux_op_finished(it6505)) {
+ if (time_after(jiffies, timeout)) {
+ DRM_DEBUG_DRIVER("Timed out waiting AUX to finish\n");
+ return -ETIMEDOUT;
+ }
+ usleep_range(1000, 2000);
+ }
+
+ err = dptxrd(it6505, 0x9f, &status);
+ if (err < 0) {
+ DRM_ERROR("Failed to read from AUX channel: %d\n", err);
+ return err;
+ }
+
+ if (status & 0x03) {
+ DRM_ERROR("Failed to wait for AUX channel (status: 0x%x)\n",
+ status);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int dptx_aux_r_edid(struct it6505 *it6505,
+ unsigned int nosegw, unsigned int block, unsigned int offset)
+{
+ unsigned int value, status;
+ int ret;
+
+ /* enable pc aux access */
+ dptxwr(it6505, 0x23, (nosegw << 6) + 0x03);
+ /* edid fifo clr */
+ dptxwr(it6505, 0x23, (nosegw << 6) + 0x82);
+ /* start address[7:0] */
+ dptxwr(it6505, 0x24, (block % 2) * 128 + offset);
+ /* start address[15:8] */
+ dptxwr(it6505, 0x25, block / 256);
+ /* writenum[3:0]+startadr[19:16] */
+ dptxwr(it6505, 0x26, 0xf0);
+ /* aux edid read fire */
+ dptxwr(it6505, 0x2b, 0x0b);
+ dptx_auxwait(it6505);
+
+ ret = dptxrd(it6505, 0x07, &value);
+ if (ret) {
+ DRM_DEBUG_DRIVER("Failed to read reg07: %d\n", ret);
+ return ret;
+ }
+
+ if (value & BIT(0)) {
+ DRM_DEBUG_DRIVER("aux channel request fail interrupt\n");
+
+ ret = dptxrd(it6505, 0x9f, &status);
+ if (ret) {
+ DRM_DEBUG_DRIVER("AUX channel failed : %d !\n",
+ ret);
+ return ret;
+ }
+
+ switch ((status & 0xc0) >> 6) {
+ case 0:
+ DRM_DEBUG_DRIVER("no error !!!\n");
+ return 0;
+ case 1:
+ DRM_DEBUG_DRIVER("defer > 7 times status: 0x%x!!!\n",
+ status);
+ return -ETIMEDOUT;
+
+ case 2:
+ DRM_DEBUG_DRIVER("Nack response status: 0x%x!!!\n",
+ status);
+ return -ETIMEDOUT;
+
+ default:
+ DRM_DEBUG_DRIVER("timeout status: 0x%x!!!\n",
+ status);
+ return -ETIMEDOUT;
+ }
+
+ }
+ return 0;
+}
+
+unsigned int dptx_getedidblock(struct it6505 *it6505, u8 *pedidbuff,
+ unsigned int blockno)
+{
+ ushort i;
+ unsigned int offset, checksum, value;
+
+ if (pedidbuff == NULL)
+ return 0xff;
+
+ dptxset(it6505, 0x05, 0x08, 0x08);
+ dptxset(it6505, 0x05, 0x08, 0x00);
+
+ for (offset = 0; offset < 0x80; offset += 8) {
+ dptx_aux_r_edid(it6505, 1, blockno, offset);
+
+ for (i = 0; i < 8; i++) {
+ dptxrd(it6505, 0x2f, &value);
+ pedidbuff[offset + i] = value;
+ DRM_DEBUG_DRIVER("%s[%d][%d]: 0x%x !!\n",
+ __func__, blockno, i, value);
+ }
+ }
+ /* disable pc aux access */
+ dptxwr(it6505, 0x23, 1 << 6);
+ checksum = 0;
+ for (i = 0; i < 0x80; i++)
+ checksum += pedidbuff[i];
+
+ checksum &= 0xff;
+
+ return checksum;
+}
+
+static u8 it6505_get_extension_num(struct it6505 *it6505)
+{
+ unsigned int checksum = 0, retrytime = 0, reg0D;
+ u8 buff[EDID_LENGTH];
+
+ DRM_DEBUG_DRIVER("start %s!\n", __func__);
+
+ do {
+ dptxrd(it6505, 0x0D, &reg0D);
+ checksum = dptx_getedidblock(it6505, buff, 0);
+ retrytime++;
+ DRM_DEBUG_DRIVER("read EDID %d time", retrytime);
+ if (!(reg0D & BIT(1))) {
+ dptx_sys_chg(it6505, SYS_UNPLUG);
+ break;
+ }
+ } while (checksum != 0 && retrytime < EDIDRETRYTIME);
+
+ DRM_DEBUG_DRIVER("extension number:%d",buff[0x7e]);
+ DRM_DEBUG_DRIVER("end %s!\n", __func__);
+ return buff[0x7e];
+}
+
+static struct edid *it6505_get_edid(struct it6505 *it6505)
+{
+ unsigned int checksum = 0, retrytime = 0;
+ unsigned int i, block, reg0D, total_size;
+ u8 *pedidbuff = kmalloc(EDID_LENGTH, GFP_KERNEL);
+
+ DRM_DEBUG_DRIVER("start %s", __func__);
+ if (!pedidbuff) {
+ DRM_DEBUG_DRIVER("%s(null)!\n", __func__);
+ return NULL;
+ }
+
+ it6505_dump(it6505);
+ block = it6505_get_extension_num(it6505);
+
+ /* dp does not have the hdmi tx four block test requirement */
+ if (block > 2)
+ block = 2;
+
+ total_size = (block + 1) * EDID_LENGTH;
+ if (total_size > EDID_LENGTH)
+ pedidbuff = krealloc(pedidbuff, total_size, GFP_KERNEL);
+
+ for (i = 0; i <= block; i++) {
+ DRM_DEBUG_DRIVER("Read block 0x%x", i);
+ retrytime = 0;
+ do {
+ dptxrd(it6505, 0x0D, &reg0D);
+ checksum = dptx_getedidblock(it6505,
+ pedidbuff + i * EDID_LENGTH, i);
+ DRM_DEBUG_DRIVER("%s in block %d %s",
+ checksum ? "Fake" : "True", i,
+ checksum ? "and read again!" : "!");
+ retrytime++;
+ DRM_DEBUG_DRIVER("read EDID %d time", retrytime);
+ if (!(reg0D & BIT(1))) {
+ dptx_sys_chg(it6505, SYS_UNPLUG);
+ break;
+ }
+ } while (checksum != 0 && retrytime < EDIDRETRYTIME);
+ if (checksum || it6505->status == SYS_UNPLUG)
+ break;
+ }
+ DRM_DEBUG_DRIVER("end %s and edid correct!", __func__);
+ return (struct edid *)pedidbuff;
+}
+
+static int it6505_get_modes(struct drm_connector *connector)
+{
+ struct it6505 *ctx = connector_to_it6505(connector);
+ int err, num_modes = 0;
+ u8 *p;
+ unsigned int reg9F, reg0D;
+
+ DRM_DEBUG_DRIVER("start %s", __func__);
+ err = it6505_poweron(ctx);
+ if (err) {
+ DRM_DEBUG_DRIVER("power on fail!");
+ goto unlock;
+ }
+ DRM_DEBUG_DRIVER("power on success!");
+ if (ctx->edid) {
+ DRM_DEBUG_DRIVER("ctx->edid is exist\n");
+ return drm_add_edid_modes(connector, ctx->edid);
+ }
+ DRM_DEBUG_DRIVER("ctx->edid not exist\n");
+ DRM_DEBUG_DRIVER("call it6505_get_edid to get EDID!\n");
+ mutex_lock(&ctx->lock);
+ dptxrd(ctx, 0x0D, &reg0D);
+ if (reg0D & BIT(1))
+ dptx_sys_chg(ctx, SYS_HPD);
+ else
+ dptx_sys_chg(ctx, SYS_UNPLUG);
+
+ dptxrd(ctx, 0x9F, &reg9F);
+ DRM_DEBUG_DRIVER("Aux status reg9F:0x%02x\n", reg9F);
+ ctx->edid = it6505_get_edid(ctx);
+ DRM_DEBUG_DRIVER("After it6505_get_edid, show the EDID:\n");
+ err = 256;
+ p = (u8 *)ctx->edid;
+ while (err) {
+ DRM_DEBUG_DRIVER("err = %d\n", err);
+ DRM_DEBUG_DRIVER("0x%02x 0x%02x 0x%02x 0x%02x\n",
+ p[0], p[1], p[2], p[3]);
+ DRM_DEBUG_DRIVER("0x%02x 0x%02x 0x%02x 0x%02x\n",
+ p[4], p[5], p[6], p[7]);
+ DRM_DEBUG_DRIVER("0x%02x 0x%02x 0x%02x 0x%02x\n",
+ p[8], p[9], p[10], p[11]);
+ DRM_DEBUG_DRIVER("0x%02x 0x%02x 0x%02x 0x%02x\n",
+ p[12], p[13], p[14], p[15]);
+
+ err -= 16;
+ p += 16;
+ }
+ if (!ctx->edid) {
+ DRM_ERROR("Failed to read EDID\n");
+ goto unlock;
+ }
+
+ err = drm_connector_update_edid_property(connector, ctx->edid);
+ if (err) {
+ DRM_ERROR("Failed to update EDID property: %d\n", err);
+ goto unlock;
+ }
+
+ num_modes = drm_add_edid_modes(connector, ctx->edid);
+
+unlock:
+ mutex_unlock(&ctx->lock);
+
+ return num_modes;
+}
+
+static const struct drm_connector_helper_funcs it6505_connector_helper_funcs = {
+ .get_modes = it6505_get_modes,
+};
+
+static enum drm_connector_status it6505_detect(struct drm_connector *connector,
+ bool force)
+{
+ struct it6505 *ctx = connector_to_it6505(connector);
+
+ if (gpiod_get_value(ctx->pdata.gpiod_hpd))
+ return connector_status_disconnected;
+
+ return connector_status_connected;
+}
+
+static const struct drm_connector_funcs it6505_connector_funcs = {
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .detect = it6505_detect,
+ .destroy = drm_connector_cleanup,
+ .reset = drm_atomic_helper_connector_reset,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+/* reverved for future use */
+/*
+ *BYTE iTE6505_dptx_aux(char *RORW, char *addr,
+ * int offset, BYTE *array, BYTE size)
+ *{
+ * BYTE i = 0;
+ * if (!strcmp(RORW, "w") || !strcmp(RORW, "W")) {
+ * while (i < size) {
+ * if (!dptx_dpcdwr(offset++, array[i++])) {
+ * DRM_DEBUG_DRIVER(("DPCD write fail!!\n"));
+ * return 3;
+ * }
+ * else {
+ * DRM_DEBUG_DRIVER(("DPCD write success!!\n"));
+ * return 0;
+ * }
+ * }
+ * }
+ * else if (!strcmp(RORW, "r") || !strcmp(RORW, "R")) {
+ * if (!strcmp(addr, "EDID")) {
+ * BYTE blocknum = offset / 0x80;
+ * offset = offset%0x80;
+ * dptx_AUX_R_EDID(1, blocknum, offset);
+ * while (i < size) {
+ * array[i] = dptxrd(0x2F);
+ * i++;
+ * }
+ * return 0;
+ * }
+ * else if (!strcmp(addr, "DPCD")) {
+ * while (i < size) {
+ * array[i++] = dptx_dpcdrd(offset++);
+ * }
+ * return 0;
+ * }
+ * else {
+ * DRM_DEBUG_DRIVER(("%s second parameter error!!\n"));
+ * return 2;
+ * }
+ * }
+ * else {
+ * DRM_DEBUG_DRIVER(%s first parameter error!!\n",
+ __func__);
+ * return 1;
+ * }
+ *}
+ */
+
+
+static ssize_t it6505_aux_transfer(struct drm_dp_aux *aux,
+ struct drm_dp_aux_msg *msg)
+{
+ /* reserved code for future debug using */
+#ifdef ENAUX_TRANSFER_DEBUG
+
+ struct it6505 *ctx = container_of(aux, struct it6505, aux);
+ u8 ctrl1 = msg->request;
+ u8 ctrl2 = SP_AUX_EN;
+ u8 *buffer = msg->buffer;
+ int err;
+
+ /* The DP AUX transmit and receive buffer has 16 bytes. */
+ if (WARN_ON(msg->size > AUX_CH_BUFFER_SIZE))
+ return -E2BIG;
+
+ /* Zero-sized messages specify address-only transactions. */
+ if (msg->size < 1)
+ ctrl2 |= SP_ADDR_ONLY;
+ else /* For non-zero-sized set the length field. */
+ ctrl1 |= (msg->size - 1) << SP_AUX_LENGTH_SHIFT;
+
+ if ((msg->request & DP_AUX_I2C_READ) == 0) {
+ /* When WRITE | MOT write values to data buffer */
+ err = regmap_bulk_write(ctx->map[I2C_IDX_TX_P0],
+ SP_DP_BUF_DATA0_REG, buffer,
+ msg->size);
+ if (err)
+ return err;
+ }
+
+ /* Write address and request */
+ err = it6505_aux_address(ctx, msg->address);
+ if (err)
+ return err;
+
+ err = regmap_write(ctx->map[I2C_IDX_TX_P0], SP_DP_AUX_CH_CTRL1_REG,
+ ctrl1);
+ if (err)
+ return err;
+
+ /* Start transaction */
+ err = regmap_update_bits(ctx->map[I2C_IDX_TX_P0],
+ SP_DP_AUX_CH_CTRL2_REG, SP_ADDR_ONLY |
+ SP_AUX_EN, ctrl2);
+ if (err)
+ return err;
+
+ err = it6505_aux_wait(ctx);
+ if (err)
+ return err;
+
+ msg->reply = DP_AUX_I2C_REPLY_ACK;
+
+ if ((msg->size > 0) && (msg->request & DP_AUX_I2C_READ)) {
+ /* Read values from data buffer */
+ err = regmap_bulk_read(ctx->map[I2C_IDX_TX_P0],
+ SP_DP_BUF_DATA0_REG, buffer,
+ msg->size);
+ if (err)
+ return err;
+ }
+
+ err = it6505_clear_bits(ctx->map[I2C_IDX_TX_P0],
+ SP_DP_AUX_CH_CTRL2_REG, SP_ADDR_ONLY);
+ if (err)
+ return err;
+
+ return msg->size;
+
+#endif
+ return 0;
+}
+
+static int it6505_extcon_notifier(struct notifier_block *self,
+ unsigned long event, void *ptr)
+{
+ struct it6505_dp_port *port =
+ container_of(self, struct it6505_dp_port, event_nb);
+
+ schedule_work(&port->extcon_wq);
+ DRM_DEBUG_DRIVER("[%s]", __func__);
+ return NOTIFY_DONE;
+}
+
+static void it6505_extcon_work(struct work_struct *work)
+{
+ struct it6505_dp_port *port =
+ container_of(work, struct it6505_dp_port, extcon_wq);
+ struct it6505 *ctx = port->it6505_dp;
+ int state = extcon_get_state(port->extcon, EXTCON_DISP_DP);
+#ifdef ENPWRONOFF
+ unsigned int pwroffretry = 0;
+#endif
+
+ mutex_lock(&ctx->lock);
+ DRM_DEBUG_DRIVER("[%s] state:%d %s", __func__, state,
+ state ? "cable in": "cable out");
+ if (state > 0) {
+ DRM_DEBUG_DRIVER("[%s] state:%d",
+ __func__, state);
+ DRM_DEBUG_DRIVER("[%s] start to power on!", __func__);
+ it6505_poweron(ctx);
+ } else {
+ DRM_DEBUG_DRIVER("[%s] state:%d",
+ __func__, state);
+#ifdef ENPWRONOFF
+ DRM_DEBUG_DRIVER("[%s] start to power off!", __func__);
+ while (it6505_poweroff(ctx) &&
+ pwroffretry++ < PWROFFRETRYTIME) {
+ DRM_DEBUG_DRIVER("power off it6505 fail! %d times",
+ pwroffretry);
+ }
+ DRM_DEBUG_DRIVER("power off it6505 success!");
+#endif
+ }
+ mutex_unlock(&ctx->lock);
+}
+
+static int use_notifier_module(struct it6505 *ctx)
+{
+ struct it6505_dp_port *port = ctx->port;
+ int ret;
+
+ DRM_DEBUG_DRIVER("[%s]", __func__);
+ port->event_nb.notifier_call = it6505_extcon_notifier;
+ INIT_WORK(&port->extcon_wq, it6505_extcon_work);
+ ret = devm_extcon_register_notifier(&ctx->client->dev,
+ port->extcon, EXTCON_DISP_DP, &port->event_nb);
+ if (ret) {
+ DRM_DEBUG_DRIVER("failed to register notifier for DP");
+ return ret;
+ }
+ return 0;
+}
+
+static int it6505_bridge_attach(struct drm_bridge *bridge)
+{
+ struct it6505 *ctx = bridge_to_it6505(bridge);
+ struct cros_ec_device *cros_ec;
+ struct extcon_dev *extcon;
+ struct it6505_dp_port *port;
+ struct device *dev;
+ int err;
+
+ DRM_DEBUG_DRIVER(" This is %s~start!!\n", __func__);
+ dev = &ctx->client->dev;
+ if (!bridge->encoder) {
+ DRM_ERROR("Parent encoder object not found");
+ return -ENODEV;
+ }
+
+ /* Register aux channel */
+ ctx->aux.name = "DP-AUX";
+ ctx->aux.dev = &ctx->client->dev;
+ ctx->aux.transfer = it6505_aux_transfer;
+
+ err = drm_dp_aux_register(&ctx->aux);
+ if (err < 0) {
+ DRM_ERROR("Failed to register aux channel: %d\n", err);
+ return err;
+ }
+
+ err = drm_connector_init(bridge->dev, &ctx->connector,
+ &it6505_connector_funcs,
+ DRM_MODE_CONNECTOR_DisplayPort);
+ if (err) {
+ DRM_ERROR("Failed to initialize connector: %d\n", err);
+ return err;
+ }
+
+ drm_connector_helper_add(&ctx->connector,
+ &it6505_connector_helper_funcs);
+
+ err = drm_connector_register(&ctx->connector);
+ if (err) {
+ DRM_ERROR("Failed to register connector: %d\n", err);
+ return err;
+ }
+
+ ctx->connector.polled = DRM_CONNECTOR_POLL_HPD;
+
+ err = drm_connector_attach_encoder(&ctx->connector,
+ bridge->encoder);
+ if (err) {
+ DRM_ERROR("Failed to link up connector to encoder: %d\n", err);
+ return err;
+ }
+
+ /* get extcon device from DTS */
+ extcon = extcon_get_edev_by_phandle(dev, 0);
+ if (PTR_ERR(extcon) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ if (IS_ERR(extcon)){
+ DRM_DEBUG_DRIVER("%s can not get extcon device!", __func__);
+ return -EINVAL;
+ } else
+ DRM_DEBUG_DRIVER("%s get extcon device!", __func__);
+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
+ return -ENOMEM;
+ port->extcon = extcon;
+ port->it6505_dp = ctx;
+ port->id = 0;
+ ctx->port = port;
+
+ err = use_notifier_module(ctx);
+ if (err < 0) {
+ DRM_DEBUG_DRIVER("%s fail to use notifier module!", __func__);
+ return err;
+ }
+ DRM_DEBUG_DRIVER("ctx->cros_ec = 0x%p\n", cros_ec);
+ DRM_DEBUG_DRIVER(" This is %s~end!!\n", __func__);
+ return 0;
+}
+
+static enum drm_mode_status
+it6505_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
+{
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ /* Max 1200p at 5.4 Ghz, one lane */
+ if (mode->clock > 80000)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
+static int it6505_send_video_infoframe(struct it6505 *it6505,
+ struct hdmi_avi_infoframe *frame)
+{
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+ int err;
+
+ err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer));
+ if (err < 0) {
+ DRM_ERROR("Failed to pack AVI infoframe: %d\n", err);
+ return err;
+ }
+
+ err = dptxset(it6505, 0xe8, 1, 0);
+ if (err)
+ return err;
+
+ err = regmap_bulk_write(it6505->regmap, 0xe9, buffer, frame->length);
+ if (err)
+ return err;
+
+ err = dptxset(it6505, 0xe8, 1, 1);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static void it6505_bridge_mode_set(struct drm_bridge *bridge,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct it6505 *ctx = bridge_to_it6505(bridge);
+ struct hdmi_avi_infoframe frame;
+ int err;
+
+ mutex_lock(&ctx->lock);
+
+ DRM_DEBUG_DRIVER("%s\n", __func__);
+
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
+ adjusted_mode, false);
+ if (err) {
+ DRM_ERROR("Failed to setup AVI infoframe: %d\n", err);
+ goto unlock;
+ }
+
+ err = it6505_send_video_infoframe(ctx, &frame);
+ if (err)
+ DRM_ERROR("Failed to send AVI infoframe: %d\n", err);
+
+unlock:
+ mutex_unlock(&ctx->lock);
+}
+
+void dptx_init(struct it6505 *it6505)
+{
+ dptxwr(it6505, 0x05, 0x3B);
+ usleep_range(1000, 2000);
+ dptxwr(it6505, 0x05, 0x1F);
+ usleep_range(1000, 1500);
+
+ DRM_DEBUG_DRIVER("this is %s end !!\n", __func__);
+}
+
+void iTE6505_INT_mask(struct it6505 *it6505)
+{
+#if ENHDCP
+ dptxwr(it6505, 0x09, 0x1F);
+#else
+ dptxwr(it6505, 0x09, 0x07);
+#endif
+
+#if ENAUD
+ dptxwr(it6505, 0x0A, 0x07);
+#else
+ dptxwr(it6505, 0x0A, 0x03);
+#endif
+ dptxwr(it6505, 0x0B, 0x90);
+}
+
+void dptx_set_aud_fmt(struct it6505 *it6505,
+ enum it6505_aud_sel audsel, unsigned int audch)
+{
+ unsigned int audsrc;
+ /* I2S MODE */
+ dptxwr(it6505, 0xB9, (it6505->audwordlength << 5)
+ | (it6505->i2s_data_seq << 4) | (it6505->i2s_ws_channel << 3)
+ | (it6505->i2s_data_delay << 2) | (it6505->i2s_justified << 1)
+ | it6505->i2s_input_fmt);
+ if (audsel == SPDIF) {
+ dptxwr(it6505, 0xBA, 0x00);
+ /* 0x30 = 128*FS */
+ dptxset(it6505, 0x11, 0xF0, 0x30);
+ } else {
+ dptxwr(it6505, 0xBA, 0xe4);
+ }
+
+ dptxwr(it6505, 0xBB, 0x00);
+ dptxwr(it6505, 0xBC, 0x00);
+ audsrc = 1;
+
+ if (audch > 2)
+ audsrc |= 2;
+
+ if (audch > 4)
+ audsrc |= 4;
+
+ if (audch == 8)
+ audsrc |= 8;
+
+ audsrc |= audsel << 4;
+
+ dptxwr(it6505, 0xB8, audsrc);
+}
+
+void dptx_set_aud_chsts(struct it6505 *it6505,
+ enum it6505_aud_type audtype, enum it6505_aud_fs audfs)
+{
+ /* Channel Status */
+ dptxwr(it6505, 0xBF, audtype << 1);
+ dptxwr(it6505, 0xC0, 0x00);
+ dptxwr(it6505, 0xC1, 0x00);
+ dptxwr(it6505, 0xC2, audfs);
+ switch (it6505->audwordlength) {
+ case AUD16BIT:
+ dptxwr(it6505, 0xC3, ((~audfs) << 4) + 0x02);
+ break;
+
+ case AUD18BIT:
+ dptxwr(it6505, 0xC3, ((~audfs) << 4) + 0x04);
+ break;
+
+ case AUD20BIT:
+ dptxwr(it6505, 0xC3, ((~audfs) << 4) + 0x03);
+ break;
+
+ case AUD24BIT:
+ dptxwr(it6505, 0xC3, ((~audfs) << 4) + 0x0B);
+ break;
+ }
+}
+
+
+void dptx_set_audio_infoframe(struct it6505 *it6505, unsigned int audch)
+{
+ dptxwr(it6505, 0xf7, audch - 1);
+
+ switch (audch) {
+ case 2:
+ dptxwr(it6505, 0xF9, 0x00);
+ break;
+ case 3:
+ dptxwr(it6505, 0xF9, 0x01);
+ break;
+ case 4:
+ dptxwr(it6505, 0xF9, 0x03);
+ break;
+ case 5:
+ dptxwr(it6505, 0xF9, 0x07);
+ break;
+ case 6:
+ dptxwr(it6505, 0xF9, 0x0B);
+ break;
+ case 7:
+ dptxwr(it6505, 0xF9, 0x0F);
+ break;
+ case 8:
+ dptxwr(it6505, 0xF9, 0x1F);
+ break;
+ default:
+ DRM_DEBUG_DRIVER("Error:Audio Channel Number Error !!!\n");
+ }
+ /* Enable Audio InfoFrame */
+ dptxset(it6505, 0xE8, 0x22, 0x22);
+}
+
+
+void iTE6505_SetAudio(struct it6505 *it6505, enum it6505_aud_sel audsel,
+ enum it6505_aud_type audtype, enum it6505_aud_fs audfs,
+ unsigned int audch)
+{
+ /* Audio Clock Domain Reset */
+ dptxset(it6505, 0x05, 0x02, 0x02);
+ /* Audio mute */
+ dptxset(it6505, 0xD3, 0x20, 0x20);
+ /* Release Audio Clock Domain Reset */
+ dptxset(it6505, 0x05, 0x02, 0x00);
+
+ dptx_set_aud_chsts(it6505, audtype, audfs);
+ dptx_set_audio_infoframe(it6505, audch);
+ dptx_set_aud_fmt(it6505, audsel, audch);
+ /* Enable Enhanced Audio TimeStmp Mode */
+ dptxset(it6505, 0xD4, 0x04, 0x04);
+ /* Disable Full Audio Packet */
+ dptxset(it6505, 0xBB, 0x10, 0x00);
+
+ dptxwr(it6505, 0xDE, 0x00);
+ dptxwr(it6505, 0xDF, 0x80);
+ dptxwr(it6505, 0xE0, 0x00);
+ dptxset(it6505, 0xD3, 0x20, 0x00);
+
+ /* Clear Video M Error Interrupt */
+ dptxset(it6505, 0x08, 0x08, 0x08);
+ /* Clear Audio FIFO OverFlow Interrupt */
+ dptxset(it6505, 0x07, 0x04, 0x04);
+}
+
+/***************************************************************************
+ * DPCD Read and EDID
+ ***************************************************************************/
+
+static unsigned int dptx_dpcdrd(struct it6505 *it6505,
+ unsigned long offset)
+{
+ unsigned int startadr0, startadr1, startadr2;
+
+ startadr0 = (unsigned int)((offset >> 0) & 0xFF);
+ startadr1 = (unsigned int)((offset >> 8) & 0xFF);
+ startadr2 = (unsigned int)((offset >> 16) & 0x0F);
+ /* Enable PC Aux Access */
+ dptxwr(it6505, 0x23, (0 << 6) + 0x02);
+ /* Start Address[7:0] */
+ dptxwr(it6505, 0x24, startadr0);
+ /* Start Address[15:8] */
+ dptxwr(it6505, 0x25, startadr1);
+ /* WriteNum[3:0]+StartAdr[19:16] */
+ dptxwr(it6505, 0x26, startadr2);
+ /* Aux Read Fire */
+ dptxwr(it6505, 0x2B, 0x00);
+ dptx_auxwait(it6505);
+ /* Disable PC Aux Access */
+ dptxwr(it6505, 0x23, (0 << 6) + 0x00);
+
+ dptxrd(it6505, 0x2C, &startadr0);
+
+ return startadr0;
+}
+
+static int dptx_dpcdwr(struct it6505 *it6505,
+ unsigned long offset, unsigned long datain)
+{
+ unsigned int startadr0, startadr1, startadr2;
+
+ startadr0 = (unsigned int)(offset >> 0) & 0xFF;
+ startadr1 = (unsigned int)(offset >> 8) & 0xFF;
+ startadr2 = (unsigned int)(offset >> 16) & 0x0F;
+ /* Enable PC Aux Access */
+ dptxwr(it6505, 0x23, (1 << 6) + 0x02);
+ /* Start Address[7:0] */
+ dptxwr(it6505, 0x24, startadr0);
+ /* Start Address[15:8] */
+ dptxwr(it6505, 0x25, startadr1);
+ /* WriteNum[3:0]+StartAdr[19:16] */
+ dptxwr(it6505, 0x26, startadr2);
+ /* WriteData Byte 1 */
+ dptxwr(it6505, 0x27, datain);
+ /* Aux Write Fire */
+ dptxwr(it6505, 0x2B, 0x05);
+ dptx_auxwait(it6505);
+ /* Aux Read Fire */
+ dptxwr(it6505, 0x2B, 0x00);
+ dptx_auxwait(it6505);
+ /* Disable PC Aux Access */
+ dptxwr(it6505, 0x23, (1 << 6) + 0x00);
+
+ dptxrd(it6505, 0x2C, &startadr0);
+
+ if (startadr0 != datain)
+ return -EINVAL;
+
+ return 0;
+}
+
+int iTE6505_GetSinkSupportHDCP(struct it6505 *it6505)
+{
+ unsigned int rddata;
+
+ dptxrd(it6505, 0x0D, &rddata);
+ if (!(rddata & BIT(1))) {
+ DRM_DEBUG_DRIVER("sys is unplug!! ...\n");
+ dptx_sys_chg(it6505, SYS_UNPLUG);
+ it6505->cp_ready = -1;
+ } else {
+ if (dptx_dpcdrd(it6505, 0x68028) & BIT(0)) {
+ DRM_DEBUG_DRIVER("Sink support HDCP!!\n");
+ it6505->cp_ready = 1;
+ DRM_DEBUG_DRIVER("Config ENHDCP, output with HDCP!!\n");
+ } else {
+ DRM_DEBUG_DRIVER("Sink not support HDCP !!\n");
+ it6505->cp_ready = 0;
+ DRM_DEBUG_DRIVER("Config ENHDCP, output no HDCP!\n");
+ }
+ }
+ return it6505->cp_ready;
+}
+
+static void iTE6505_GetDPCD(struct it6505 *it6505)
+{
+ unsigned int offset = 0;
+
+ DRM_DEBUG_DRIVER("\n ========== [DPCD] ===========\n");
+ for (offset = 0; offset < 0x10; offset++) {
+ it6505->dumpdpcd[offset] = dptx_dpcdrd(it6505, offset);
+ DRM_DEBUG_DRIVER("DPCD[0x%02x]=0x%02x ",
+ offset, it6505->dumpdpcd[offset]);
+ if (offset == 0x07)
+ DRM_DEBUG_DRIVER("\n");
+ }
+ DRM_DEBUG_DRIVER("\n =============================\n");
+}
+
+static void iTE6505_ParseDPCD(struct it6505 *it6505)
+{
+ it6505->dpcd_rev = it6505->dumpdpcd[0];
+ DRM_DEBUG_DRIVER(" =========== Start Parse DPCD! !===========\n");
+ DRM_DEBUG_DRIVER("#########DPCD Rev.: %d.%d###########\n",
+ it6505->dpcd_rev >> 4, it6505->dpcd_rev & 0x0F);
+
+ switch (it6505->dumpdpcd[1]) {
+ case 0x06:
+ DRM_DEBUG_DRIVER("Maximum Link Rate: 1.62Gbps per lane\n");
+ if (it6505->hbr) {
+ DRM_DEBUG_DRIVER("Not support HBR Mode");
+ DRM_DEBUG_DRIVER("will train LBR\n");
+ it6505->hbr = false;
+ } else
+ DRM_DEBUG_DRIVER("Training LBR\n");
+ break;
+
+ case 0x0A:
+ DRM_DEBUG_DRIVER("Maximum Link Rate: 2.7Gbps per lane\n");
+ if (!it6505->hbr) {
+ DRM_DEBUG_DRIVER("Support HBR Mode");
+ DRM_DEBUG_DRIVER("will train LBR\n");
+ it6505->hbr = false;
+ } else
+ DRM_DEBUG_DRIVER("Training HBR\n");
+ break;
+
+ case 0x14:
+ DRM_DEBUG_DRIVER("Maximum Link Rate: 2.7Gbps per lane\n");
+ break;
+
+ default:
+ DRM_DEBUG_DRIVER("Unknown Maximum Link Rate!!\n");
+ break;
+ }
+
+ switch (it6505->dumpdpcd[2] & 0x1F) {
+ case 1:
+ DRM_DEBUG_DRIVER("Maximum Lane Count : 1 lane\n");
+ if (it6505->lane > 1) {
+ DRM_DEBUG_DRIVER("Not support %d lane training\n",
+ it6505->lane);
+ DRM_DEBUG_DRIVER("Training 1 lane\n");
+ it6505->lane = 1;
+ } else
+ DRM_DEBUG_DRIVER("Training %d lane!!\n", it6505->lane);
+ break;
+ case 2:
+ DRM_DEBUG_DRIVER("Maximum Lane Count : 2 lanes\n");
+ if (it6505->lane > 2) {
+ DRM_DEBUG_DRIVER("Not support %d lane training\n",
+ it6505->lane);
+ DRM_DEBUG_DRIVER("Training 2 lane\n");
+ it6505->lane = 2;
+ } else
+ DRM_DEBUG_DRIVER("Training %d lane!!\n", it6505->lane);
+ break;
+ case 4:
+ DRM_DEBUG_DRIVER("Maximum Lane Count : 4 lanes\n");
+ if (it6505->lane > 4) {
+ DRM_DEBUG_DRIVER("Not support %d lane training\n",
+ it6505->lane);
+ DRM_DEBUG_DRIVER("Training 4 lane\n");
+ it6505->lane = 4;
+ } else
+ DRM_DEBUG_DRIVER("Training %d lane!!\n", it6505->lane);
+ break;
+ default:
+ DRM_DEBUG_DRIVER("Maximum Lane Count : Error !!!\n");
+ }
+
+ if (it6505->dpcd_rev == 0x11 && it6505->dumpdpcd[2] & BIT(7)) {
+ DRM_DEBUG_DRIVER("Support Enhanced Framing Mode\n");
+ } else {
+ DRM_DEBUG_DRIVER("Can not support Enhanced Framing Mode\n");
+ if (it6505->en_hframe) {
+ DRM_DEBUG_DRIVER("Can not support Enhanced Framing!\n");
+ it6505->en_hframe = 0;
+ }
+ }
+
+ if (it6505->dumpdpcd[3] & BIT(0)) {
+ DRM_DEBUG_DRIVER("Maximum Down-Spread: 0.5, support SSC!\n");
+ } else {
+ DRM_DEBUG_DRIVER("Maximum Down-Spread: 0, No support SSC!\n");
+ if (it6505->en_ssc) {
+ DRM_DEBUG_DRIVER("Can not support SSC!!\n");
+ it6505->en_ssc = 0;
+ }
+ }
+
+ if (it6505->dpcd_rev == 0x11 && it6505->dumpdpcd[3] & BIT(6))
+ DRM_DEBUG_DRIVER("Support No AUX Training\n");
+ else
+ DRM_DEBUG_DRIVER("Can not support No AUX Training\n");
+
+ if (dptx_dpcdrd(it6505, 0x68028) & BIT(0)) {
+ DRM_DEBUG_DRIVER("Sink support HDCP!\n");
+ it6505->cp_ready = true;
+#if ENHDCP
+ DRM_DEBUG_DRIVER("Config ENHDCP output with HDCP!\n");
+#else
+ DRM_DEBUG_DRIVER("Not config ENHDCP output no HDCP!\n");
+#endif
+ } else {
+ DRM_DEBUG_DRIVER("Sink not support HDCP !\n");
+ it6505->cp_ready = false;
+#if ENHDCP
+ DRM_DEBUG_DRIVER("Config ENHDCP output no HDCP!\n");
+#else
+ DRM_DEBUG_DRIVER("Not config ENHDCP output no HDCP!\n");
+#endif
+ }
+
+ if (dptx_dpcdrd(it6505, 0x68028) & BIT(1)) {
+ DRM_DEBUG_DRIVER("Downstream is repeater!!\n");
+ it6505->downstreamrepeater = true;
+ } else {
+ DRM_DEBUG_DRIVER("Downstream is receiver!!\n");
+ it6505->downstreamrepeater = false;
+ }
+
+ DRM_DEBUG_DRIVER(" ======== Parse DPCD END! ========\n");
+}
+
+void iTE6505_EnableHDCP(struct it6505 *it6505)
+{
+ int i;
+ u8 c;
+ unsigned long BKSV[5], bksv;
+
+ DRM_DEBUG_DRIVER("%s start!!", __func__);
+ /* Disable CP_Desired */
+ dptxset(it6505, 0x38, 0x0B, 0x00);
+ dptxset(it6505, 0x05, 0x10, 0x10);
+
+ usleep_range(1000, 1500);
+ c = dptx_dpcdrd(it6505, 0x68028);
+ DRM_DEBUG_DRIVER("DPCD[0x68028]:0x%x!!\n", c);
+ if (!c)
+ return;
+
+ dptxset(it6505, 0x05, 0x10, 0x00);
+ /* Disable CP_Desired */
+ dptxset(it6505, 0x38, 0x01, 0x00);
+ /* Use R0' 100ms waiting */
+ dptxset(it6505, 0x38, 0x08, 0x00);
+ /* clear the repeater List Chk Done and fail bit */
+ dptxset(it6505, 0x39, 0x30, 0x00);
+
+ for (i = 0; i < 5; i++)
+ BKSV[i] = dptx_dpcdrd(it6505, 0x68000 + i);
+
+ bksv = BKSV[0] + (BKSV[1] << 8) + (BKSV[2] << 16)
+ + (BKSV[3] << 24) + (BKSV[4] << 32);
+ DRM_DEBUG_DRIVER("Sink BKSV = 0x%lx", bksv);
+
+ /* Select An Generator */
+ dptxset(it6505, 0x3A, 0x01, 0x01);
+ /* Enable An Generator */
+ dptxset(it6505, 0x3A, 0x02, 0x02);
+ /* delay1ms(10);*/
+ usleep_range(10000, 15000);
+ /* Stop An Generator */
+ dptxset(it6505, 0x3A, 0x02, 0x00);
+
+ dptxset(it6505, 0x38, 0x01, 0x01);
+ dptxset(it6505, 0x39, 0x01, 0x01);
+
+ DRM_DEBUG_DRIVER("%s end !!\n", __func__);
+}
+
+void iTE6505_lanespeed_setup(struct it6505 *it6505)
+{
+ if (!it6505->hbr) {
+ dptxset(it6505, 0x16, 0x01, 1);
+ dptxset(it6505, 0x5C, 0x02, 0x00);
+ } else {
+ dptxset(it6505, 0x16, 0x01, 0);
+ dptxset(it6505, 0x5C, 0x02, 0x02);
+ }
+}
+
+void iTE6505_lane_swap(struct it6505 *it6505)
+{
+ int err;
+ union extcon_property_value property;
+
+ if (it6505->hpd_status == 0) {
+ err = extcon_get_property(it6505->port->extcon,
+ EXTCON_DISP_DP,
+ EXTCON_PROP_USB_TYPEC_POLARITY, &property);
+ if (err) {
+ DRM_DEBUG_DRIVER("%s get property fail!",
+ __func__);
+ }
+ it6505->laneswap = property.intval;
+ DRM_DEBUG_DRIVER("property.intval = 0x%d\n", property.intval);
+ }
+
+ dptxset(it6505, 0x16, 0x08, (it6505->laneswap) ? 8 : 0);
+ dptxset(it6505, 0x16, 0x06, (it6505->lane - 1) << 1);
+ DRM_DEBUG_DRIVER("it6505->laneswap = 0x%x\n", it6505->laneswap);
+
+ if (it6505->laneswap) {
+ switch (it6505->lane) {
+ case 1:
+ dptxset(it6505, 0x5C, 0xF1, 0x81);
+ break;
+ case 2:
+ dptxset(it6505, 0x5C, 0xF1, 0xC1);
+ break;
+ default:
+ dptxset(it6505, 0x5C, 0xF1, 0xF1);
+ break;
+ }
+ } else {
+ switch (it6505->lane) {
+ case 1:
+ dptxset(it6505, 0x5C, 0xF1, 0x11);
+ break;
+ case 2:
+ dptxset(it6505, 0x5C, 0xF1, 0x31);
+ break;
+ default:
+ dptxset(it6505, 0x5C, 0xF1, 0xF1);
+ break;
+ }
+ }
+}
+
+void iTE6505_lane_config(struct it6505 *it6505)
+{
+ iTE6505_lanespeed_setup(it6505);
+ iTE6505_lane_swap(it6505);
+}
+
+void dptx_chgbank(struct it6505 *it6505, unsigned int bank_id)
+{
+ dptxset(it6505, 0x0F, 0x01, bank_id & BIT(0));
+}
+
+void iTE6505_set_ssc(struct it6505 *it6505)
+{
+ dptxset(it6505, 0x16, 0x10, it6505->en_ssc << 4);
+ if (it6505->en_ssc) {
+ dptx_chgbank(it6505, 1);
+ dptxwr(it6505, 0x88, 0x9e);
+ dptxwr(it6505, 0x89, 0x1c);
+ dptxwr(it6505, 0x8A, 0x42);
+ dptx_chgbank(it6505, 0);
+ dptxwr(it6505, 0x58, 0x07);
+ dptxwr(it6505, 0x59, 0x29);
+ dptxwr(it6505, 0x5A, 0x03);
+ DRM_DEBUG_DRIVER("Enable 27M 4463 PPM SSC\n");
+ /* Stamp Interrupt Step */
+ dptxset(it6505, 0xD4, 0x30, 0x10);
+ dptx_dpcdwr(it6505, 0x107, 0x10);
+ } else {
+ dptx_dpcdwr(it6505, 0x107, 0x00);
+ dptxset(it6505, 0xD4, 0x30, 0x00);
+ }
+}
+
+void PCLK_phase(struct it6505 *it6505)
+{
+ dptxset(it6505, 0x10, 0x03, PCLK_DELAY);
+ dptxset(it6505, 0x12, 0x10, PCLK_INV << 4);
+}
+
+void AFE_driving_setting(struct it6505 *it6505)
+{
+ dptxset(it6505, 0x0F, 0x01, 0x01);
+ dptxwr(it6505, 0x7E, 0x93);
+ dptxwr(it6505, 0x7F, 0x2A);
+ dptxwr(it6505, 0x81, 0x85);
+ dptxset(it6505, 0x0F, 0x01, 0x00);
+}
+
+void dptx_output(struct it6505 *it6505, unsigned int HBR, unsigned int lane,
+ unsigned int laneswap, unsigned int en_ssc,
+ unsigned int EnhFraming)
+{
+ dptxwr(it6505, 0x05, 0x13);
+ /* change bank 0 */
+ dptxset(it6505, 0x0F, 0x01, 0x00);
+ /* RegTxFFRst set */
+ dptxset(it6505, 0x61, 0x02, 0x02);
+ /* RegTxFFRst clear */
+ dptxset(it6505, 0x61, 0x02, 0x00);
+ dptxwr(it6505, 0x64, 0x10);
+ dptxwr(it6505, 0x65, 0x80);
+ dptxwr(it6505, 0x66, 0x10);
+ dptxwr(it6505, 0x67, 0x4F);
+ dptxwr(it6505, 0x68, 0x09);
+ dptxwr(it6505, 0x69, 0xBA);
+ dptxwr(it6505, 0x6A, 0x3B);
+ dptxwr(it6505, 0x6B, 0x4B);
+ dptxwr(it6505, 0x6C, 0x3E);
+ dptxwr(it6505, 0x6D, 0x4F);
+ dptxwr(it6505, 0x6E, 0x09);
+ dptxwr(it6505, 0x6F, 0x56);
+ dptxwr(it6505, 0x70, 0x0E);
+ dptxwr(it6505, 0x71, 0x00);
+ dptxwr(it6505, 0x72, 0x00);
+ dptxwr(it6505, 0x73, 0x4F);
+ dptxwr(it6505, 0x74, 0x09);
+ dptxwr(it6505, 0x75, 0x00);
+ dptxwr(it6505, 0x76, 0x00);
+ dptxwr(it6505, 0x77, 0xE7);
+ dptxwr(it6505, 0x78, 0x10);
+ dptxwr(it6505, 0xE8, 0x00);
+ dptxset(it6505, 0xCE, 0x70, 0x60);
+ dptxset(it6505, 0xD0, 0xC0, 0x80);
+ dptxwr(it6505, 0xCA, 0x4D);
+ dptxwr(it6505, 0xC9, 0xF5);
+ dptxwr(it6505, 0x5C, 0x02);
+
+ dptx_dpcdwr(it6505, 0x600, 0x01);
+ dptxset(it6505, 0x59, 0x01, 0x01);
+ dptxset(it6505, 0x5A, 0x05, 0x01);
+ dptxwr(it6505, 0x12, 0x01);
+ dptxwr(it6505, 0xCB, 0x17);
+ dptxwr(it6505, 0x11, 0x09);
+ dptxwr(it6505, 0x20, 0x28);
+ dptxset(it6505, 0x23, 0x30, 00);
+ dptxset(it6505, 0x3A, 0x04, 0x04);
+ dptxset(it6505, 0x15, 0x01, 0x01);
+ dptxwr(it6505, 0x0C, 0x08);
+
+ dptxset(it6505, 0x5F, 0x20, 0x00);
+ iTE6505_lane_config(it6505);
+
+ iTE6505_set_ssc(it6505);
+
+ if (EnhFraming)
+ dptxwr(it6505, 0xD3, 0x33);
+ else
+ dptxwr(it6505, 0xD3, 0x32);
+
+ dptxset(it6505, 0x15, 0x02, 0x02);
+ dptxset(it6505, 0x15, 0x02, 0x00);
+ dptxset(it6505, 0x05, 0x03, 0x02);
+ dptxset(it6505, 0x05, 0x03, 0x00);
+
+ /* reg60[2] = InDDR */
+ dptxwr(it6505, 0x60, 0x44);
+ /* M444B24 foramt */
+ dptxwr(it6505, 0x62, 1);
+ /* select RGB Bypass CSC */
+ dptxwr(it6505, 0x63, 0);
+
+ PCLK_phase(it6505);
+ dptxset(it6505, 0x61, 0x01, 0x01);
+ dptxwr(it6505, 0x06, 0xFF);
+ dptxwr(it6505, 0x07, 0xFF);
+ dptxwr(it6505, 0x08, 0xFF);
+
+ dptxset(it6505, 0xd3, 0x30, 0x00);
+ dptxset(it6505, 0xd4, 0x41, 0x41);
+ dptxset(it6505, 0xe8, 0x11, 0x11);
+
+ AFE_driving_setting(it6505);
+ dptxwr(it6505, 0x17, 0x04);
+ dptxwr(it6505, 0x17, 0x01);
+ DRM_DEBUG_DRIVER(" ======= end main flow! !========\n");
+}
+
+
+void dptx_sys_fsm(struct it6505 *it6505)
+{
+ unsigned int value, temp1, temp2, temp3;
+ unsigned int count, dpcd1[0x09], dpcd2[0x18];
+ unsigned int temp, i, dpcdstart = 0x100;
+ int ret, reg0D, reg9F;
+#if ENHDCP
+ unsigned int Ar0_low, Ar0_high, Br0_low, Br0_high;
+#endif
+
+ DRM_DEBUG_DRIVER("%s start state: %d\n", __func__,
+ it6505->status);
+
+ dptxrd(it6505, 0x0D, &reg0D);
+
+ if (it6505->status != SYS_UNPLUG && !(reg0D & BIT(1)))
+ dptx_sys_chg(it6505, SYS_UNPLUG);
+
+ switch (it6505->status) {
+ case SYS_PWRDN:
+ break;
+ case SYS_UNPLUG:
+ DRM_DEBUG_DRIVER("sys_state is in SYS_UNPLUG!!\n");
+ break;
+
+ case SYS_HPD:
+ DRM_DEBUG_DRIVER("Is in SYS_HPD!!\n");
+ dptxrd(it6505, 0x9f, &reg9F);
+ DRM_DEBUG_DRIVER("Aux channel status reg9F=0x%02x\n", reg9F);
+ /* GETDPCD */
+ iTE6505_GetDPCD(it6505);
+ iTE6505_ParseDPCD(it6505);
+
+ /*
+ * training fail TRAINFAILCNT times,
+ * then change to HPD to restart
+ */
+ it6505->cntfsm = TRAINFAILCNT;
+ DRM_DEBUG_DRIVER("will Train %s %d lanes\n",
+ it6505->hbr ? "HBR" : "LBR", it6505->lane);
+ dptx_sys_chg(it6505, SYS_AUTOTRAIN);
+ break;
+
+ case SYS_AUTOTRAIN:
+ DRM_DEBUG_DRIVER("%s in SYS_AUTOTRAIN!\n", __func__);
+ dptx_output(it6505,
+ it6505->hbr,
+ it6505->lane,
+ it6505->laneswap,
+ it6505->en_ssc,
+ it6505->en_hframe);
+
+ /*
+ * waiting for training down flag
+ * because we don't know
+ * how long this step will be completed
+ * so use step 1ms to wait
+ */
+ for (count = 0; count < FLAGTRAINDOWN; count++) {
+ msleep(1);
+ dptxrd(it6505, 0x0E, &temp3);
+ if (temp3 & BIT(4))
+ break;
+ }
+
+ dptx_sys_chg(it6505, SYS_WAIT);
+ break;
+