diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml index ecd5783f001b3e..b10311e72af168 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml @@ -12,6 +12,20 @@ description: allOf: - $ref: /schemas/i2c/i2c-controller.yaml# + - if: + properties: + compatible: + contains: + const: mediatek,mt6572-i2c + then: + properties: + reg: + minItems: 3 + maxItems: 3 + else: + properties: + reg: + maxItems: 2 maintainers: - Qii Wang @@ -20,6 +34,7 @@ properties: compatible: oneOf: - const: mediatek,mt2712-i2c + - const: mediatek,mt6572-i2c - const: mediatek,mt6577-i2c - const: mediatek,mt6589-i2c - const: mediatek,mt7622-i2c @@ -64,9 +79,11 @@ properties: - const: mediatek,mt8192-i2c reg: + minItems: 2 items: - description: Physical base address - - description: DMA base address + - description: DMA base address (TX channel on mt6572) + - description: DMA RX channel base address (mt6572 only) interrupts: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml index 5d4ab701f51a1e..852eb7336a5a2e 100644 --- a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/iio/adc/mediatek,mt6359-auxadc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: MediaTek MT6350 series PMIC AUXADC +title: MediaTek MT6350 series and similar PMIC AUXADC maintainers: - AngeloGioacchino Del Regno @@ -19,6 +19,7 @@ description: properties: compatible: enum: + - mediatek,mt6323-auxadc - mediatek,mt6357-auxadc - mediatek,mt6358-auxadc - mediatek,mt6359-auxadc diff --git a/MAINTAINERS b/MAINTAINERS index c3fe46d7c4bc43..7730249d3d9344 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16335,6 +16335,11 @@ S: Orphan F: Documentation/devicetree/bindings/mtd/mediatek,mtk-nfc.yaml F: drivers/mtd/nand/raw/mtk_* +MEDIATEK MT6323 PMIC AUXADC DRIVER +M: Roman Vivchar +S: Maintained +F: drivers/iio/adc/mt6323-auxadc.c + MEDIATEK PMIC LED DRIVER M: Sen Chu M: Sean Wang diff --git a/README b/README deleted file mode 100644 index e6549b2a7aac37..00000000000000 --- a/README +++ /dev/null @@ -1,168 +0,0 @@ -Linux kernel -============ - -The Linux kernel is the core of any Linux operating system. It manages hardware, -system resources, and provides the fundamental services for all other software. - -Quick Start ------------ - -* Report a bug: See Documentation/admin-guide/reporting-issues.rst -* Get the latest kernel: https://kernel.org -* Build the kernel: See Documentation/admin-guide/quickly-build-trimmed-linux.rst -* Join the community: https://lore.kernel.org/ - -Essential Documentation ------------------------ - -All users should be familiar with: - -* Building requirements: Documentation/process/changes.rst -* Code of Conduct: Documentation/process/code-of-conduct.rst -* License: See COPYING - -Documentation can be built with make htmldocs or viewed online at: -https://www.kernel.org/doc/html/latest/ - - -Who Are You? -============ - -Find your role below: - -* New Kernel Developer - Getting started with kernel development -* Academic Researcher - Studying kernel internals and architecture -* Security Expert - Hardening and vulnerability analysis -* Backport/Maintenance Engineer - Maintaining stable kernels -* System Administrator - Configuring and troubleshooting -* Maintainer - Leading subsystems and reviewing patches -* Hardware Vendor - Writing drivers for new hardware -* Distribution Maintainer - Packaging kernels for distros -* AI Coding Assistant - LLMs and AI-powered development tools - - -For Specific Users -================== - -New Kernel Developer --------------------- - -Welcome! Start your kernel development journey here: - -* Getting Started: Documentation/process/development-process.rst -* Your First Patch: Documentation/process/submitting-patches.rst -* Coding Style: Documentation/process/coding-style.rst -* Build System: Documentation/kbuild/index.rst -* Development Tools: Documentation/dev-tools/index.rst -* Kernel Hacking Guide: Documentation/kernel-hacking/hacking.rst -* Core APIs: Documentation/core-api/index.rst - -Academic Researcher -------------------- - -Explore the kernel's architecture and internals: - -* Researcher Guidelines: Documentation/process/researcher-guidelines.rst -* Memory Management: Documentation/mm/index.rst -* Scheduler: Documentation/scheduler/index.rst -* Networking Stack: Documentation/networking/index.rst -* Filesystems: Documentation/filesystems/index.rst -* RCU (Read-Copy Update): Documentation/RCU/index.rst -* Locking Primitives: Documentation/locking/index.rst -* Power Management: Documentation/power/index.rst - -Security Expert ---------------- - -Security documentation and hardening guides: - -* Security Documentation: Documentation/security/index.rst -* LSM Development: Documentation/security/lsm-development.rst -* Self Protection: Documentation/security/self-protection.rst -* Reporting Vulnerabilities: Documentation/process/security-bugs.rst -* CVE Procedures: Documentation/process/cve.rst -* Embargoed Hardware Issues: Documentation/process/embargoed-hardware-issues.rst -* Security Features: Documentation/userspace-api/seccomp_filter.rst - -Backport/Maintenance Engineer ------------------------------ - -Maintain and stabilize kernel versions: - -* Stable Kernel Rules: Documentation/process/stable-kernel-rules.rst -* Backporting Guide: Documentation/process/backporting.rst -* Applying Patches: Documentation/process/applying-patches.rst -* Subsystem Profile: Documentation/maintainer/maintainer-entry-profile.rst -* Git for Maintainers: Documentation/maintainer/configure-git.rst - -System Administrator --------------------- - -Configure, tune, and troubleshoot Linux systems: - -* Admin Guide: Documentation/admin-guide/index.rst -* Kernel Parameters: Documentation/admin-guide/kernel-parameters.rst -* Sysctl Tuning: Documentation/admin-guide/sysctl/index.rst -* Tracing/Debugging: Documentation/trace/index.rst -* Performance Security: Documentation/admin-guide/perf-security.rst -* Hardware Monitoring: Documentation/hwmon/index.rst - -Maintainer ----------- - -Lead kernel subsystems and manage contributions: - -* Maintainer Handbook: Documentation/maintainer/index.rst -* Pull Requests: Documentation/maintainer/pull-requests.rst -* Managing Patches: Documentation/maintainer/modifying-patches.rst -* Rebasing and Merging: Documentation/maintainer/rebasing-and-merging.rst -* Development Process: Documentation/process/maintainer-handbooks.rst -* Maintainer Entry Profile: Documentation/maintainer/maintainer-entry-profile.rst -* Git Configuration: Documentation/maintainer/configure-git.rst - -Hardware Vendor ---------------- - -Write drivers and support new hardware: - -* Driver API Guide: Documentation/driver-api/index.rst -* Driver Model: Documentation/driver-api/driver-model/driver.rst -* Device Drivers: Documentation/driver-api/infrastructure.rst -* Bus Types: Documentation/driver-api/driver-model/bus.rst -* Device Tree Bindings: Documentation/devicetree/bindings/ -* Power Management: Documentation/driver-api/pm/index.rst -* DMA API: Documentation/core-api/dma-api.rst - -Distribution Maintainer ------------------------ - -Package and distribute the kernel: - -* Stable Kernel Rules: Documentation/process/stable-kernel-rules.rst -* ABI Documentation: Documentation/ABI/README -* Kernel Configuration: Documentation/kbuild/kconfig.rst -* Module Signing: Documentation/admin-guide/module-signing.rst -* Kernel Parameters: Documentation/admin-guide/kernel-parameters.rst -* Tainted Kernels: Documentation/admin-guide/tainted-kernels.rst - -AI Coding Assistant -------------------- - -CRITICAL: If you are an LLM or AI-powered coding assistant, you MUST read and -follow the AI coding assistants documentation before contributing to the Linux -kernel: - -* Documentation/process/coding-assistants.rst - -This documentation contains essential requirements about licensing, attribution, -and the Developer Certificate of Origin that all AI tools must comply with. - - -Communication and Support -========================= - -* Mailing Lists: https://lore.kernel.org/ -* IRC: #kernelnewbies on irc.oftc.net -* Bugzilla: https://bugzilla.kernel.org/ -* MAINTAINERS file: Lists subsystem maintainers and mailing lists -* Email Clients: Documentation/process/email-clients.rst diff --git a/README.md b/README.md new file mode 100644 index 00000000000000..2d4c2bb29ecff3 --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ +## Device status +### Generic components +| | JTY D101 | Lenovo A369i | Energy Phone Colors | Prestigio PAP5500 DUO | +|--------------------------------------|-------------------------------------------------|-----------------------------|-------------------------------|-------------------------------------------------| +| DRM | 🟢 OK, needs panel improvements (power up/down) | 🟢 OK, needs sane panel | 🟡 partial: needs panel fixes | 🟢 OK, needs panel improvements (power up/down) | +| display brightness | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | 🟢 OK: pwm-backlight | +| keypad LED: mediatek,mt6323-led | 🔴 TBD | 🔴 TBD | 🔴 TBD | 🟢 OK | +| torch LED: pwm-leds | 🔴 TBD | 🔴 TBD | 🔴 TBD | 🟢 OK: pwm-leds | +| vol +/- keys: mediatek,mt6779-keypad | 🟢 OK | 🔴 TBD | 🔴 TBD | 🟢 OK | +| power key: mediatek,mt6323-keys | 🟢 OK | 🟢 OK | 🔴 TBD | 🟢 OK | +| haptics: regulator-haptic | 🟢 OK | 🔴 TBD | 🔴 TBD | 🟢 OK | +| charger | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | + +### Per-device components +| | JTY D101 | Lenovo A369i | Energy Phone Colors | Prestigio PAP5500 DUO | +|-----------------|------------------------------------|---------------------------|-------------------------------|------------------------------------| +| touchscreen | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | 🟢 OK: goodix,gt911 | +| panel | 🟡 partial: needs power cycle seqs | 🟢 OK, needs improvements | 🟡 partial: needs panel fixes | 🟡 partial | +| accelerometer | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | 🟢 OK: bosch,bma222e (polling) | +| alsps | 🔴 DEAD | 🔴 DEAD | 🔴 DEAD | 🟢 OK: rohm,rpr0400 (polling) | + +## Platform status +everything marked with 'needs upstreaming' means it's not existent in the upstream + +### CPU +| component | driver | status | note | +|-----------|------------------------------------|-----------|-----------------------------------------| +| SMP | arch/arm/mach-mediatek/platsmp.c | 🟢 OK | | +| cpufreq | drivers/cpufreq/mediatek-cpufreq.c | 🟢 OK | | +| hotplug | arch/arm/mach-mediatek/platsmp.c | 🟢 OK | needs upstreaming | +| cpuidle | | 🔴 DEAD | probably needs new driver, wfi may work | +| PMU | arm,cortex-a7-pmu | 🔴 DEAD | low priority, should be easy to port | + +### Timer +| component | driver | status | note | +|------------|-----------------------|-----------|---------------------------| +| APXGPT | mediatek,mt6577-timer | 🟢 OK | | +| arch timer | arm,armv7-timer | 🟢 OK | needs fix upstreaming | + +### Clocks +all of these need upstreaming + +| component | driver | status | note | +|-----------|----------------------------|------------|--------------------------------------| +| topckgen | mediatek,mt6572-topckgen | 🟢 OK | | +| infracfg | mediatek,mt6572-infracfg | 🟢 OK | | +| apmixed | mediatek,mt6572-apmixedsys | 🟢 OK | | +| fhctl | subset of apmixed iirc | 🔴 DEAD | not sure if we really need it | +| mmsys | mediatek,mt6572-mmsys | 🟡 partial | some dbi clocks from cg1 are missing | +| mfgcfg | mediatek,mt6572-mfgcfg | 🟢 OK | | +| audio | | 🔴 DEAD | not needed for now, can't test | + +### Pinctrl +missing emmc r1r0 pins, needs upstreaming + +### Buses +| component | driver | status | note | +|-----------|--------------------------|---------|-------------------| +| UART | mediatek,mt6577-uart | 🟢 OK | | +| I2C | mediatek,mt6572-i2c | 🟢 OK | needs upstreaming | +| SPI | | 🔴 DEAD | | +| USB | mediatek,mtk-musb | 🟢 OK | | +| USB PHY | mediatek,generic-tphy-v1 | 🟢 OK | | + +### Power +### SoC +| component | driver | status | note | +|--------------|----------------------------------|------------|----------------------------| +| pwrap | mediatek,mt6572-pwrap | 🟢 OK | needs upstreaming | +| power domain | mediatek,mt6572-power-controller | 🟡 partial | only disp and mfg pds work | + +#### PMIC +| component | driver | status | note | +|------------|---------------------------|-----------|------------------------------------------| +| regulators | mediatek,mt6323-regulator | 🟢 OK | | +| efuse | mediatek,mt6323-efuse | 🟢 OK | needs upstreaming | +| thermal | mediatek,mt6323-thermal | 🟢 OK | needs upstreaming, also tested on mt8163 | +| ADC | mediatek,mt6323-auxadc | 🟢 OK | needs upstreaming, needs cleanup a bit | +| fuel gauge | | 🔴 DEAD | needs new driver | + +### Storage +using upstream driver + +| component | driver | status | note | +|-----------|----------------------------|------------|--------------------------------------| +| eMMC | mediatek,mt2701-mmc | 🟢 OK | no PMT parser yet | +| microSD | mediatek,mt2701-mmc | 🟢 OK | | +| NAND | | 🔴 DEAD | no known device with NAND | + +### SoC +misc SoC components without category + +| component | driver | status | note | +|------------------|-------------------------|------------|----------------------------------------------------------| +| interrupt parent | mediatek,mt6577-sysirq | 🟢 OK | | +| reset controller | mediatek,mt6572-wdt | 🟢 OK | needs upstreaming | +| cpu core control | mediatek,mt6572-mcusys | | dummy compatible, used for hotplug | +| efuse | mediatek,mt8173-efuse | 🟢 OK | needs upstreaming | +| ADC | mediatek,mt8173-auxadc | 🟢 OK | | +| thermal | mediatek,mt6572-thermal | 🟡 partial | temperature is higher (?) than actual, needs upstreaming | + +### Display +| component | driver | status | note | +|------------------|---------------------------------------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------| +| MMSYS | drivers/soc/mediatek/mtk-mmsys.c: mediatek,mt6572-mmsys | 🟡 partial | no cmdq, needs upstreaming and routing table cleanup | +| DRM | drivers/gpu/drm/mediatek/mtk_drm_drm.c: mediatek,mt6572-mmsys | 🟡 partial | currently falls back to mt2701 plat data, needs own data because we have only 1 rdma | +| IOMMU | mediatek,mt6572-m4u | 🟢 OK | needs upstreaming | +| SMI | mediatek,mt6572-smi-common | 🟢 OK | needs upstreaming | +| LARB | mediatek,mt6572-smi-larb | 🟢 OK | needs upstreaming | +| overlay | mediatek,mt6572-disp-ovl | 🟢 OK | needs upstreaming | +| read DMA | mediatek,mt6572-disp-rdma | 🟢 OK | needs upstreaming | +| write DMA | | 🔴 DEAD | no driver | +| BLS | mediatek,mt2701-disp-pwm | 🟡 partial | brightness doesn't work, needs some fixes and likely new compatible | +| color correction | mediatek,mt2701-disp-color | 🟢 OK | | +| DSI | mediatek,mt6572-dsi | 🟡 partial | needs upstreaming, vblank timeout before drm inits (observed on mt8163 and mt6735 too), might be compatible with mt2701, needs checking | +| DSI PHY | mediatek,mt2701-mipi-tx | 🟢 OK | | +| DBI | | 🔴 DEAD | no known device with DBI display, can't test/port | +| DPI | | 🔴 DEAD | no known device with DPI display, can't test/port | +| hw mutex | mediatek,mt6572-disp-mutex | 🟡 partial | needs upstreaming, missing mdp ids | +| CMDQ | | 🔴 DEAD | cmdq is very different from gce, needs lot of drm hacking to make it work | +| GPU | arm,mali-400 | 🟢 OK | | + +## External contributions +this is so i can track who contributed to this kernel fork + +- [CustomFirmwareDev](https://github.com/gabin8) - i2c dma fix, Prestigio PAP5500 DUO support + +## Dead subsystems +there's no upstream support OR they need some effort to make them working + +### MDP +| component | similar driver | note | +|-----------|----------------------------|------| +| read DMA | mediatek,mt8183-mdp3-rdma | | +| resize | mediatek,mt8183-mdp3-rsz | | +| write DMA | mediatek,mt8183-mdp3-wdma | | +| sharpness | mediatek,mt8195-mdp3-tdshp | | + +### Camera +non existent in the upstream + +### HW video enc/dec +mostly useless i'd say, they're not full hw engines but rather only parts of the process. not worth the effort + +### Connectivity +not existent in the upstream + +### Audio +needs afe/i2s/etc drivers + +### Pericfg +it seems to be clock + reset controller for NAND and USB + +### EMI mfd +EMI has performance monitoring + bw limiter + +### HACC +might be not worth the effort because it's pretty slow compared to software + +### devapc +bus violation monitor? not sure if we really need it, but should be pretty easy to port + +### APARM (?) +downstrema calls it APARM_BASE and maps as infrasys? used for watchpoint and breakpoint diff --git a/arch/arm/boot/dts/mediatek/Makefile b/arch/arm/boot/dts/mediatek/Makefile index 37c4cded0eae8c..49226837501e4f 100644 --- a/arch/arm/boot/dts/mediatek/Makefile +++ b/arch/arm/boot/dts/mediatek/Makefile @@ -1,8 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt2701-evb.dtb \ + mt6572-energy-phone-colors.dtb \ mt6572-jty-d101.dtb \ mt6572-lenovo-a369i.dtb \ + mt6572-prestigio-pap5500-duo.dtb \ mt6580-evbp1.dtb \ mt6582-alcatel-yarisxl.dtb \ mt6582-prestigio-pmt5008-3g.dtb \ diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi index c230c865116d08..78e370b7100736 100644 --- a/arch/arm/boot/dts/mediatek/mt6323.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi @@ -6,6 +6,8 @@ * */ +#include + &pwrap { pmic: mt6323 { compatible = "mediatek,mt6323"; @@ -14,6 +16,25 @@ interrupt-controller; #interrupt-cells = <2>; + mt6323_adc: adc { + compatible = "mediatek,mt6323-auxadc"; + #io-channel-cells = <1>; + }; + + efuse { + compatible = "mediatek,mt6323-efuse"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mt6323_thermal_calibration_data: thermal-data@14 { + reg = <0x14 0x4>; + }; + }; + }; + mt6323_leds: leds { compatible = "mediatek,mt6323-led"; #address-cells = <1>; @@ -265,5 +286,24 @@ rtc { compatible = "mediatek,mt6323-rtc"; }; + + mt6323_thermal: thermal { + compatible = "mediatek,mt6323-thermal"; + nvmem-cells = <&mt6323_thermal_calibration_data>; + + io-channels = <&mt6323_adc MT6323_AUXADC_CHIP_TEMP>; + #thermal-sensor-cells = <1>; + }; + }; +}; + +/ { + thermal-zones { + pmic-vts-thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = <&mt6323_thermal 0>; + }; }; }; diff --git a/arch/arm/boot/dts/mediatek/mt6572-energy-phone-colors.dts b/arch/arm/boot/dts/mediatek/mt6572-energy-phone-colors.dts new file mode 100644 index 00000000000000..409073da370897 --- /dev/null +++ b/arch/arm/boot/dts/mediatek/mt6572-energy-phone-colors.dts @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 rva3 + */ + +/dts-v1/; +#include +//#include +#include "mt6572.dtsi" +#include "mt6323.dtsi" + +/ { + model = "Energy Phone Colors"; + compatible = "energysistem,colors", "mediatek,mt6572"; + + aliases { + serial0 = &uart0; + }; + + chosen { + #address-cells = <1>; + #size-cells = <1>; + stdout-path = "serial0:921600n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + connsys@80000000 { + reg = <0x80000000 0x100000>; + no-map; + }; + + framebuffer_reserved: framebuffer@9fa00000 { + reg = <0x9fa00000 0x600000>; + no-map; + }; + + }; +}; + +&cpu0 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&cpu1 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&bls { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "eastaeon,n402"; + reg = <0>; + vcc-supply = <&mt6323_vgp1_reg>; + + reset-gpios = <&pio 56 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; +}; + +&mt6323keys { + power-off-time-sec = <5>; + home { + status = "disabled"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&pmic { + pinctrl-0 = <&pmic_int_pins>; + pinctrl-names = "default"; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; +}; + +&pwrap { + assigned-clocks = <&topckgen CLK_TOP_PMIC_SPI_SEL>; + assigned-clock-parents = <&uart_clk>; +}; + +&pio { + pmic_int_pins: pmic-int-pins { + pins { + pinmux = ; + input-enable; + bias-pull-down; + }; + }; +}; diff --git a/arch/arm/boot/dts/mediatek/mt6572-jty-d101.dts b/arch/arm/boot/dts/mediatek/mt6572-jty-d101.dts index 18c3cab6b7a3ca..6dbd862755038d 100644 --- a/arch/arm/boot/dts/mediatek/mt6572-jty-d101.dts +++ b/arch/arm/boot/dts/mediatek/mt6572-jty-d101.dts @@ -4,7 +4,11 @@ */ /dts-v1/; +#include +#include +//#include #include "mt6572.dtsi" +#include "mt6323.dtsi" / { model = "JTY D101"; @@ -18,15 +22,6 @@ #address-cells = <1>; #size-cells = <1>; stdout-path = "serial0:921600n8"; - - framebuffer: framebuffer@bf400000 { - compatible = "simple-framebuffer"; - memory-region = <&framebuffer_reserved>; - width = <1024>; - height = <600>; - stride = <(1024 * 2)>; - format = "r5g6b5"; - }; }; memory@80000000 { @@ -53,9 +48,230 @@ reg = <0xbf400000 0xc00000>; no-map; }; + + default-pool { + compatible = "shared-dma-pool"; + size = <0x6000000>; + alloc-ranges = <0x90000000 0x10000000>; + reusable; + linux,cma-default; + }; + }; + + haptic { + compatible = "regulator-haptic"; + haptic-supply = <&mt6323_vibr_reg>; + min-microvolt = <1200000>; + max-microvolt = <3300000>; + }; +}; + +&auxadc { + status = "okay"; +}; + +&cpu0 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&cpu1 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&bls { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "wsvgalnl,ek79007"; + reg = <0>; + vcc-supply = <&mt6323_vgp1_reg>; + + //pinctrl-names = "default"; + //pinctrl-0 = <&panel_pins>; + + reset-gpios = <&pio 56 GPIO_ACTIVE_HIGH>; + //enable-gpios = <&pio 135 GPIO_ACTIVE_HIGH>; + //standby-gpios = <&pio 56 GPIO_ACTIVE_HIGH>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; +}; + +&i2c0 { + clock-frequency = <400000>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + accelerometer@4c { + compatible = "mcube,mc3236"; + reg = <0x4c>; }; }; &uart0 { status = "okay"; }; + +&usb { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&pmic { + pinctrl-0 = <&pmic_int_pins>; + pinctrl-names = "default"; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; +}; + +&pwrap { + assigned-clocks = <&topckgen CLK_TOP_PMIC_SPI_SEL>; + assigned-clock-parents = <&uart_clk>; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins>; + pinctrl-1 = <&mmc0_pins>; + pinctrl-names = "default", "state_uhs"; + bus-width = <1>; + max-frequency = <50000000>; + cap-mmc-highspeed; + //mmc-ddr-1_8v; + //mmc-hs200-1_8v; + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; + non-removable; + status = "okay"; +}; + +&mmc1 { + pinctrl-0 = <&mmc1_pins>; + pinctrl-1 = <&mmc1_pins>; + pinctrl-names = "default", "state_uhs"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + //sd-uhs-ddr50; + //sd-uhs-sdr104; + sd-uhs-sdr12; + sd-uhs-sdr25; + //sd-uhs-sdr50; + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vmc_reg>; + //cd-gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + broken-cd; + status = "okay"; +}; + +&mt6323keys { + power-off-time-sec = <5>; + home { + status = "disabled"; + }; +}; + +&keyboard { + status = "okay"; + linux,keymap = ; + keypad,num-rows = <2>; + keypad,num-columns = <1>; + debounce-delay-ms = <32>; +}; + +&pio { + pmic_int_pins: pmic-int-pins { + pins { + pinmux = ; + input-enable; + bias-pull-down; + }; + }; + + pwrap_pins: pwrap-pins { + pins { + pinmux = , + , + , + ; + }; + }; + + mmc0_pins: mmc0-pins { + pins-clk { + pinmux = ; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + bias-pull-up = ; + }; + + pins-rst { + pinmux = ; + bias-pull-up = ; + }; + }; + + mmc1_pins: mmc1-pins { + pins-clk { + pinmux = ; + bias-pull-down; + drive-strength = <8>; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + ; + input-enable; + bias-pull-up; + drive-strength = <8>; + }; + }; + + panel_pins: panel-pins { + pins_reset { + pinmux = ; + output-low; + }; + pins_enable { + pinmux = ; + output-low; + }; + }; +}; diff --git a/arch/arm/boot/dts/mediatek/mt6572-lenovo-a369i.dts b/arch/arm/boot/dts/mediatek/mt6572-lenovo-a369i.dts index c2f0c60ea77743..1b8d726561af69 100644 --- a/arch/arm/boot/dts/mediatek/mt6572-lenovo-a369i.dts +++ b/arch/arm/boot/dts/mediatek/mt6572-lenovo-a369i.dts @@ -4,7 +4,10 @@ */ /dts-v1/; +#include +#include #include "mt6572.dtsi" +#include "mt6323.dtsi" / { model = "Lenovo A369i"; @@ -20,12 +23,13 @@ stdout-path = "serial0:921600n8"; framebuffer: framebuffer@9fa00000 { - compatible = "simple-framebuffer"; + //compatible = "simple-framebuffer"; memory-region = <&framebuffer_reserved>; width = <480>; height = <800>; stride = <(480 * 2)>; format = "r5g6b5"; + power-domains = <&spm MT6572_POWER_DOMAIN_DIS>; }; }; @@ -49,8 +53,170 @@ no-map; }; }; + + haptic { + compatible = "regulator-haptic"; + haptic-supply = <&mt6323_vibr_reg>; + min-microvolt = <1200000>; + max-microvolt = <3300000>; + }; +}; + +&bls { + status = "okay"; +}; + +&cpu0 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&cpu1 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "djn,otm8018b"; + reg = <0>; + vcc-supply = <&mt6323_vgp1_reg>; + + //pinctrl-names = "default"; + //pinctrl-0 = <&panel_pins>; + + reset-gpios = <&pio 56 GPIO_ACTIVE_HIGH>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + +}; + +&gpu { + /* Switch to WHPLL */ + assigned-clocks = <&topckgen CLK_TOP_MFG_MUX_SEL>, + <&topckgen CLK_TOP_MFG_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_MFG_PRE_500M>, + <&topckgen CLK_TOP_MFG_MUX_SEL>; + + operating-points-v2 = <&gpu_opp_table>; + nvmem-cells = <&gpu_speedbin>; + nvmem-cell-names = "speedbin"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + accelerometer@15 { + compatible = "memsic,mxc6255"; + reg = <0x15>; + }; +}; + +&mmc1 { + pinctrl-0 = <&mmc1_pins>; + pinctrl-1 = <&mmc1_pins>; + pinctrl-names = "default", "state_uhs"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + //sd-uhs-ddr50; + //sd-uhs-sdr104; + sd-uhs-sdr12; + sd-uhs-sdr25; + //sd-uhs-sdr50; + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vmc_reg>; + //cd-gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + broken-cd; + status = "okay"; }; &uart0 { status = "okay"; }; + +&usb { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&pmic { + pinctrl-0 = <&pmic_int_pins>; + pinctrl-names = "default"; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; +}; + +&pwrap { + pinctrl-names = "default"; +}; + +&pio { + mmc1_pins: mmc1-pins { + pins-clk { + pinmux = ; + bias-pull-down; + drive-strength = <8>; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + ; + input-enable; + bias-pull-up; + drive-strength = <8>; + }; + }; + + panel_pins: panel-pins { + pins_reset { + pinmux = ; + }; + }; + + pmic_int_pins: pmic-int-pins { + pins { + pinmux = ; + input-enable; + }; + }; +}; + +&mt6323keys { + power-off-time-sec = <5>; + home { + status = "disabled"; + }; +}; + +&keyboard { + status = "okay"; + linux,keymap = ; + keypad,num-rows = <1>; + keypad,num-columns = <2>; + debounce-delay-ms = <32>; +}; diff --git a/arch/arm/boot/dts/mediatek/mt6572-prestigio-pap5500-duo.dts b/arch/arm/boot/dts/mediatek/mt6572-prestigio-pap5500-duo.dts new file mode 100644 index 00000000000000..6ca5c94debf302 --- /dev/null +++ b/arch/arm/boot/dts/mediatek/mt6572-prestigio-pap5500-duo.dts @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Custom Firmware + */ + +/dts-v1/; +#include +#include +#include +#include "mt6572.dtsi" +#include "mt6323.dtsi" + +/ { + model = "Prestigio MultiPhone PAP5500 DUO"; + compatible = "prestigio,pap5500-duo", "mediatek,mt6572"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + framebuffer_reserved: framebuffer@9f800000 { + reg = <0x9f800000 0x800000>; + no-map; + }; + }; + + battery: battery { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <2000000>; + voltage-max-design-microvolt = <4200000>; + voltage-min-design-microvolt = <3300000>; + ocv-capacity-celsius = <25>; + ocv-capacity-table-0 = <4189000 100>, <4107000 95>, + <4063000 90>, <4018000 85>, + <3975000 80>, <3937000 75>, + <3907000 70>, <3871000 65>, + <3843000 60>, <3810000 55>, + <3787000 50>, <3781000 45>, + <3777000 40>, <3772000 35>, + <3753000 30>, <3719000 25>, + <3671000 20>, <3596000 15>, + <3536000 10>, <3493000 5>, + <3419000 0>; + }; + + haptic { + compatible = "regulator-haptic"; + haptic-supply = <&mt6323_vibr_reg>; + min-microvolt = <1200000>; + max-microvolt = <3300000>; + }; + + pwm-leds { + compatible = "pwm-leds"; + pinctrl-0 = <&flash_pins>; + pinctrl-names = "default"; + + led-torch { + function = LED_FUNCTION_TORCH; + color = ; + pwms = <&pwm 0 31250>; + max-brightness = <255>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm 1 31250>; + brightness-levels = <0 1023>; + num-interpolated-steps = <1023>; + default-brightness-level = <512>; + power-supply = <&mt6323_vsys_reg>; + }; +}; + +&auxadc { + status = "okay"; +}; + +&bls { + status = "okay"; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "boyi,otm8018b"; + reg = <0>; + vcc-supply = <&mt6323_vgp1_reg>; + backlight = <&backlight>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; +}; + +&cpu0 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&cpu1 { + proc-supply = <&mt6323_vproc_reg>; +}; + +&gpu { + /* Switch to WHPLL */ + assigned-clocks = <&topckgen CLK_TOP_MFG_MUX_SEL>, + <&topckgen CLK_TOP_MFG_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_MFG_PRE_500M>, + <&topckgen CLK_TOP_MFG_MUX_SEL>; + + operating-points-v2 = <&gpu_opp_table>; + nvmem-cells = <&gpu_speedbin>; + nvmem-cell-names = "speedbin"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + clock-frequency = <400000>; + status = "okay"; + + touchscreen@5d { + status = "okay"; + compatible = "goodix,gt911"; + reg = <0x5d>; + + interrupt-parent = <&pio>; + interrupts = <1 IRQ_TYPE_EDGE_RISING>; + irq-gpios = <&pio 129 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pio 57 GPIO_ACTIVE_HIGH>; + + AVDD28-supply = <&mt6323_vgp1_reg>; + VDDIO-supply = <&mt6323_vio18_reg>; + + touchscreen-size-x = <480>; + touchscreen-size-y = <854>; + touchscreen-inverted-x; + + pinctrl-0 = <&tpd_pins>; + pinctrl-names = "default"; + }; + + light-sensor@39 { + compatible = "rohm,rpr0400"; + reg = <0x39>; + vdd-supply = <&mt6323_vgp1_reg>; + vddio-supply = <&mt6323_vio18_reg>; + }; + + accelerometer@18 { + compatible = "bosch,bma222e"; + reg = <0x18>; + vdd-supply = <&mt6323_vgp1_reg>; + vddio-supply = <&mt6323_vio18_reg>; + }; +}; + +&mt6323_vgp1_reg { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; +}; + +&mt6323_vgp2_reg { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; +}; + +&mt6323_vgp3_reg { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; +}; + +&mt6323keys { + power-off-time-sec = <5>; + home { + status = "disabled"; + }; +}; + +&mt6323_leds { + status = "okay"; + + led@3 { + reg = <3>; + function = LED_FUNCTION_KBD_BACKLIGHT; + color = ; + default-state = "off"; + }; +}; + + +&pwm { + pinctrl-0 = <&bl_pwm_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&pmic { + pinctrl-0 = <&pmic_int_pins>; + pinctrl-names = "default"; + interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; +}; + +&pwrap { + assigned-clocks = <&topckgen CLK_TOP_PMIC_SPI_SEL>; + assigned-clock-parents = <&uart_clk>; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins>; + pinctrl-1 = <&mmc0_pins>; + pinctrl-names = "default", "state_uhs"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; + non-removable; + status = "okay"; +}; + +&mmc1 { + pinctrl-0 = <&mmc1_pins>; + pinctrl-1 = <&mmc1_pins>; + pinctrl-names = "default", "state_uhs"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vmc_reg>; + broken-cd; + status = "okay"; +}; + +&keyboard { + status = "okay"; + linux,keymap = ; + keypad,num-rows = <1>; + keypad,num-columns = <3>; + debounce-delay-ms = <32>; +}; + +&pio { + bl_pwm_pins: bl-pwm-pins { + pins { + pinmux = ; + }; + }; + + pmic_int_pins: pmic-int-pins { + pins { + pinmux = ; + input-enable; + bias-pull-down; + }; + }; + + mmc0_pins: mmc0-pins { + pins-clk { + pinmux = ; + bias-pull-down = ; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + bias-pull-up = ; + }; + + pins-rst { + pinmux = ; + bias-pull-up = ; + }; + }; + + tpd_pins: tpd-pins { + pins-rst { + pinmux = ; + output-high; + }; + pins-int { + pinmux = ; + input-enable; + bias-pull-up; + }; + }; + + i2c1_pins: i2c1-pins { + pins { + pinmux = , + ; + }; + }; + + flash_pins: flash-pins { + pins { + pinmux = ; + }; + }; + + mmc1_pins: mmc1-pins { + pins-clk { + pinmux = ; + bias-pull-down; + drive-strength = <8>; + }; + + pins-cmd-dat { + pinmux = , + , + , + , + ; + input-enable; + bias-pull-up; + drive-strength = <8>; + }; + }; +}; diff --git a/arch/arm/boot/dts/mediatek/mt6572.dtsi b/arch/arm/boot/dts/mediatek/mt6572.dtsi index ac70f266d698d3..2042ebd69a7158 100644 --- a/arch/arm/boot/dts/mediatek/mt6572.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6572.dtsi @@ -5,33 +5,131 @@ #include #include +#include +#include +#include +#include +#include +#include +#include / { #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&sysirq>; + aliases { + ovl0 = &ovl; + rdma0 = &rdma0; + }; + + cpu_opp_table: cpu-opp-table { + compatible = "operating-points-v2"; + opp-shared; + + nvmem-cells = <&cpu_speedbin>; + nvmem-cell-names = "speedbin"; + + /* MT6572M, MT6572A, MT6572W */ + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0xf>; + }; + + opp-806000000 { + opp-hz = /bits/ 64 <806000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0xf>; + }; + + opp-1001000000 { + opp-hz = /bits/ 64 <1001000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0xf>; + }; + + /* MT6572A, MT6572W */ + opp-1209000000 { + opp-hz = /bits/ 64 <1209000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0x7>; + }; + + /* MT6572W */ + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0x3>; + }; + + opp-1404000000 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <1150000>; + opp-supported-hw = <0x3>; + }; + }; + + gpu_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-supported-hw = <0x1>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-supported-hw = <0x3>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-supported-hw = <0x1>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "mediatek,mt6589-smp"; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x0>; + clock-frequency = <1001000000>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&topckgen CLK_TOP_MPLL_D2>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; }; - cpu@1 { + + cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x1>; + clock-frequency = <1001000000>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&topckgen CLK_TOP_MPLL_D2>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; }; }; + univpll: univpll { + compatible = "fixed-clock"; + clock-frequency = <1248000000>; + #clock-cells = <0>; + }; + uart_clk: dummy26m { compatible = "fixed-clock"; clock-frequency = <26000000>; #clock-cells = <0>; + clock-output-names = "clk26m"; }; system_clk: dummy13m { @@ -46,14 +144,134 @@ #clock-cells = <0>; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = <&thermal 0>; + + trips { + cpu_passive: cpu-passive { + temperature = <57000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu-active { + temperature = <67000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_hot: cpu-hot { + temperature = <87000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu-crit { + temperature = <107000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_passive>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_active>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map2 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + clock-frequency = <13000000>; + arm,cpu-registers-not-fw-configured; + }; + soc { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges; + topckgen: syscon@10000000 { + compatible = "mediatek,mt6572-topckgen", "syscon"; + reg = <0x10000000 0x1000>; + #clock-cells = <1>; + }; + + mcusys: syscon@10200000 { + compatible = "mediatek,mt6572-mcusys", "syscon"; + reg = <0x10200000 0x1000>; + }; + + infracfg: syscon@10001000 { + compatible = "mediatek,mt6572-infracfg", "syscon"; + reg = <0x10001000 0x1000>; + #clock-cells = <1>; + }; + + keyboard: keyboard@10002000 { + compatible = "mediatek,mt6572-keypad", "mediatek,mt6779-keypad"; + reg = <0x10002000 0x1000>; + interrupts = ; + clocks = <&uart_clk>; + clock-names = "kpd"; + status = "disabled"; + }; + + power-controller@10006000 { + compatible = "mediatek,mt6572-scpsys", "syscon", "simple-mfd"; + reg = <0x10006000 0x1000>; + + spm: power-controller { + compatible = "mediatek,mt6572-power-controller"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT6572_POWER_DOMAIN_DIS { + reg = ; + #power-domain-cells = <0>; + clocks = <&mmsys CLK_MM_MUTEX_SLOW_CLOCK>; + clock-names = "mm"; + mediatek,infracfg = <&infracfg>; + }; + + power-domain@MT6572_POWER_DOMAIN_MFG { + reg = ; + #power-domain-cells = <0>; + clocks = <&topckgen CLK_TOP_MFG_MM>; + clock-names = "mfg"; + mediatek,infracfg = <&infracfg>; + }; + }; + }; + watchdog: watchdog@10007000 { - compatible = "mediatek,mt6572-wdt", "mediatek,mt6589-wdt"; + compatible = "mediatek,mt6572-wdt"; reg = <0x10007000 0x100>; interrupts = ; timeout-sec = <15>; @@ -68,6 +286,90 @@ clock-names = "system-clk", "rtc-clk"; }; + efuse: efuse@10009000 { + compatible = "mediatek,mt6572-efuse"; + reg = <0x10009000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + thermal_calibration: calib@174 { + reg = <0x174 0x8>; + }; + + gpu_speedbin: calib@178 { + reg = <0x178 0x4>; + bits = <27 1>; + }; + + cpu_speedbin: socinfo-data1@180 { + reg = <0x180 0x4>; + bits = <8 2>; + }; + }; + + pio: pinctrl@1000b000 { + compatible = "mediatek,mt6572-pinctrl"; + reg = <0x10005000 0x1000>, + <0x10208000 0x1000>, + <0x10209000 0x1000>, + <0x1020a000 0x1000>, + <0x1020b000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "gpio", "iocfg_t", "iocfg_b", + "iocfg_l", "iocfg_r", "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 153>; + interrupt-controller; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupts = ; + }; + + thermal: thermal@1100d000 { + #thermal-sensor-cells = <1>; + compatible = "mediatek,mt6572-thermal"; + reg = <0x1100d000 0x1000>; + interrupts = ; + clocks = <&topckgen CLK_TOP_THERMAL>, <&topckgen CLK_TOP_AUXADC>; + clock-names = "therm", "auxadc"; + mediatek,auxadc = <&auxadc>; + mediatek,apmixedsys = <&apmixedsys>; + nvmem-cells = <&thermal_calibration>; + nvmem-cell-names = "calibration-data"; + }; + + smi_common: smi@1000e000 { + compatible = "mediatek,mt6572-smi-common"; + reg = <0x1000e000 0x1000>, <0x14011000 0x1000>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6572_POWER_DOMAIN_DIS>; + }; + + pwrap: pwrap@1000f000 { + compatible = "mediatek,mt6572-pwrap"; + reg = <0x1000f000 0x1000>; + reg-names = "pwrap"; + interrupts = ; + resets = <&watchdog MT6572_TOPRGU_PWRAP_SPI_CTL_RST>; + reset-names = "pwrap"; + clocks = <&topckgen CLK_TOP_PMIC_SPI>, + <&topckgen CLK_TOP_PMIC_WRAP>; + clock-names = "spi", "wrap"; + }; + + mipi_tx0: dsi-phy@10011000 { + compatible = "mediatek,mt7623-mipi-tx", + "mediatek,mt2701-mipi-tx"; + reg = <0x10011000 0x90>; + clocks = <&uart_clk>; + clock-output-names = "mipi_tx0_pll"; + #clock-cells = <0>; + #phy-cells = <0>; + }; + sysirq: interrupt-controller@10200100 { compatible = "mediatek,mt6572-sysirq", "mediatek,mt6577-sysirq"; reg = <0x10200100 0x1c>; @@ -87,12 +389,38 @@ interrupt-parent = <&gic>; }; + iommu: iommu@10203000 { + compatible = "mediatek,mt6572-m4u"; + reg = <0x10203000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_SMI_COMMON>; + clock-names = "bclk"; + mediatek,larbs = <&larb0>; + #iommu-cells = <1>; + power-domains = <&spm MT6572_POWER_DOMAIN_DIS>; /* probably */ + }; + + apmixedsys: apmixedsys@10205000 { + compatible = "mediatek,mt6572-apmixedsys", "syscon"; + reg = <0x10205000 0x1000>; + #clock-cells = <1>; + }; + + auxadc: adc@110013000 { + compatible = "mediatek,mt8173-auxadc"; + reg = <0x11003000 0x1000>; + clocks = <&topckgen CLK_TOP_AUXADC>; + clock-names = "main"; + #io-channel-cells = <1>; + status = "disabled"; + }; + uart0: serial@11005000 { compatible = "mediatek,mt6572-uart", "mediatek,mt6577-uart"; reg = <0x11005000 0x400>; interrupts = ; - clocks = <&uart_clk>; - clock-names = "baud"; + clocks = <&topckgen CLK_TOP_UART0_SEL>, <&topckgen CLK_TOP_UART0>; + clock-names = "baud", "bus"; status = "disabled"; }; @@ -100,9 +428,201 @@ compatible = "mediatek,mt6572-uart", "mediatek,mt6577-uart"; reg = <0x11006000 0x400>; interrupts = ; - clocks = <&uart_clk>; + clocks = <&topckgen CLK_TOP_UART1_SEL>, <&topckgen CLK_TOP_UART1>; clock-names = "baud"; status = "disabled"; }; + + i2c0: i2c@11009000 { + compatible = "mediatek,mt6572-i2c"; + reg = <0x11009000 0x70>, + <0x11000180 0x80>, + <0x11000200 0x80>; + interrupts = ; + clocks = <&topckgen CLK_TOP_I2C0>, <&topckgen CLK_TOP_APDMA>; + clock-names = "main", "dma"; + clock-div = <12>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@1100a000 { + compatible = "mediatek,mt6572-i2c"; + reg = <0x1100a000 0x70>, + <0x11000280 0x80>, + <0x11000300 0x80>; + interrupts = ; + clocks = <&topckgen CLK_TOP_I2C1>, <&topckgen CLK_TOP_APDMA>; + clock-names = "main", "dma"; + clock-div = <12>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm: pwm@11008000 { + compatible = "mediatek,mt7623-pwm"; + reg = <0x11008000 0x1000>; + #pwm-cells = <2>; + clocks = <&topckgen CLK_TOP_PWM>, <&topckgen CLK_TOP_PWM>, + <&topckgen CLK_TOP_PWM>, <&topckgen CLK_TOP_PWM>, + <&topckgen CLK_TOP_PWM>, <&topckgen CLK_TOP_PWM>, + <&topckgen CLK_TOP_PWM>; + clock-names = "top", "main", + "pwm1", "pwm2", "pwm3", "pwm4", "pwm5"; + status = "disabled"; + }; + + usb: usb@11100000 { + compatible = "mediatek,mt2701-musb", + "mediatek,mtk-musb"; + reg = <0x11100000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + interrupt-names = "mc"; + phys = <&u2port0 PHY_TYPE_USB2>; + dr_mode = "otg"; + clocks = <&topckgen CLK_TOP_USB>, + <&topckgen CLK_TOP_USB>, + <&topckgen CLK_TOP_UNIV_48M_SEL>; + clock-names = "main", "mcu", "univpll"; + status = "disabled"; + }; + + u2phy0: t-phy@11110000 { + compatible = "mediatek,mt2701-tphy", + "mediatek,generic-tphy-v1"; + reg = <0x11110000 0x0700>; + ranges; + #address-cells = <1>; + #size-cells = <1>; + status = "disabled"; + + u2port0: usb-phy@11110800 { + reg = <0x11110800 0x0100>; + clocks = <&topckgen CLK_TOP_UNIV_48M_SEL>; + clock-names = "ref"; + #phy-cells = <1>; + }; + }; + + mmc0: mmc@11120000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; + reg = <0x11120000 0x1000>; + interrupts = ; + clocks = <&topckgen CLK_TOP_MSDC0>, + <&topckgen CLK_TOP_MSDC0_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + + mmc1: mmc@11130000 { + compatible = "mediatek,mt7623-mmc", + "mediatek,mt2701-mmc"; + reg = <0x11130000 0x1000>; + interrupts = ; + clocks = <&topckgen CLK_TOP_MSDC1>, + <&topckgen CLK_TOP_MSDC1_SEL>; + clock-names = "source", "hclk"; + status = "disabled"; + }; + + mfgcfg: syscon@13000000 { + compatible = "mediatek,mt6572-mfgcfg", "syscon"; + reg = <0x13000000 0x1000>; + #clock-cells = <1>; + power-domains = <&spm MT6572_POWER_DOMAIN_MFG>; + }; + + gpu: gpu@13010000 { + compatible = "arm,mali-400"; + reg = <0x13010000 0x10000>; + interrupts = , + , + , + ; + interrupt-names = "gp", + "gpmmu", + "pp0", + "ppmmu0"; + clocks = <&mfgcfg CLK_MFG_BG3D>, <&mfgcfg CLK_MFG_BG3D>; + clock-names = "bus", "core"; + + power-domains = <&spm MT6572_POWER_DOMAIN_MFG>; + resets = <&watchdog MT6572_TOPRGU_MFG_SW_RST>; + }; + + mmsys: syscon@14000000 { + compatible = "mediatek,mt6572-mmsys", "syscon"; + reg = <0x14000000 0x1000>; + #clock-cells = <1>; + }; + + larb0: larb@14010000 { + compatible = "mediatek,mt6572-smi-larb"; + reg = <0x14010000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6572_POWER_DOMAIN_DIS>; + }; + + ovl: ovl@14007000 { + compatible = "mediatek,mt6572-disp-ovl"; + reg = <0x14007000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_DISP_OVL>; + iommus = <&iommu MT6572_M4U_PORT_DISP_OVL>; + }; + + rdma0: rdma@14008000 { + compatible = "mediatek,mt6572-disp-rdma"; + reg = <0x14008000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_DISP_RDMA>; + iommus = <&iommu MT6572_M4U_PORT_LCD_R>; + }; + + bls: pwm@1400a000 { + compatible = "mediatek,mt2701-disp-pwm"; + reg = <0x1400a000 0x1000>; + #pwm-cells = <2>; + clocks = <&mmsys CLK_MM_DISP_MDP_BLS_26M>, + <&mmsys CLK_MM_DISP_BLS>; + clock-names = "main", "mm"; + status = "disabled"; + }; + + color: color@1400b000 { + compatible = "mediatek,mt2701-disp-color"; + reg = <0x1400b000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_DISP_COLOR>; + }; + + dsi: dsi@1400c000 { + compatible = "mediatek,mt6572-dsi"; + reg = <0x1400c000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_DSI_ENGINE>, + <&mmsys CLK_MM_DSI_DIGITAL>, + <&mipi_tx0>; + clock-names = "engine", "digital", "hs"; + phys = <&mipi_tx0>; + phy-names = "dphy"; + status = "disabled"; + }; + + mutex: mutex@1400e000 { + compatible = "mediatek,mt6572-disp-mutex"; + reg = <0x1400e000 0x1000>; + interrupts = ; + clocks = <&mmsys CLK_MM_MUTEX_SLOW_CLOCK>; + }; }; }; diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index fd3a8834fc4fd4..904f76c21bb497 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -49,7 +49,7 @@ static const char * const mediatek_board_dt_compat[] = { NULL, }; -DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)") +DT_MACHINE_START(MEDIATEK_DT, "MediaTek Cortex-A7 (Device Tree)") .dt_compat = mediatek_board_dt_compat, .init_time = mediatek_timer_init, MACHINE_END diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index 6b0943d95555af..ca1a69c7ea8caf 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -6,21 +6,65 @@ * Author: Shunli Wang * Yingjoe Chen */ +#include +#include +#include #include #include #include #include #include #include +#include "../drivers/pmdomain/mediatek/mtk-pm-domains.h" #define MTK_MAX_CPU 8 #define MTK_SMP_REG_SIZE 0x1000 +#ifdef CONFIG_HOTPLUG_CPU +#define SPM_L1_PDN(n) (0x25c + (8 * n)) + +#define SPM_SLEEP_TIMER_STA 0x0720 +#define CPU_SLEEP(n) BIT(15 + n) + +#define L1RSTDISABLE1 BIT(1) + +#define BOOT_SLAVE_CONFIG 0x0000 +#define BOOT_SLAVE_ADDR 0x0004 +#define BOOT_SLAVE_KEY 0x13800000 + +enum mtk_cpu_target_state { + POWER_DOWN, + POWER_UP, +}; + +struct mtk_hotplug_info { + const char *const spm_compat; + const char *const mcusys_compat; + + unsigned int spm_pwr_con[MTK_MAX_CPU - 1]; + unsigned int spm_pwr_status_bits[MTK_MAX_CPU - 1]; + unsigned int spm_l1_pdn_bits[MTK_MAX_CPU - 1]; + unsigned int spm_l1_pdn_ack_bits[MTK_MAX_CPU - 1]; +}; + +static const struct mtk_hotplug_info mtk_mt6572_hotplug = { + .spm_compat = "mediatek,mt6572-scpsys", + .mcusys_compat = "mediatek,mt6572-mcusys", + .spm_pwr_con = { 0x218 }, + .spm_pwr_status_bits = { BIT(11) }, + .spm_l1_pdn_bits = { BIT(0) }, + .spm_l1_pdn_ack_bits = { BIT(8) }, +}; +#endif + struct mtk_smp_boot_info { unsigned long smp_base; unsigned int jump_reg; unsigned int core_keys[MTK_MAX_CPU - 1]; unsigned int core_regs[MTK_MAX_CPU - 1]; +#ifdef CONFIG_HOTPLUG_CPU + const struct mtk_hotplug_info *hotplug; +#endif }; static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = { @@ -33,6 +77,9 @@ static const struct mtk_smp_boot_info mtk_mt6572_boot = { 0x10001400, 0x08, { 0x534c4131 }, { 0x0c }, +#ifdef CONFIG_HOTPLUG_CPU + &mtk_mt6572_hotplug, +#endif }; static const struct mtk_smp_boot_info mtk_mt6589_boot = { @@ -66,16 +113,152 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = { static void __iomem *mtk_smp_base; static const struct mtk_smp_boot_info *mtk_smp_info; +#ifdef CONFIG_HOTPLUG_CPU +static void __iomem *spm_base; +static void __iomem *mcusys_base; + +static void spm_cpu_wait_busy(enum mtk_cpu_target_state state, unsigned int cpu) +{ + u32 val, mask = mtk_smp_info->hotplug->spm_pwr_status_bits[cpu - 1]; + do { + val = readl(spm_base + SPM_PWR_STATUS) & mask; + val |= readl(spm_base + SPM_PWR_STATUS_2ND) & mask; + } while (state == POWER_DOWN ? !!val : !val); +} + +static void spm_l1_wait_busy(enum mtk_cpu_target_state state, unsigned int cpu) +{ + u32 val; + do { + val = readl(spm_base + SPM_L1_PDN(cpu)) & + mtk_smp_info->hotplug->spm_l1_pdn_ack_bits[cpu - 1]; + } while (state == POWER_DOWN ? !val : !!val); +} + +static void spm_ctrl_cpu(enum mtk_cpu_target_state state, unsigned int cpu) +{ + u32 val, pwr_con = mtk_smp_info->hotplug->spm_pwr_con[cpu - 1], + l1_pdn_bits = mtk_smp_info->hotplug->spm_l1_pdn_bits[cpu - 1]; + + switch (state) { + case POWER_DOWN: + while (!(readl(spm_base + SPM_SLEEP_TIMER_STA) & + CPU_SLEEP(cpu))) + ; + + val = readl(spm_base + pwr_con); + val |= PWR_CLK_DIS_BIT | PWR_SRAM_CLKISO_BIT | PWR_ISO_BIT; + writel(val, spm_base + pwr_con); + val = readl(spm_base + pwr_con); + val &= ~(PWR_SRAM_ISOINT_B_BIT | PWR_RST_B_BIT); + writel(val, spm_base + pwr_con); + + val = readl(spm_base + SPM_L1_PDN(cpu)); + val |= l1_pdn_bits; + writel(val, spm_base + SPM_L1_PDN(cpu)); + spm_l1_wait_busy(state, cpu); + + val = readl(spm_base + pwr_con); + val &= ~PWR_ON_BIT; + writel(val, spm_base + pwr_con); + udelay(1); + + val = readl(spm_base + pwr_con); + val &= ~PWR_ON_2ND_BIT; + writel(val, spm_base + pwr_con); + udelay(1); + + spm_cpu_wait_busy(state, cpu); + + break; + case POWER_UP: + val = readl(spm_base + pwr_con); + val |= PWR_ON_BIT; + writel(val, spm_base + pwr_con); + udelay(1); + + val = readl(spm_base + pwr_con); + val |= PWR_ON_2ND_BIT; + writel(val, spm_base + pwr_con); + udelay(3); + + spm_cpu_wait_busy(state, cpu); + + val = readl(spm_base + SPM_L1_PDN(cpu)); + val &= ~l1_pdn_bits; + writel(val, spm_base + SPM_L1_PDN(cpu)); + udelay(1); + spm_l1_wait_busy(state, cpu); + + val = readl(spm_base + pwr_con); + val |= PWR_SRAM_ISOINT_B_BIT; + writel(val, spm_base + pwr_con); + + val = readl(spm_base + pwr_con); + val &= ~(PWR_CLK_DIS_BIT | PWR_ISO_BIT); + writel(val, spm_base + pwr_con); + + val = readl(spm_base + pwr_con); + val |= PWR_CLK_DIS_BIT; + writel(val, spm_base + pwr_con); + + val = readl(spm_base + pwr_con); + val &= ~PWR_SRAM_CLKISO_BIT; + writel(val, spm_base + pwr_con); + + val = readl(mcusys_base); + writel(val | L1RSTDISABLE1, mcusys_base); + dsb(); + + val = readl(spm_base + pwr_con); + val &= ~PWR_CLK_DIS_BIT; + writel(val, spm_base + pwr_con); + dsb(); + + val = readl(spm_base + pwr_con); + val |= PWR_RST_B_BIT; + writel(val, spm_base + pwr_con); + + break; + } +} + +static bool mtk_hotplug_is_available(void) +{ + return spm_base && mcusys_base; +} + +static bool mtk_hotplug_is_off(unsigned int cpu) +{ + u32 val = readl_relaxed(spm_base + SPM_PWR_STATUS); + return !(val & mtk_smp_info->hotplug->spm_pwr_status_bits[cpu - 1]); +} +#endif + static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle) { + u32 val; + if (!mtk_smp_base) return -EINVAL; - if (!mtk_smp_info->core_keys[cpu-1]) + if (!mtk_smp_info->core_keys[cpu - 1]) return -EINVAL; - writel_relaxed(mtk_smp_info->core_keys[cpu-1], - mtk_smp_base + mtk_smp_info->core_regs[cpu-1]); + if (mtk_hotplug_is_available() && mtk_hotplug_is_off(cpu)) { + val = readl(mcusys_base); + writel(val & ~L1RSTDISABLE1, mcusys_base); + + writel(BOOT_SLAVE_KEY | 1, mtk_smp_base + BOOT_SLAVE_CONFIG); + writel(__pa_symbol(secondary_startup_arm), + mtk_smp_base + BOOT_SLAVE_ADDR); + + wmb(); + spm_ctrl_cpu(POWER_UP, cpu); + dsb_sev(); + } else + writel(mtk_smp_info->core_keys[cpu - 1], + mtk_smp_base + mtk_smp_info->core_regs[cpu - 1]); arch_send_wakeup_ipi_mask(cpumask_of(cpu)); @@ -128,6 +311,43 @@ static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone) mtk_smp_base + mtk_smp_info->jump_reg); } +#ifdef CONFIG_HOTPLUG_CPU +static void __mtk_hotplug_prepare(void) +{ + struct device_node *np; + + if (!mtk_smp_info->hotplug || !mtk_smp_info->hotplug->spm_compat || + !mtk_smp_info->hotplug->mcusys_compat) { + pr_err("%s: hotplug data is incomplete, disabling hotplug\n", + __func__); + return; + } + + np = of_find_compatible_node(NULL, NULL, + mtk_smp_info->hotplug->spm_compat); + if (!np) { + pr_err("%s: SPM node not found, hotplug won't be available\n", + __func__); + return; + } + + spm_base = of_iomap(np, 0); + of_node_put(np); + + np = of_find_compatible_node(NULL, NULL, + mtk_smp_info->hotplug->mcusys_compat); + if (!np) { + pr_err("%s: MCUSYS node not found, hotplug won't be available\n", + __func__); + iounmap(spm_base); + return; + } + + mcusys_base = of_iomap(np, 0); + of_node_put(np); +} +#endif + static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus) { __mtk_smp_prepare_cpus(max_cpus, 1); @@ -136,7 +356,38 @@ static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus) static void __init mtk_smp_prepare_cpus(unsigned int max_cpus) { __mtk_smp_prepare_cpus(max_cpus, 0); +#ifdef CONFIG_HOTPLUG_CPU + __mtk_hotplug_prepare(); +#endif +} + +#ifdef CONFIG_HOTPLUG_CPU +static bool mtk_cpu_can_disable(unsigned int cpu) +{ + return mtk_hotplug_is_available() && cpu != 0; +} + +static int mtk_cpu_disable(unsigned int cpu) +{ + if (mtk_cpu_can_disable(cpu)) + return 0; + + return -EPERM; +} + +static void mtk_cpu_die(unsigned int cpu) +{ + v7_exit_coherency_flush(louis); + + while (1) + wfi(); +} +static int mtk_cpu_kill(unsigned int cpu) +{ + spm_ctrl_cpu(POWER_DOWN, cpu); + return 1; } +#endif static const struct smp_operations mt81xx_tz_smp_ops __initconst = { .smp_prepare_cpus = mtk_tz_smp_prepare_cpus, @@ -147,5 +398,11 @@ CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_op static const struct smp_operations mt6589_smp_ops __initconst = { .smp_prepare_cpus = mtk_smp_prepare_cpus, .smp_boot_secondary = mtk_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_can_disable = mtk_cpu_can_disable, + .cpu_disable = mtk_cpu_disable, + .cpu_die = mtk_cpu_die, + .cpu_kill = mtk_cpu_kill, +#endif }; CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops); diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 2c09fd729bab04..4046053284b743 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -124,6 +124,14 @@ config COMMON_CLK_MT2712_VENCSYS help This driver supports MediaTek MT2712 vencsys clocks. +config COMMON_CLK_MT6572 + bool "Clock driver for MediaTek MT6572" + depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK && ARM + help + This driver supports MediaTek MT6572 basic clocks. + config COMMON_CLK_MT6735 tristate "Main clock drivers for MediaTek MT6735" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index d8736a060dbdca..dbf0f07c043a33 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o obj-$(CONFIG_COMMON_CLK_MEDIATEK_FHCTL) += clk-fhctl.o clk-pllfh.o +obj-$(CONFIG_COMMON_CLK_MT6572) += clk-mt6572-topckgen.o clk-mt6572-apmixedsys.o clk-mt6572-infracfg.o clk-mt6572-mm.o clk-mt6572-mfg.o obj-$(CONFIG_COMMON_CLK_MT6735) += clk-mt6735-apmixedsys.o clk-mt6735-infracfg.o clk-mt6735-pericfg.o clk-mt6735-topckgen.o obj-$(CONFIG_COMMON_CLK_MT6735_IMGSYS) += clk-mt6735-imgsys.o obj-$(CONFIG_COMMON_CLK_MT6735_MFGCFG) += clk-mt6735-mfgcfg.o diff --git a/drivers/clk/mediatek/clk-mt6572-apmixedsys.c b/drivers/clk/mediatek/clk-mt6572-apmixedsys.c new file mode 100644 index 00000000000000..88d3d8d6c00c12 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6572-apmixedsys.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "clk-mux.h" +#include +#include + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include + +#define ARMPLL_OFFSET 0x100 +#define MAINPLL_OFFSET 0x120 +#define UNIVPLL_OFFSET 0x140 +#define WHPLL_OFFSET 0x240 + +#define WHPLL_PATHSEL_CON 0x254 +#define RSV_RW0_CON1 0xf04 + +#define REG_CON0 0x0 +#define REG_CON1 0x4 +#define REG_PWR_CON0 0x10 + +#define CON0_RST_BAR BIT(27) + +#define PLL_DIV(_id, _name, _base, _en_mask, _rst_bar_mask, _flags, _fmin, \ + _fmax, _div) \ + { .id = _id, \ + .name = _name, \ + .parent_name = "clk26m", \ + .reg = (_base) + REG_CON0, \ + .pwr_reg = (_base) + REG_PWR_CON0, \ + .en_mask = _en_mask, \ + .rst_bar_mask = _rst_bar_mask, \ + .pd_reg = (_base) + REG_CON1, \ + .pd_shift = 24, \ + .pcw_reg = (_base) + REG_CON1, \ + .pcw_chg_reg = (_base) + REG_CON1, \ + .pcwbits = 21, \ + .flags = _flags, \ + .fmin = _fmin, \ + .fmax = _fmax, \ + .div_table = _div } + +#define PLL_FREQ(_id, _name, _base, _en_mask, _rst_bar_mask, _flags, _fmin, _fmax) \ + PLL_DIV(_id, _name, _base, _en_mask, _rst_bar_mask, _flags, _fmin, _fmax, NULL) + +#define PLL(_id, _name, _base, _en_mask, _rst_bar_mask, _flags) \ + PLL_DIV(_id, _name, _base, _en_mask, _rst_bar_mask, _flags, 0, 0, NULL) + +static const struct mtk_pll_div_table armpll_div_table[] = { + { .div = 0, .freq = 1989 * MHZ }, + { .div = 1, .freq = 1001 * MHZ }, + { .div = 2, .freq = 520 * MHZ }, + { .div = 3, .freq = 260 * MHZ }, + { .div = 4, .freq = 130 * MHZ }, + { /* sentinel */ } +}; + +static const struct mtk_pll_data apmixedsys_plls[] = { + PLL_DIV(CLK_APMIXED_ARMPLL, "armpll", ARMPLL_OFFSET, 0x00000011, 0, + PLL_AO, 1000 * MHZ, 1800 * MHZ, armpll_div_table), + + PLL_FREQ(CLK_APMIXED_MAINPLL, "mainpll", MAINPLL_OFFSET, 0x00000011, + CON0_RST_BAR, PLL_AO | HAVE_RST_BAR, 1000 * MHZ, 1800 * MHZ), + + //PLL_FREQ(CLK_APMIXED_UNIVPLL, "univpll", UNIVPLL_OFFSET, 0x30000011, + // CON0_RST_BAR, HAVE_RST_BAR, 1248 * MHZ, 1248 * MHZ), + + PLL_DIV(CLK_APMIXED_WHPLL, "whpll", WHPLL_OFFSET, 0x00000011, 0, 0, + 754 * MHZ, 1508 * MHZ, armpll_div_table), +}; + +static int clk_mt6572_apmixed_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct clk_hw_onecell_data *clk_data; + int ret; + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + /* + * WHPLL requires WHPLL_PATHSEL_CON and RSV_RW0_CON1 setup to enable + * output. Otherwise the GPU will get 0 Hz and hang. + */ + writel(1, base + WHPLL_PATHSEL_CON); + writel(0xC0000000, base + RSV_RW0_CON1); + + clk_data = mtk_devm_alloc_clk_data(&pdev->dev, ARRAY_SIZE(apmixedsys_plls)); + if (!clk_data) + return -ENOMEM; + platform_set_drvdata(pdev, clk_data); + + ret = mtk_clk_register_plls(&pdev->dev, apmixedsys_plls, + ARRAY_SIZE(apmixedsys_plls), clk_data); + if (ret) { + dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret); + return ret; + } + + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, + clk_data); + if (ret) + dev_err(&pdev->dev, + "Failed to register clock provider: %d\n", ret); + + return ret; +} + +static void clk_mt6572_apmixed_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + + mtk_clk_unregister_plls(apmixedsys_plls, ARRAY_SIZE(apmixedsys_plls), clk_data); +} + +static const struct of_device_id of_match_mt6572_apmixedsys[] = { + { .compatible = "mediatek,mt6572-apmixedsys" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6572_apmixedsys); + +static struct platform_driver clk_mt6572_apmixedsys = { + .probe = clk_mt6572_apmixed_probe, + .remove = clk_mt6572_apmixed_remove, + .driver = { + .name = "clk-mt6572-apmixedsys", + .of_match_table = of_match_mt6572_apmixedsys, + }, +}; +module_platform_driver(clk_mt6572_apmixedsys); + +MODULE_DESCRIPTION("MediaTek MT6572 apmixedsys clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6572-infracfg.c b/drivers/clk/mediatek/clk-mt6572-infracfg.c new file mode 100644 index 00000000000000..1a92294871c36f --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6572-infracfg.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 rva3 + */ + +#include +#include + +#include "clk-mtk.h" + +#include + +static const char * const cpu_mux_parents[] = { + "clk26m", + "armpll", + "univpll", + "mpll_d2" +}; + +static const struct mtk_composite infra_muxes[] = { + MUX(CLK_INFRA_CPUSEL, "cpu_mux", cpu_mux_parents, 0x0, 2, 2), +}; + +static const struct mtk_clk_desc infracfg_clks = { + .composite_clks = infra_muxes, + .num_composite_clks = ARRAY_SIZE(infra_muxes), +}; + +static const struct of_device_id of_match_mt6572_infracfg[] = { + { .compatible = "mediatek,mt6572-infracfg", .data = &infracfg_clks }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6572_infracfg); + +static struct platform_driver clk_mt6572_infracfg = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6572-infracfg", + .of_match_table = of_match_mt6572_infracfg, + }, +}; +module_platform_driver(clk_mt6572_infracfg); + +MODULE_DESCRIPTION("MediaTek MT6572 infracfg clock driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/clk/mediatek/clk-mt6572-mfg.c b/drivers/clk/mediatek/clk-mt6572-mfg.c new file mode 100644 index 00000000000000..75fed991fc4983 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6572-mfg.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mfg_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_MFG(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mfg_clks[] = { + GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0), +}; + +static const struct mtk_clk_desc mfg_desc = { + .clks = mfg_clks, + .num_clks = ARRAY_SIZE(mfg_clks), +}; + +static const struct of_device_id of_match_clk_mt6572_mfg[] = { + { + .compatible = "mediatek,mt6572-mfgcfg", + .data = &mfg_desc, + }, + { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, of_match_clk_mt6572_mfg); + +static struct platform_driver clk_mt6572_mfg_drv = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6572-mfg", + .of_match_table = of_match_clk_mt6572_mfg, + }, +}; +module_platform_driver(clk_mt6572_mfg_drv); + +MODULE_DESCRIPTION("MediaTek MT6572 GPU mfg clocks driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6572-mm.c b/drivers/clk/mediatek/clk-mt6572-mm.c new file mode 100644 index 00000000000000..58e15dc80672cc --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6572-mm.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mm0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +#define GATE_MM0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +#define GATE_MM1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + + +static const struct mtk_gate mm_clks[] = { + GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_smi_src", 0), + GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_smi_src", 1), + GATE_MM0(CLK_MM_CMDQ, "mm_cmdq", "mm_smi_src", 2), + GATE_MM0(CLK_MM_SMI_CMDQ, "mm_smi_cmdq", "mm_smi_src", 3), + GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_smi_src", 4), + GATE_MM0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_smi_src", 5), + GATE_MM0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_smi_src", 6), + GATE_MM0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_smi_src", 7), + GATE_MM0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_smi_src", 8), + GATE_MM0(CLK_MM_DISP_MDP_TDSHP, "mm_mdp_tdshp", "mm_smi_src", 9), + GATE_MM0(CLK_MM_DISP_MDP_WROT, "mm_mdp_wrot", "mm_smi_src", 10), + GATE_MM0(CLK_MM_DISP_MDP_WDMA, "mm_mdp_wdma", "mm_smi_src", 11), + GATE_MM0(CLK_MM_DISP_MDP_RSZ1, "mm_mdp_rsz1", "mm_smi_src", 12), + GATE_MM0(CLK_MM_DISP_MDP_RSZ0, "mm_mdp_rsz0", "mm_smi_src", 13), + GATE_MM0(CLK_MM_DISP_MDP_RDMA, "mm_mdp_rdma", "mm_smi_src", 14), + GATE_MM0(CLK_MM_DISP_MDP_BLS_26M, "mm_mdp_bls_26m", "mm_smi_src", 15), + GATE_MM0(CLK_MM_CAM, "mm_cam", "mm_smi_src", 16), + GATE_MM0(CLK_MM_SENINF, "mm_seninf", "mm_smi_src", 17), + GATE_MM0(CLK_MM_CAMTG, "mm_camtg", "mm_smi_src", 18), + GATE_MM0(CLK_MM_CODEC, "mm_codec", "mm_smi_src", 19), + GATE_MM0(CLK_MM_DISP_FAKE_ENG, "mm_disp_fake_eng", "mm_smi_src", 20), + GATE_MM0(CLK_MM_MUTEX_SLOW_CLOCK, "mm_mutex_slow_clock", "mm_smi_src", 21), + + GATE_MM1(CLK_MM_DSI_ENGINE, "dsi_engine", "mm_smi_src", 0), + GATE_MM1(CLK_MM_DSI_DIGITAL, "dsi_digital", "mm_smi_src", 1), +}; + +static const struct mtk_clk_desc mm_desc = { + .clks = mm_clks, + .num_clks = ARRAY_SIZE(mm_clks), +}; + +static const struct platform_device_id clk_mt6572_mm_id_table[] = { + { .name = "clk-mt6572-mm", .driver_data = (kernel_ulong_t)&mm_desc }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, clk_mt6572_mm_id_table); + +static struct platform_driver clk_mt6572_mm = { + .probe = mtk_clk_pdev_probe, + .remove = mtk_clk_pdev_remove, + .driver = { + .name = "clk-mt6572-mm", + }, + .id_table = clk_mt6572_mm_id_table, +}; +module_platform_driver(clk_mt6572_mm); + +MODULE_DESCRIPTION("MediaTek MT6572 MultiMedia clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6572-topckgen.c b/drivers/clk/mediatek/clk-mt6572-topckgen.c new file mode 100644 index 00000000000000..61fecf53416d0f --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6572-topckgen.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include "clk-gate.h" +#include +#include + +#include "clk-mtk.h" + +#include + +#define CLK_CFG_0 0x00 +#define CLK_CFG_0_SET 0x04 +#define CLK_CFG_0_CLR 0x08 + +static DEFINE_SPINLOCK(mt6572_topckgen_lock); + +static const struct mtk_fixed_clk topckgen_fixed_clks[] = { + FIXED_CLK(CLK_TOP_SC_26M_SEL, "sc_26m_sel", "clk26m", 26 * MHZ), +}; + +static const struct mtk_fixed_factor topckgen_factors[] = { + FACTOR(CLK_TOP_MPLL_D2, "mpll_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_MPLL_D3, "mpll_d3", "mainpll", 1, 3), + FACTOR(CLK_TOP_MPLL_D5, "mpll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_MPLL_D7, "mpll_d7", "mainpll", 1, 7), + FACTOR(CLK_TOP_MPLL_D4, "mpll_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_MPLL_D6, "mpll_d6", "mainpll", 1, 6), + FACTOR(CLK_TOP_MPLL_D10, "mpll_d10", "mainpll", 1, 10), + FACTOR(CLK_TOP_MPLL_D8, "mpll_d8", "mainpll", 1, 8), + FACTOR(CLK_TOP_MPLL_D12, "mpll_d12", "mainpll", 1, 12), + FACTOR(CLK_TOP_MPLL_D20, "mpll_d20", "mainpll", 1, 20), + FACTOR(CLK_TOP_MPLL_D24, "mpll_d24", "mainpll", 1, 24), + + FACTOR(CLK_TOP_UPLL_D2, "upll_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UPLL_D3, "upll_d3", "univpll", 1, 3), + FACTOR(CLK_TOP_UPLL_D5, "upll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UPLL_D7, "upll_d7", "univpll", 1, 7), + FACTOR(CLK_TOP_UPLL_D4, "upll_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_UPLL_D6, "upll_d6", "univpll", 1, 6), + FACTOR(CLK_TOP_UPLL_D10, "upll_d10", "univpll", 1, 10), + FACTOR(CLK_TOP_UPLL_D8, "upll_d8", "univpll", 1, 8), + FACTOR(CLK_TOP_UPLL_D12, "upll_d12", "univpll", 1, 12), + FACTOR(CLK_TOP_UPLL_D20, "upll_d20", "univpll", 1, 20), + FACTOR(CLK_TOP_UPLL_D16, "upll_d16", "univpll", 1, 16), + FACTOR(CLK_TOP_UPLL_D24, "upll_d24", "univpll", 1, 24), + + FACTOR(CLK_TOP_UNIV_48M_SEL, "univ_48m", "univpll", 1, 26), +}; + +static const char * const uart_sel_parents[] = { + "clk26m", + "upll_d24" +}; + +static const char * const emi2x_sel_parents[] = { + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "mpll_d3", + "mpll_d4", + "clk26m", + "mpll_d2" +}; + +static const char * const axi_sel_parents[] = { + "clk26m", + "clk26m", + "mpll_d10", + "clk26m", + "mpll_d12" +}; + +static const char *const mfg_mux_parents[] = { + "mfg_pre_491m", // 3'b000: 491.52 MHz + "mfg_pre_500m", // 3'b001: 500.5 MHz (whpll) + "mpll_d3", // 3'b010: "mainpll output clock divided by 3 (designed for DDR 533MHz case)" from datasheet suggests this one should be mpll_d3, and previous one is some fixed clock? mainpll rate depends on the DRAM type... + "upll_d2", // 3'b011: 624 MHz (upll is 1248 MHz) + "clk26m", // 3'b1x0: 26 MHz + "mpll_d2", // 3'b1x1: "mainpll output clock divided by 2 (designed for DDR 663MHz case)" from datasheet suggests this one should be mpll_d2, and previous one is some fixed clock? mainpll rate depends on the DRAM type... + "clk26m", // 3'b1x0: 26 MHz + "mpll_d2", // 3'b1x1: "mainpll output clock divided by 2 (designed for DDR 663MHz case)" from datasheet suggests this one should be mpll_d2, and previous one is some fixed clock? mainpll rate depends on the DRAM type... +}; + +static const char *const mfg_gf_parents[] = { + "upll_d3", // 0 = 416 MHz + "mfg_mux_sel" // 1 = the mux +}; + +static const char * const msdc0_sel_parents[] = { + "mpll_d12", + "mpll_d10", + "mpll_d8", + "upll_d7", + "mpll_d7", + "mpll_d8", + "clk26m", + "upll_d6" +}; + +static const char * const spi_nand_sel_parents[] = { + "mpll_d24", + "mpll_d20", + "upll_d20", + "upll_d16", + "upll_d12", + "upll_d10", + "mpll_d12", + "mpll_d10", +}; + +static const char * const cam_sel_parents[] = { + "univ_48m", + "upll_d6" +}; + +static const char * const pwm_mm_sel_parents[] = { + "clk26m", + "upll_d12" +}; + +static const char * const msdc1_sel_parents[] = { + "mpll_d12", + "mpll_d10", + "mpll_d8", + "upll_d7", + "mpll_d7", + "mpll_d8", + "clk26m", + "upll_d6" +}; + +static const char * const spm_52m_sel_parents[] = { + "clk26m", + "upll_d24" +}; + +static const char * const pmic_spi_sel_ddr2_parents[] = { + "mpll_d24", + "univ_48m", + "upll_d16", + "clk26m" +}; + +static const char * const pmic_spi_sel_ddr3_parents[] = { + "mpll_d20", + "univ_48m", + "upll_d16", + "clk26m" +}; + +static const char * const audio_intbus_sel_ddr2_parents[] = { + "clk26m", + "clk26m", + "mpll_d24", + "clk26m", + "mpll_d12" +}; + +static const char * const audio_intbus_sel_ddr3_parents[] = { + "clk26m", + "clk26m", + "mpll_d20", + "clk26m", + "mpll_d10" +}; + +static const char * const spinfi_pre_sel_parents[] = { + "clk26m", + "spinfi_sel" +}; + +static const struct mtk_composite topckgen_ddr2_muxes[] = { + MUX(CLK_TOP_PMIC_SPI_SEL, "pmic_spi_sel", pmic_spi_sel_ddr2_parents, CLK_CFG_0, 24, 2), + MUX(CLK_TOP_AUDIO_INTBUS_SEL, "audio_intbus_sel", audio_intbus_sel_ddr2_parents, CLK_CFG_0, 27, 3), +}; + +static const struct mtk_composite topckgen_ddr3_muxes[] = { + MUX(CLK_TOP_PMIC_SPI_SEL, "pmic_spi_sel", pmic_spi_sel_ddr3_parents, CLK_CFG_0, 24, 2), + MUX(CLK_TOP_AUDIO_INTBUS_SEL, "audio_intbus_sel", audio_intbus_sel_ddr3_parents, CLK_CFG_0, 27, 3), +}; + +static const struct mtk_composite topckgen_muxes[] = { + MUX(CLK_TOP_UART0_SEL, "uart0_sel", uart_sel_parents, CLK_CFG_0, 0, 1), + MUX_FLAGS(CLK_TOP_EMI2X_SEL, "emi2x_sel", emi2x_sel_parents, CLK_CFG_0, + 1, 4, CLK_IS_CRITICAL), + MUX_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_sel_parents, CLK_CFG_0, 5, 3, + CLK_IS_CRITICAL), + MUX_FLAGS(CLK_TOP_MFG_MUX_SEL, "mfg_mux_sel", mfg_mux_parents, CLK_CFG_0, + 8, 3, CLK_SET_RATE_PARENT), + MUX(CLK_TOP_MSDC0_SEL, "msdc0_sel", msdc0_sel_parents, CLK_CFG_0, 11, + 3), + MUX(CLK_TOP_SPINFI_SEL, "spinfi_sel", spi_nand_sel_parents, CLK_CFG_0, + 14, 3), + MUX(CLK_TOP_CAM_SEL, "cam_sel", cam_sel_parents, CLK_CFG_0, 17, 1), + MUX(CLK_TOP_PWM_MM_SEL, "pwm_mm_sel", pwm_mm_sel_parents, CLK_CFG_0, 18, + 1), + MUX(CLK_TOP_UART1_SEL, "uart1_sel", uart_sel_parents, CLK_CFG_0, 19, 1), + MUX(CLK_TOP_MSDC1_SEL, "msdc1_sel", msdc1_sel_parents, CLK_CFG_0, 20, + 3), + MUX_FLAGS(CLK_TOP_SPM_52M_SEL, "spm_52m_sel", spm_52m_sel_parents, + CLK_CFG_0, 23, 1, CLK_IS_CRITICAL), + MUX(CLK_TOP_SPINFI_PRE_SEL, "spinfi_pre_sel", spinfi_pre_sel_parents, + CLK_CFG_0, 30, 1), + MUX_FLAGS(CLK_TOP_MFG_SEL, "mfg_sel", mfg_gf_parents, CLK_CFG_0, 31, 1, + CLK_SET_RATE_PARENT), +}; + +static const struct mtk_gate_regs top0_cg_regs = { + .sta_ofs = 0x20, + .set_ofs = 0x50, + .clr_ofs = 0x80, +}; + +static const struct mtk_gate_regs top1_cg_regs = { + .sta_ofs = 0x24, + .set_ofs = 0x54, + .clr_ofs = 0x84, +}; + +#define GATE_TOP0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_TOP0_INV(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &top0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + +#define GATE_TOP1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate top_ddr2_clks[] = { + GATE_TOP0(CLK_TOP_DBI_BCLK, "dbi_bclk", "mpll_d12", 5), +}; + +static const struct mtk_gate top_ddr3_clks[] = { + GATE_TOP0(CLK_TOP_DBI_BCLK, "dbi_bclk", "mpll_d10", 5), +}; + +static const struct mtk_gate top_clks[] = { + GATE_TOP0(CLK_TOP_PWM_MM, "pwm_mm", "pwm_mm_sel", 0), + GATE_TOP0(CLK_TOP_CAM_MM, "cam_mm", "cam_sel", 1), + GATE_TOP0(CLK_TOP_MFG_MM, "mfg_mm", "mfg_mux_sel", 2), + GATE_TOP0(CLK_TOP_SPM_52M, "spm_52m", "spm_52m_sel", 3), + GATE_TOP0_INV(CLK_TOP_MIPI_26M_DBG, "mipi_26m_dbg", "clk26m", 4), + GATE_TOP0_INV(CLK_TOP_SC_26M, "sc_26m", "clk26m", 6), + GATE_TOP0_INV(CLK_TOP_SC_MEM, "sc_mem", "clk26m", 7), // unk parent + GATE_TOP0(CLK_TOP_DBI_PAD0, "dbi_pad0", "dbi_bclk", 16), + GATE_TOP0(CLK_TOP_DBI_PAD1, "dbi_pad1", "dbi_bclk", 17), + GATE_TOP0(CLK_TOP_DBI_PAD2, "dbi_pad2", "dbi_bclk", 18), + GATE_TOP0(CLK_TOP_DBI_PAD3, "dbi_pad3", "dbi_bclk", 19), + GATE_TOP0_INV(CLK_TOP_MFG_PRE_491M, "mfg_pre_491m", "mpll_d3", 20), // unk parent, but i tend to think it's mainpll/3 + GATE_TOP0_INV(CLK_TOP_MFG_PRE_500M, "mfg_pre_500m", "whpll", 21), + GATE_TOP0_INV(CLK_TOP_ARMDCM, "armdcm", "clk26m", 31), // unk parent + + GATE_TOP1(CLK_TOP_EFUSE, "efuse", "clk26m", 0), + GATE_TOP1(CLK_TOP_THERMAL, "thermal", "clk26m", 1), + GATE_TOP1(CLK_TOP_APDMA, "apdma", "axi_sel", 2), + GATE_TOP1(CLK_TOP_I2C0, "i2c0", "axi_sel", 3), + GATE_TOP1(CLK_TOP_I2C1, "i2c1", "axi_sel", 4), + GATE_TOP1(CLK_TOP_NFI, "nfi", "axi_sel", 6), + GATE_TOP1(CLK_TOP_NFI_ECC, "nfi_ecc", "axi_sel", 7), + GATE_TOP1(CLK_TOP_DEBUGSYS, "debugsys", "axi_sel", 8), + GATE_TOP1(CLK_TOP_PWM, "pwm", "axi_sel", 9), + GATE_TOP1(CLK_TOP_UART0, "uart0", "uart0_sel", 10), + GATE_TOP1(CLK_TOP_UART1, "uart1", "uart1_sel", 11), + GATE_TOP1(CLK_TOP_BTIF, "btif", "axi_sel", 12), + GATE_TOP1(CLK_TOP_USB, "usb", "axi_sel", 13), + GATE_TOP1(CLK_TOP_FHCTL, "fhctl", "clk26m", 14), + GATE_TOP1(CLK_TOP_SPINFI, "spinfi", "spinfi_sel", 16), + GATE_TOP1(CLK_TOP_MSDC0, "msdc0", "msdc0_sel", 17), + GATE_TOP1(CLK_TOP_MSDC1, "msdc1", "msdc1_sel", 18), + GATE_TOP1(CLK_TOP_PMIC_WRAP, "pmic_wrap", "pmic_spi_sel", 20), + GATE_TOP1(CLK_TOP_SEJ, "sej", "clk26m", 21), // MT_CG_SYS_26M, AXIBUS, let it be clk26m + GATE_TOP1(CLK_TOP_MEMSLP_DLYER, "memslp_dlyer", "clk26m", 22), // unk parent + GATE_TOP1(CLK_TOP_APXGPT, "apxgpt", "clk26m", 24), + GATE_TOP1(CLK_TOP_AUDIO, "audio", "audio_intbus_sel", 25), + GATE_TOP1(CLK_TOP_SPM, "spm", "clk26m", 26), + GATE_TOP1(CLK_TOP_PMIC_SPI, "pmic_spi", "clk26m", 29), + GATE_TOP1(CLK_TOP_AUXADC, "auxadc", "clk26m", 30), +}; + +static int clk_mt6572_topckgen_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct clk_hw_onecell_data *clk_data; + struct clk_hw *hw; + void __iomem *base; + bool is_ddr3; + int ret; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + is_ddr3 = !(readl(base + CLK_CFG_0) & BIT(7)); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + if (!clk_data) + return -ENOMEM; + + mtk_clk_register_fixed_clks(topckgen_fixed_clks, + ARRAY_SIZE(topckgen_fixed_clks), clk_data); + mtk_clk_register_factors(topckgen_factors, ARRAY_SIZE(topckgen_factors), + clk_data); + mtk_clk_register_composites(dev, topckgen_muxes, + ARRAY_SIZE(topckgen_muxes), base, + &mt6572_topckgen_lock, clk_data); + mtk_clk_register_gates(dev, node, top_clks, ARRAY_SIZE(top_clks), + clk_data); + + if (is_ddr3) { + mtk_clk_register_composites(dev, topckgen_ddr3_muxes, + ARRAY_SIZE(topckgen_ddr3_muxes), + base, &mt6572_topckgen_lock, + clk_data); + mtk_clk_register_gates(dev, node, top_ddr3_clks, + ARRAY_SIZE(top_ddr3_clks), clk_data); + hw = clk_hw_register_fixed_factor(NULL, "mm_smi_src", "mainpll", + 0, 1, 5); + } else { + mtk_clk_register_composites(dev, topckgen_ddr2_muxes, + ARRAY_SIZE(topckgen_ddr2_muxes), + base, &mt6572_topckgen_lock, + clk_data); + mtk_clk_register_gates(dev, node, top_ddr2_clks, + ARRAY_SIZE(top_ddr2_clks), clk_data); + hw = clk_hw_register_fixed_factor(NULL, "mm_smi_src", "mainpll", + 0, 1, 6); + } + + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + dev_err(dev, "failed to register mm_smi_src clock: %d", ret); + goto free_data; + } + + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + if (ret) { + dev_err(dev, "failed to register clock provider: %d\n", ret); + goto free_data; + } + + return 0; + +free_data: + mtk_free_clk_data(clk_data); + return ret; +} + +static const struct mtk_clk_desc topckgen_desc = { + .fixed_clks = topckgen_fixed_clks, + .num_fixed_clks = ARRAY_SIZE(topckgen_fixed_clks), + .factor_clks = topckgen_factors, + .num_factor_clks = ARRAY_SIZE(topckgen_factors), + .clks = top_clks, + .num_clks = ARRAY_SIZE(top_clks), + .composite_clks = topckgen_muxes, + .num_composite_clks = ARRAY_SIZE(topckgen_muxes), + .clk_lock = &mt6572_topckgen_lock, +}; + +static const struct of_device_id of_match_mt6572_topckgen[] = { + { .compatible = "mediatek,mt6572-topckgen" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6572_topckgen); + +static struct platform_driver clk_mt6572_topckgen = { + .probe = clk_mt6572_topckgen_probe, + .driver = { + .name = "clk-mt6572-topckgen", + .of_match_table = of_match_mt6572_topckgen, + }, +}; +module_platform_driver(clk_mt6572_topckgen); + +MODULE_DESCRIPTION("MediaTek MT6572 topckgen clock driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c index 7bcb4a3f26fb0e..7de34cace572f6 100644 --- a/drivers/clocksource/timer-mediatek.c +++ b/drivers/clocksource/timer-mediatek.c @@ -22,6 +22,8 @@ #define TIMER_SYNC_TICKS (3) +#define TIMER_SYSCNT (6) + /* gpt */ #define GPT_IRQ_EN_REG 0x00 #define GPT_IRQ_ENABLE(val) BIT((val) - 1) @@ -335,6 +337,9 @@ static int __init mtk_gpt_init(struct device_node *node) mtk_gpt_enable_irq(&to, TIMER_CLK_EVT); + /* Configure GPT6 to feed arch timer */ + mtk_gpt_setup(&to, TIMER_SYSCNT, GPT_CTRL_OP_FREERUN); + return 0; } TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init); diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 052ca7cd2f4fd8..8854dd807b8f44 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ struct mtk_cpu_dvfs_info { const struct mtk_cpufreq_platform_data *soc_data; int vtrack_max; bool ccifreq_bound; + int opp_token; }; static struct platform_device *cpufreq_pdev; @@ -383,9 +385,15 @@ static struct device *of_get_cci(struct device *cpu_dev) static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) { + struct nvmem_cell *speedbin_cell; + struct dev_pm_opp_config config; struct device *cpu_dev; + struct device_node *np; struct dev_pm_opp *opp; unsigned long rate; + u32 opp_hw_ver; + u8 *speedbin; + size_t len; int ret; cpu_dev = get_cpu_device(cpu); @@ -450,6 +458,40 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) } } + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); + if (!np) + goto no_speedbin; + + speedbin_cell = of_nvmem_cell_get(np, "speedbin"); + of_node_put(np); + + if (IS_ERR(speedbin_cell)) + goto no_speedbin; + + speedbin = nvmem_cell_read(speedbin_cell, &len); + nvmem_cell_put(speedbin_cell); + + if (IS_ERR(speedbin)) { + ret = PTR_ERR(speedbin); + dev_err_probe(cpu_dev, ret, "cpu%d: failed to read speedbin\n", cpu); + goto out_disable_sram_reg; + } + + /* Convert the raw value to a bitmask */ + opp_hw_ver = BIT(*speedbin); + kfree(speedbin); + + config.supported_hw = &opp_hw_ver; + config.supported_hw_count = 1; + + info->opp_token = dev_pm_opp_set_config(cpu_dev, &config); + if (info->opp_token < 0) { + ret = info->opp_token; + dev_err_probe(cpu_dev, ret, "cpu%d: failed to set OPP config\n", cpu); + goto out_disable_sram_reg; + } + +no_speedbin: /* Get OPP-sharing information from "operating-points-v2" bindings */ ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus); if (ret) { @@ -573,6 +615,10 @@ static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info) clk_disable_unprepare(info->inter_clk); clk_put(info->inter_clk); dev_pm_opp_of_cpumask_remove_table(&info->cpus); + + if (info->opp_token > 0) + dev_pm_opp_clear_config(info->opp_token); + dev_pm_opp_unregister_notifier(info->cpu_dev, &info->opp_nb); if (info->soc_data->ccifreq_supported) put_device(info->cci_dev); @@ -691,6 +737,14 @@ static const struct mtk_cpufreq_platform_data mt2701_platform_data = { .ccifreq_supported = false, }; +static const struct mtk_cpufreq_platform_data mt6572_platform_data = { + .min_volt_shift = 100000, + .max_volt_shift = 200000, + .proc_max_volt = 1250000, + .sram_min_volt = 0, + .ccifreq_supported = false, +}; + static const struct mtk_cpufreq_platform_data mt7622_platform_data = { .min_volt_shift = 100000, .max_volt_shift = 200000, @@ -747,6 +801,7 @@ static const struct mtk_cpufreq_platform_data mt8516_platform_data = { static const struct of_device_id mtk_cpufreq_machines[] __initconst __maybe_unused = { { .compatible = "mediatek,mt2701", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt2712", .data = &mt2701_platform_data }, + { .compatible = "mediatek,mt6572", .data = &mt6572_platform_data }, { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data }, { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data }, { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data }, diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 300de30fd92021..364f832c2fbb28 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -5338,7 +5338,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) guard(srcu)(&desc->gdev->desc_srcu); flags = READ_ONCE(desc->flags); is_irq = test_bit(GPIOD_FLAG_USED_AS_IRQ, &flags); - if (is_irq || test_bit(GPIOD_FLAG_REQUESTED, &flags)) { + if (is_irq || test_bit(GPIOD_FLAG_REQUESTED, &flags) || true) { gpiod_get_direction(desc); is_out = test_bit(GPIOD_FLAG_IS_OUT, &flags); value = gpio_chip_get_value(gc, desc); diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c index bc8fb4e38d0a72..1f59c19d0957c4 100644 --- a/drivers/gpu/drm/lima/lima_devfreq.c +++ b/drivers/gpu/drm/lima/lima_devfreq.c @@ -9,9 +9,11 @@ #include #include #include +#include #include #include #include +#include #include "lima_device.h" #include "lima_devfreq.h" @@ -102,6 +104,40 @@ void lima_devfreq_fini(struct lima_device *ldev) } } +static int lima_devfreq_set_opp_config(struct device *dev) +{ + struct dev_pm_opp_config config = {}; + struct nvmem_cell *cell; + u8 *speedbin; + size_t len; + u32 opp_hw_ver; + int ret; + + cell = nvmem_cell_get(dev, "speedbin"); + if (IS_ERR(cell)) + /* Optional, continue without speedbin restriction */ + return 0; + + speedbin = nvmem_cell_read(cell, &len); + nvmem_cell_put(cell); + + if (IS_ERR(speedbin)) + /* Optional, continue without speedbin restriction */ + return 0; + + opp_hw_ver = BIT(*speedbin); + kfree(speedbin); + + config.supported_hw = &opp_hw_ver; + config.supported_hw_count = 1; + + ret = devm_pm_opp_set_config(dev, &config); + if (ret) + dev_err(dev, "Failed to set OPP config\n"); + + return ret; +} + int lima_devfreq_init(struct lima_device *ldev) { struct thermal_cooling_device *cooling; @@ -134,6 +170,10 @@ int lima_devfreq_init(struct lima_device *ldev) return ret; } + ret = lima_devfreq_set_opp_config(dev); + if (ret) + return ret; + ret = devm_pm_opp_of_add_table(dev); if (ret) return ret; diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index e0236353d4997e..5ac8e9b907dba9 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -20,9 +20,21 @@ #include "mtk_disp_drv.h" #include "mtk_drm_drv.h" -#define DISP_REG_OVL_INTEN 0x0004 -#define OVL_FME_CPL_INT BIT(1) +#define DISP_REG_OVL_INTEN 0x0004 +#define OVL_FME_CPL_INT BIT(1) +#define OVL_FME_UND_INT BIT(2) +#define OVL_RDMA0_EOF_ABNORMAL_INT BIT(5) +#define OVL_RDMA1_EOF_ABNORMAL_INT BIT(6) +#define OVL_RDMA0_FIFO_UND_INT BIT(9) +#define OVL_RDMA1_FIFO_UND_INT BIT(10) + #define DISP_REG_OVL_INTSTA 0x0008 +#define OVL_FME_UND BIT(2) +#define OVL_RDMA0_EOF_ABNORMAL BIT(5) +#define OVL_RDMA1_EOF_ABNORMAL BIT(6) +#define OVL_RDMA0_FIFO_UND BIT(9) +#define OVL_RDMA1_FIFO_UND BIT(10) + #define DISP_REG_OVL_EN 0x000c #define DISP_REG_OVL_RST 0x0014 #define DISP_REG_OVL_ROI_SIZE 0x0020 @@ -170,6 +182,18 @@ struct mtk_disp_ovl { static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) { struct mtk_disp_ovl *priv = dev_id; + u32 reg = readl(priv->regs + DISP_REG_OVL_INTSTA); + + if (reg & OVL_FME_UND) + pr_err("OVL: OVL frame underflow\n"); + if (reg & OVL_RDMA0_EOF_ABNORMAL) + pr_err("OVL: RDMA0 didn't complete frame\n"); + if (reg & OVL_RDMA1_EOF_ABNORMAL) + pr_err("OVL: RDMA1 didn't complete frame\n"); + if (reg & OVL_RDMA0_FIFO_UND) + pr_err("OVL: RDMA0 FIFO underflow\n"); + if (reg & OVL_RDMA1_FIFO_UND) + pr_err("OVL: RDMA1 FIFO underflow\n"); /* Clear frame completion interrupt */ writel(0x0, priv->regs + DISP_REG_OVL_INTSTA); @@ -205,7 +229,10 @@ void mtk_ovl_enable_vblank(struct device *dev) struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); - writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); + writel_relaxed(OVL_FME_CPL_INT | OVL_FME_UND_INT | + OVL_RDMA0_EOF_ABNORMAL_INT | OVL_RDMA1_EOF_ABNORMAL_INT | + OVL_RDMA0_FIFO_UND_INT | OVL_RDMA1_FIFO_UND_INT, + ovl->regs + DISP_REG_OVL_INTEN); } void mtk_ovl_disable_vblank(struct device *dev) @@ -671,6 +698,19 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .num_formats = ARRAY_SIZE(mt8173_formats), }; +static const struct mtk_disp_ovl_data mt6572_ovl_driver_data = { + .addr = DISP_REG_OVL_ADDR_MT2701, + .gmc_bits = 10, + .layer_nr = 4, + .fmt_rgb565_is_0 = false, + .supports_afbc = false, + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE), + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), +}; + static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .addr = DISP_REG_OVL_ADDR_MT8173, .gmc_bits = 8, @@ -742,6 +782,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-ovl", .data = &mt2701_ovl_driver_data}, + { .compatible = "mediatek,mt6572-disp-ovl", + .data = &mt6572_ovl_driver_data}, { .compatible = "mediatek,mt8173-disp-ovl", .data = &mt8173_ovl_driver_data}, { .compatible = "mediatek,mt8183-disp-ovl", diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index c9d41d75e7f2a3..691978d4f1cb83 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -36,6 +36,10 @@ #define DISP_REG_RDMA_SIZE_CON_1 0x0018 #define DISP_REG_RDMA_TARGET_LINE 0x001c #define DISP_RDMA_MEM_CON 0x0024 + +#define MEM_MODE_INPUT_FORMAT_RGB565_MT65XX (0x004 << 4) +#define MEM_MODE_INPUT_FORMAT_RGB888_MT65XX (0x008 << 4) + #define MEM_MODE_INPUT_FORMAT_RGB565 (0x000 << 4) #define MEM_MODE_INPUT_FORMAT_RGB888 (0x001 << 4) #define MEM_MODE_INPUT_FORMAT_RGBA8888 (0x002 << 4) @@ -72,6 +76,9 @@ struct mtk_disp_rdma_data { unsigned int fifo_size; const u32 *formats; size_t num_formats; + u32 size_con0; + u32 size_con1; + unsigned int (*fmt_convert)(unsigned int fmt); }; /* @@ -191,9 +198,9 @@ void mtk_rdma_config(struct device *dev, unsigned int width, u32 rdma_fifo_size; mtk_ddp_write_mask(cmdq_pkt, width, &rdma->cmdq_reg, rdma->regs, - DISP_REG_RDMA_SIZE_CON_0, 0xfff); + DISP_REG_RDMA_SIZE_CON_0, rdma->data->size_con0); mtk_ddp_write_mask(cmdq_pkt, height, &rdma->cmdq_reg, rdma->regs, - DISP_REG_RDMA_SIZE_CON_1, 0xfffff); + DISP_REG_RDMA_SIZE_CON_1, rdma->data->size_con1); if (rdma->fifo_size) rdma_fifo_size = rdma->fifo_size; @@ -213,8 +220,43 @@ void mtk_rdma_config(struct device *dev, unsigned int width, mtk_ddp_write(cmdq_pkt, reg, &rdma->cmdq_reg, rdma->regs, DISP_REG_RDMA_FIFO_CON); } -static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma, - unsigned int fmt) +static unsigned int rdma_fmt_convert_mt65xx(unsigned int fmt) +{ + /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" + * is defined in mediatek HW data sheet. + * The alphabet order in XXX is no relation to data + * arrangement in memory. + */ + switch (fmt) { + default: + case DRM_FORMAT_RGB565: + return MEM_MODE_INPUT_FORMAT_RGB565_MT65XX; + case DRM_FORMAT_BGR565: + return MEM_MODE_INPUT_FORMAT_RGB565_MT65XX | MEM_MODE_INPUT_SWAP; + case DRM_FORMAT_RGB888: + return MEM_MODE_INPUT_FORMAT_RGB888_MT65XX; + case DRM_FORMAT_BGR888: + return MEM_MODE_INPUT_FORMAT_RGB888_MT65XX | MEM_MODE_INPUT_SWAP; + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_RGBA8888: + return MEM_MODE_INPUT_FORMAT_ARGB8888; + case DRM_FORMAT_BGRX8888: + case DRM_FORMAT_BGRA8888: + return MEM_MODE_INPUT_FORMAT_ARGB8888 | MEM_MODE_INPUT_SWAP; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + return MEM_MODE_INPUT_FORMAT_RGBA8888; + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + return MEM_MODE_INPUT_FORMAT_RGBA8888 | MEM_MODE_INPUT_SWAP; + case DRM_FORMAT_UYVY: + return MEM_MODE_INPUT_FORMAT_UYVY; + case DRM_FORMAT_YUYV: + return MEM_MODE_INPUT_FORMAT_YUYV; + } +} + +static unsigned int rdma_fmt_convert(unsigned int fmt) { /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" * is defined in mediatek HW data sheet. @@ -266,7 +308,7 @@ void mtk_rdma_layer_config(struct device *dev, unsigned int idx, unsigned int fmt = pending->format; unsigned int con; - con = rdma_fmt_convert(rdma, fmt); + con = rdma->data->fmt_convert(fmt); mtk_ddp_write_relaxed(cmdq_pkt, con, &rdma->cmdq_reg, rdma->regs, DISP_RDMA_MEM_CON); if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) { @@ -380,29 +422,52 @@ static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = { .fifo_size = SZ_4K, .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), + .size_con0 = 0xfff, + .size_con1 = 0xfffff, + .fmt_convert = rdma_fmt_convert, +}; + +static const struct mtk_disp_rdma_data mt6572_rdma_driver_data = { + .fifo_size = 3840, + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), + .size_con0 = 0, + .size_con1 = 0, + .fmt_convert = rdma_fmt_convert_mt65xx, }; static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = { .fifo_size = SZ_8K, .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), + .size_con0 = 0xfff, + .size_con1 = 0xfffff, + .fmt_convert = rdma_fmt_convert, }; static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = { .fifo_size = 5 * SZ_1K, .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), + .size_con0 = 0xfff, + .size_con1 = 0xfffff, + .fmt_convert = rdma_fmt_convert, }; static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = { .fifo_size = 1920, .formats = mt8173_formats, .num_formats = ARRAY_SIZE(mt8173_formats), + .size_con0 = 0xfff, + .size_con1 = 0xfffff, + .fmt_convert = rdma_fmt_convert, }; static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-rdma", .data = &mt2701_rdma_driver_data}, + { .compatible = "mediatek,mt6572-disp-rdma", + .data = &mt6572_rdma_driver_data}, { .compatible = "mediatek,mt8173-disp-rdma", .data = &mt8173_rdma_driver_data}, { .compatible = "mediatek,mt8183-disp-rdma", diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index a94c51a8326162..6ad1be86019ce2 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -333,6 +333,8 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = { static const struct of_device_id mtk_drm_of_ids[] = { { .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data}, + { .compatible = "mediatek,mt6572-mmsys", + .data = &mt2701_mmsys_driver_data}, { .compatible = "mediatek,mt7623-mmsys", .data = &mt7623_mmsys_driver_data}, { .compatible = "mediatek,mt2712-mmsys", @@ -752,6 +754,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt2712-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, + { .compatible = "mediatek,mt6572-disp-mutex", + .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8167-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8173-disp-mutex", @@ -772,6 +776,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_OD }, { .compatible = "mediatek,mt2701-disp-ovl", .data = (void *)MTK_DISP_OVL }, + { .compatible = "mediatek,mt6572-disp-ovl", + .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8167-disp-ovl", .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8173-disp-ovl", @@ -796,6 +802,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_PWM }, { .compatible = "mediatek,mt2701-disp-rdma", .data = (void *)MTK_DISP_RDMA }, + { .compatible = "mediatek,mt6572-disp-rdma", + .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8167-disp-rdma", .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8173-disp-rdma", @@ -828,6 +836,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DPI }, { .compatible = "mediatek,mt2701-dsi", .data = (void *)MTK_DSI }, + { .compatible = "mediatek,mt6572-dsi", + .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8173-dsi", .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8183-dsi", diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index aaf6c9ebd319f7..5e6e83d17b6431 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -712,6 +712,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi) goto err_disable_engine_clk; } + mtk_dsi_set_cmd_mode(dsi); mtk_dsi_enable(dsi); if (dsi->driver_data->has_shadow_ctl) @@ -1245,6 +1246,7 @@ static int mtk_dsi_probe(struct platform_device *pdev) if (ret < 0) return dev_err_probe(dev, ret, "Failed to register DSI host\n"); + writel(0, dsi->regs + DSI_INTSTA); ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq, IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi); if (ret) { @@ -1278,6 +1280,13 @@ static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = { .reg_shadow_dbg_off = 0x190 }; +static const struct mtk_dsi_driver_data mt6572_dsi_driver_data = { + .reg_cmdq_off = 0x180, + .reg_vm_cmd_off = 0x130, + .has_shadow_ctl = false, + .has_size_ctl = false, +}; + static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = { .reg_cmdq_off = 0x200, .reg_vm_cmd_off = 0x130, @@ -1306,6 +1315,7 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = { static const struct of_device_id mtk_dsi_of_match[] = { { .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data }, + { .compatible = "mediatek,mt6572-dsi", .data = &mt6572_dsi_driver_data }, { .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data }, { .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data }, { .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data }, diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 307152ad77591a..7039ad35396690 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -605,6 +605,16 @@ config DRM_PANEL_ORISETECH_OTM8009A Say Y here if you want to enable support for Orise Technology otm8009a 480x800 dsi 2dl panel. +config DRM_PANEL_ORISETECH_OTM8018B + tristate "Orise Technology otm8018b 480x854 dsi panel" + depends on OF + depends on DRM_MIPI_DSI + help + Say Y here if you want to enable support for Orise Technology + otm8018b 480x854 dsi panel as found on the Prestigio PAP5500 DUO + (boyi variant). Bootloader runs the full Orise CMD2 init; this + driver only does sleep-exit + display-on. + config DRM_PANEL_OSD_OSD101T2587_53TS tristate "OSD OSD101T2587-53TS DSI 1920x1200 video mode panel" depends on OF @@ -1214,6 +1224,15 @@ config DRM_PANEL_WIDECHIPS_WS2401 480x800 display controller used in panels such as Samsung LMS380KF01. This display is used in the Samsung Galaxy Ace 2 GT-I8160 (Codina). +config DRM_PANEL_WSVGALNL_EK79007 + tristate "WSVGALNL EK79007 DSI panel driver" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the WSVGALNL EK79007 DSI + 1024x600 LCD panel + config DRM_PANEL_XINPENG_XPP055C272 tristate "Xinpeng XPP055C272 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index aeffaa95666d6d..95cf47f2f3c189 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o obj-$(CONFIG_DRM_PANEL_ORISETECH_OTA5601A) += panel-orisetech-ota5601a.o obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o +obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8018B) += panel-orisetech-otm8018b.o obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o @@ -120,4 +121,5 @@ obj-$(CONFIG_DRM_PANEL_VISIONOX_RM692E5) += panel-visionox-rm692e5.o obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o obj-$(CONFIG_DRM_PANEL_VISIONOX_R66451) += panel-visionox-r66451.o obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o +obj-$(CONFIG_DRM_PANEL_WSVGALNL_EK79007) += panel-wsvgalnl-ek79007.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c index 18aa6222b0c557..51339abf8c2232 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c @@ -192,14 +192,15 @@ static int ili9806e_dsi_probe(struct mipi_dsi_device *dsi) dsi->mode_flags = ctx->desc->mode_flags; dsi->format = ctx->desc->format; dsi->lanes = ctx->desc->lanes; + dsi->channel = 2; ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation); if (ret) return dev_err_probe(dev, ret, "Failed to get orientation\n"); - ret = drm_panel_of_backlight(&ctx->panel); - if (ret) - return dev_err_probe(dev, ret, "Failed to get backlight\n"); + //ret = drm_panel_of_backlight(&ctx->panel); + //if (ret) + // return dev_err_probe(dev, ret, "Failed to get backlight\n"); ctx->panel.prepare_prev_first = true; drm_panel_add(&ctx->panel); @@ -378,6 +379,156 @@ static const struct panel_desc com35h3p70ulc_desc = { .lanes = 2, }; +static void n402_init(struct mipi_dsi_multi_context *ctx) +{ + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x10); + mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x02); + mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x02); + mipi_dsi_dcs_write_seq_multi(ctx, 0x60, 0x07); + mipi_dsi_dcs_write_seq_multi(ctx, 0x61, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0x62, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0x63, 0x04); + mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x14); + mipi_dsi_dcs_write_seq_multi(ctx, 0x41, 0x44); + mipi_dsi_dcs_write_seq_multi(ctx, 0x42, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x43, 0x89); + mipi_dsi_dcs_write_seq_multi(ctx, 0x44, 0x89); + mipi_dsi_dcs_write_seq_multi(ctx, 0x45, 0x1b); + mipi_dsi_dcs_write_seq_multi(ctx, 0x46, 0x44); + mipi_dsi_dcs_write_seq_multi(ctx, 0x47, 0x44); + mipi_dsi_dcs_write_seq_multi(ctx, 0x50, 0x85); + mipi_dsi_dcs_write_seq_multi(ctx, 0x51, 0x85); + mipi_dsi_dcs_write_seq_multi(ctx, 0x52, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x64); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa0, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa1, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa2, 0x03); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa3, 0x0e); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa4, 0x08); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa5, 0x1f); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa6, 0x0f); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa7, 0x0b); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa8, 0x03); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa9, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0xa9, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0xab, 0x02); + mipi_dsi_dcs_write_seq_multi(ctx, 0xac, 0x0e); + mipi_dsi_dcs_write_seq_multi(ctx, 0xad, 0x25); + mipi_dsi_dcs_write_seq_multi(ctx, 0xae, 0x1d); + mipi_dsi_dcs_write_seq_multi(ctx, 0xaf, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc0, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc1, 0x04); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc2, 0x0f); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc3, 0x10); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc4, 0x0b); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc5, 0x1e); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc6, 0x09); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc7, 0x0a); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc8, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xc9, 0x0a); + mipi_dsi_dcs_write_seq_multi(ctx, 0xca, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0xcb, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0xcc, 0x09); + mipi_dsi_dcs_write_seq_multi(ctx, 0xcd, 0x2a); + mipi_dsi_dcs_write_seq_multi(ctx, 0xce, 0x28); + mipi_dsi_dcs_write_seq_multi(ctx, 0xcf, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x06); + mipi_dsi_dcs_write_seq_multi(ctx, 0x00, 0xa0); + mipi_dsi_dcs_write_seq_multi(ctx, 0x01, 0x05); + mipi_dsi_dcs_write_seq_multi(ctx, 0x02, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x03, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x04, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x05, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x88); + mipi_dsi_dcs_write_seq_multi(ctx, 0x07, 0x04); + mipi_dsi_dcs_write_seq_multi(ctx, 0x08, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x09, 0x90); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0a, 0x04); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0b, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0c, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0d, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0e, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x0f, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x10, 0x55); + mipi_dsi_dcs_write_seq_multi(ctx, 0x11, 0x50); + mipi_dsi_dcs_write_seq_multi(ctx, 0x12, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x13, 0x85); + mipi_dsi_dcs_write_seq_multi(ctx, 0x14, 0x85); + mipi_dsi_dcs_write_seq_multi(ctx, 0x15, 0xc0); + mipi_dsi_dcs_write_seq_multi(ctx, 0x16, 0x0b); + mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x19, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x1a, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x1b, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x1c, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x1d, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x20, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x21, 0x23); + mipi_dsi_dcs_write_seq_multi(ctx, 0x22, 0x45); + mipi_dsi_dcs_write_seq_multi(ctx, 0x23, 0x67); + mipi_dsi_dcs_write_seq_multi(ctx, 0x24, 0x01); + mipi_dsi_dcs_write_seq_multi(ctx, 0x25, 0x23); + mipi_dsi_dcs_write_seq_multi(ctx, 0x26, 0x45); + mipi_dsi_dcs_write_seq_multi(ctx, 0x27, 0x67); + mipi_dsi_dcs_write_seq_multi(ctx, 0x30, 0x02); + mipi_dsi_dcs_write_seq_multi(ctx, 0x31, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x32, 0x11); + mipi_dsi_dcs_write_seq_multi(ctx, 0x33, 0xaa); + mipi_dsi_dcs_write_seq_multi(ctx, 0x34, 0xbb); + mipi_dsi_dcs_write_seq_multi(ctx, 0x35, 0x66); + mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0x37, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x38, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x39, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3b, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3c, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3d, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3e, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x3f, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x40, 0x22); + mipi_dsi_dcs_write_seq_multi(ctx, 0x53, 0x1a); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x07); + mipi_dsi_dcs_write_seq_multi(ctx, 0x18, 0x1d); + mipi_dsi_dcs_write_seq_multi(ctx, 0x17, 0x12); + mipi_dsi_dcs_write_seq_multi(ctx, 0x02, 0x77); + mipi_dsi_dcs_write_seq_multi(ctx, 0xe1, 0x79); + mipi_dsi_dcs_write_seq_multi(ctx, 0x06, 0x13); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x00); + + mipi_dsi_dcs_write_seq_multi(ctx, 0x3a, 0x77); + mipi_dsi_dcs_write_seq_multi(ctx, 0x36, 0x00); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x08); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x08); + mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x08); +} + +static const struct drm_display_mode n402_default_mode = { + .clock = 30000, + .hdisplay = 480, + .hsync_start = 480 + 28, + .hsync_end = 480 + 28 + 1, + .htotal = 480 + 28 + 1 + 1, + .vdisplay = 800, + .vsync_start = 800 + 80, + .vsync_end = 800 + 80 + 40, + .vtotal = 800 + 80 + 40 + 40, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static const struct panel_desc n402_desc = { + .init_sequence = n402_init, + .display_mode = &n402_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, + .format = MIPI_DSI_FMT_RGB888, + .lanes = 2, +}; + static void dmt028vghmcmi_1d_init(struct mipi_dsi_multi_context *ctx) { mipi_dsi_dcs_write_seq_multi(ctx, 0xff, 0xff, 0x98, 0x06, 0x04, 0x01); @@ -544,6 +695,7 @@ static const struct panel_desc dmt028vghmcmi_1d_desc = { static const struct of_device_id ili9806e_of_match[] = { { .compatible = "densitron,dmt028vghmcmi-1d", .data = &dmt028vghmcmi_1d_desc }, + { .compatible = "eastaeon,n402", .data = &n402_desc }, { .compatible = "ortustech,com35h3p70ulc", .data = &com35h3p70ulc_desc }, { } }; diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8018b.c b/drivers/gpu/drm/panel/panel-orisetech-otm8018b.c new file mode 100644 index 00000000000000..6a5a843eff701d --- /dev/null +++ b/drivers/gpu/drm/panel/panel-orisetech-otm8018b.c @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include + +#include