From 04c1822c0aeadcda064b0f9490f130a5d1316e27 Mon Sep 17 00:00:00 2001 From: "Raziel K. Crowe" <84860158+CWDSYSTEMS@users.noreply.github.com> Date: Tue, 15 Mar 2022 21:13:23 +0500 Subject: [PATCH] There is a moose on the mool buff Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! --- .../accessibility/speakup/speakup_acntpc.c | 2 +- drivers/accessibility/speakup/speakup_dtlk.c | 2 +- drivers/accessibility/speakup/speakup_keypc.c | 2 +- drivers/accessibility/speakup/spk_ttyio.c | 4 +- drivers/acpi/Kconfig | 45 +- drivers/acpi/Makefile | 4 +- drivers/acpi/ac.c | 43 +- drivers/acpi/acpi_apd.c | 13 +- drivers/acpi/acpi_lpss.c | 13 +- drivers/acpi/acpi_pnp.c | 2 + drivers/acpi/acpi_video.c | 5 +- drivers/acpi/acpica/acevents.h | 5 - drivers/acpi/acpica/acobject.h | 1 - drivers/acpi/acpica/actables.h | 8 +- drivers/acpi/acpica/dsopcode.c | 1 - drivers/acpi/acpica/evhandler.c | 2 +- drivers/acpi/acpica/evregion.c | 10 - drivers/acpi/acpica/evrgnini.c | 52 - drivers/acpi/acpica/exconfig.c | 2 +- drivers/acpi/acpica/excreate.c | 1 - drivers/acpi/acpica/exregion.c | 15 +- drivers/acpi/acpica/tbdata.c | 93 +- drivers/acpi/acpica/tbfadt.c | 6 +- drivers/acpi/acpica/tbinstal.c | 15 +- drivers/acpi/acpica/tbprint.c | 3 +- drivers/acpi/acpica/tbutils.c | 2 +- drivers/acpi/acpica/tbxfload.c | 52 +- drivers/acpi/acpica/utosi.c | 1 - drivers/acpi/apei/einj.c | 18 +- drivers/acpi/apei/ghes.c | 2 +- drivers/acpi/apei/hest.c | 5 +- drivers/acpi/battery.c | 42 +- drivers/acpi/bus.c | 2 - drivers/acpi/cppc_acpi.c | 211 +- drivers/acpi/device_pm.c | 57 +- drivers/acpi/device_sysfs.c | 3 +- drivers/acpi/dock.c | 11 +- drivers/acpi/dptf/dptf_pch_fivr.c | 3 +- drivers/acpi/dptf/dptf_power.c | 2 - drivers/acpi/dptf/int340x_thermal.c | 6 - drivers/acpi/ec.c | 297 +- drivers/acpi/ec_sys.c | 2 +- drivers/acpi/fan.h | 1 - drivers/acpi/glue.c | 41 +- drivers/acpi/internal.h | 12 +- drivers/acpi/nfit/core.c | 4 +- drivers/acpi/numa/srat.c | 64 +- drivers/acpi/pci_link.c | 12 +- drivers/acpi/pci_root.c | 173 +- drivers/acpi/pmic/intel_pmic.c | 14 +- drivers/acpi/pmic/intel_pmic.h | 8 +- drivers/acpi/pmic/intel_pmic_bxtwc.c | 3 +- drivers/acpi/pmic/intel_pmic_bytcrc.c | 3 +- drivers/acpi/pmic/intel_pmic_chtcrc.c | 3 +- drivers/acpi/pmic/intel_pmic_chtdc_ti.c | 3 +- drivers/acpi/pmic/intel_pmic_chtwc.c | 3 +- drivers/acpi/pmic/intel_pmic_xpower.c | 24 +- drivers/acpi/power.c | 28 +- drivers/acpi/pptt.c | 67 - drivers/acpi/prmt.c | 35 +- drivers/acpi/processor_driver.c | 10 +- drivers/acpi/processor_idle.c | 19 +- drivers/acpi/processor_thermal.c | 13 +- drivers/acpi/property.c | 14 +- drivers/acpi/resource.c | 4 +- drivers/acpi/scan.c | 176 +- drivers/acpi/sleep.c | 55 +- drivers/acpi/spcr.c | 9 +- drivers/acpi/sysfs.c | 3 +- drivers/acpi/tables.c | 95 +- drivers/acpi/thermal.c | 11 +- drivers/acpi/video_detect.c | 84 +- drivers/acpi/x86/s2idle.c | 4 +- drivers/acpi/x86/utils.c | 189 - drivers/android/binder.c | 339 +- drivers/ata/Kconfig | 44 +- drivers/ata/acard-ahci.c | 4 + drivers/ata/ahci.c | 37 +- drivers/ata/ahci.h | 8 +- drivers/ata/ahci_brcm.c | 4 +- drivers/ata/ahci_ceva.c | 2 +- drivers/ata/ahci_qoriq.c | 4 + drivers/ata/ahci_xgene.c | 12 +- drivers/ata/ata_piix.c | 19 +- drivers/ata/libahci.c | 85 +- drivers/ata/libahci_platform.c | 14 +- drivers/ata/libata-acpi.c | 69 +- drivers/ata/libata-core.c | 307 +- drivers/ata/libata-eh.c | 72 +- drivers/ata/libata-pmp.c | 8 + drivers/ata/libata-sata.c | 34 +- drivers/ata/libata-scsi.c | 251 +- drivers/ata/libata-sff.c | 88 +- drivers/ata/libata-trace.c | 47 - drivers/ata/libata-transport.c | 48 +- drivers/ata/libata.h | 5 +- drivers/ata/pata_ali.c | 8 +- drivers/ata/pata_amd.c | 2 +- drivers/ata/pata_arasan_cf.c | 3 - drivers/ata/pata_atp867x.c | 105 +- drivers/ata/pata_cmd640.c | 2 +- drivers/ata/pata_cmd64x.c | 4 +- drivers/ata/pata_cs5520.c | 4 +- drivers/ata/pata_cs5536.c | 4 +- drivers/ata/pata_cypress.c | 2 +- drivers/ata/pata_ep93xx.c | 1 + drivers/ata/pata_falcon.c | 16 +- drivers/ata/pata_hpt366.c | 5 +- drivers/ata/pata_hpt37x.c | 20 +- drivers/ata/pata_hpt3x2n.c | 12 +- drivers/ata/pata_it821x.c | 66 +- drivers/ata/pata_ixp4xx_cf.c | 6 +- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_marvell.c | 9 +- drivers/ata/pata_netcell.c | 5 +- drivers/ata/pata_octeon_cf.c | 54 +- drivers/ata/pata_of_platform.c | 15 +- drivers/ata/pata_optidma.c | 4 +- drivers/ata/pata_pdc2027x.c | 71 +- drivers/ata/pata_pdc202xx_old.c | 2 + drivers/ata/pata_platform.c | 2 - drivers/ata/pata_radisys.c | 4 +- drivers/ata/pata_rz1000.c | 4 +- drivers/ata/pata_serverworks.c | 4 +- drivers/ata/pata_sil680.c | 9 +- drivers/ata/pata_via.c | 12 + drivers/ata/pdc_adma.c | 33 +- drivers/ata/sata_dwc_460ex.c | 165 +- drivers/ata/sata_fsl.c | 224 +- drivers/ata/sata_gemini.c | 4 +- drivers/ata/sata_highbank.c | 4 +- drivers/ata/sata_inic162x.c | 4 +- drivers/ata/sata_mv.c | 134 +- drivers/ata/sata_nv.c | 58 +- drivers/ata/sata_promise.c | 31 +- drivers/ata/sata_qstor.c | 15 +- drivers/ata/sata_rcar.c | 26 +- drivers/ata/sata_sil.c | 1 + drivers/ata/sata_sil24.c | 7 +- drivers/ata/sata_sx4.c | 148 +- drivers/atm/iphase.c | 4 +- drivers/auxdisplay/Kconfig | 12 +- drivers/auxdisplay/Makefile | 1 - drivers/auxdisplay/cfag12864bfb.c | 9 +- drivers/auxdisplay/charlcd.c | 2 +- drivers/auxdisplay/ht16k33.c | 501 +- drivers/auxdisplay/img-ascii-lcd.c | 217 +- drivers/auxdisplay/ks0108.c | 3 + drivers/auxdisplay/lcd2s.c | 24 +- drivers/base/Kconfig | 11 - drivers/base/Makefile | 2 +- drivers/base/arch_numa.c | 54 +- drivers/base/arch_topology.c | 62 +- drivers/base/auxiliary.c | 152 +- drivers/base/bus.c | 4 +- drivers/base/component.c | 1 + drivers/base/core.c | 48 +- drivers/base/dd.c | 7 +- drivers/base/devtmpfs.c | 10 +- drivers/base/firmware_loader/builtin/Makefile | 8 +- drivers/base/firmware_loader/fallback.c | 7 +- drivers/base/firmware_loader/fallback.h | 11 - drivers/base/firmware_loader/fallback_table.c | 25 +- drivers/base/firmware_loader/firmware.h | 17 - drivers/base/firmware_loader/main.c | 66 +- drivers/base/node.c | 12 +- drivers/base/platform-msi.c | 234 +- drivers/base/platform.c | 12 +- drivers/base/power/main.c | 6 +- drivers/base/power/power.h | 7 +- drivers/base/power/runtime.c | 63 +- drivers/base/power/trace.c | 6 +- drivers/base/power/wakeirq.c | 101 +- drivers/base/property.c | 225 +- drivers/base/regmap/regmap-debugfs.c | 2 +- drivers/base/regmap/regmap-mdio.c | 6 +- drivers/base/regmap/regmap-spi.c | 36 +- drivers/base/regmap/regmap.c | 1 - drivers/base/swnode.c | 6 + drivers/base/test/test_async_driver_probe.c | 14 +- drivers/base/topology.c | 38 +- drivers/bcma/host_pci.c | 6 +- drivers/bcma/main.c | 2 +- drivers/block/Kconfig | 37 +- drivers/block/Makefile | 2 + drivers/block/amiflop.c | 12 +- drivers/block/aoe/aoeblk.c | 19 +- drivers/block/aoe/aoecmd.c | 2 +- drivers/block/ataflop.c | 35 +- drivers/block/brd.c | 95 +- drivers/block/drbd/drbd_int.h | 5 +- drivers/block/drbd/drbd_main.c | 8 +- drivers/block/drbd/drbd_protocol.h | 6 +- drivers/block/drbd/drbd_receiver.c | 3 +- drivers/block/drbd/drbd_req.c | 3 +- drivers/block/floppy.c | 50 +- drivers/block/loop.c | 468 +- drivers/block/loop.h | 30 + drivers/block/mtip32xx/mtip32xx.c | 94 +- drivers/block/n64cart.c | 26 +- drivers/block/nbd.c | 196 +- drivers/block/null_blk/main.c | 196 +- drivers/block/null_blk/null_blk.h | 6 - drivers/block/paride/bpck.c | 1 - drivers/block/paride/pcd.c | 317 +- drivers/block/paride/pd.c | 154 +- drivers/block/paride/pf.c | 255 +- drivers/block/pktcdvd.c | 336 +- drivers/block/ps3disk.c | 8 +- drivers/block/ps3vram.c | 14 +- drivers/block/rbd.c | 19 +- drivers/block/rnbd/rnbd-clt-sysfs.c | 3 +- drivers/block/rnbd/rnbd-clt.c | 25 +- drivers/block/rnbd/rnbd-clt.h | 2 +- drivers/block/rnbd/rnbd-srv.c | 16 +- drivers/block/rnbd/rnbd-srv.h | 2 +- drivers/block/sunvdc.c | 33 +- drivers/block/swim.c | 37 +- drivers/block/swim3.c | 7 +- drivers/block/sx8.c | 19 +- drivers/block/virtio_blk.c | 202 +- drivers/block/xen-blkback/xenbus.c | 4 +- drivers/block/xen-blkfront.c | 98 +- drivers/block/z2ram.c | 8 +- drivers/block/zram/zram_drv.c | 131 +- drivers/bluetooth/Kconfig | 6 - drivers/bluetooth/Makefile | 1 - drivers/bluetooth/btintel.c | 263 +- drivers/bluetooth/btintel.h | 11 - drivers/bluetooth/btmrvl_main.c | 8 +- drivers/bluetooth/btmtksdio.c | 523 +- drivers/bluetooth/btqca.c | 48 - drivers/bluetooth/btqca.h | 2 - drivers/bluetooth/btrsi.c | 1 + drivers/bluetooth/btrtl.c | 26 +- drivers/bluetooth/btsdio.c | 2 - drivers/bluetooth/btusb.c | 548 ++- drivers/bluetooth/hci_bcm.c | 1 + drivers/bluetooth/hci_h5.c | 7 +- drivers/bluetooth/hci_ldisc.c | 10 +- drivers/bluetooth/hci_qca.c | 5 +- drivers/bluetooth/hci_vhci.c | 226 - drivers/bus/Kconfig | 2 +- drivers/bus/brcmstb_gisb.c | 9 +- drivers/bus/fsl-mc/Makefile | 3 +- drivers/bus/fsl-mc/dprc-driver.c | 8 +- drivers/bus/fsl-mc/fsl-mc-allocator.c | 9 +- drivers/bus/fsl-mc/fsl-mc-msi.c | 79 +- drivers/bus/fsl-mc/fsl-mc-private.h | 39 +- drivers/bus/imx-weim.c | 18 +- drivers/bus/mhi/core/boot.c | 2 +- drivers/bus/mhi/core/init.c | 3 +- drivers/bus/mhi/core/internal.h | 9 +- drivers/bus/mhi/core/main.c | 24 +- drivers/bus/mhi/core/pm.c | 4 +- drivers/bus/mhi/pci_generic.c | 54 +- drivers/bus/mvebu-mbus.c | 5 - drivers/bus/sun50i-de2.c | 7 +- drivers/bus/tegra-gmi.c | 50 +- drivers/bus/ti-sysc.c | 102 +- drivers/cdrom/cdrom.c | 86 +- drivers/cdrom/gdrom.c | 8 +- drivers/clk/Kconfig | 27 +- drivers/clk/Makefile | 6 +- drivers/clk/actions/owl-factor.c | 1 + drivers/clk/at91/at91rm9200.c | 2 +- drivers/clk/at91/at91sam9260.c | 2 +- drivers/clk/at91/at91sam9g45.c | 2 +- drivers/clk/at91/at91sam9n12.c | 2 +- drivers/clk/at91/at91sam9rl.c | 2 +- drivers/clk/at91/at91sam9x5.c | 2 +- drivers/clk/at91/clk-generated.c | 46 +- drivers/clk/at91/clk-main.c | 66 - drivers/clk/at91/clk-master.c | 467 +- drivers/clk/at91/clk-peripheral.c | 40 +- drivers/clk/at91/clk-pll.c | 39 - drivers/clk/at91/clk-programmable.c | 29 +- drivers/clk/at91/clk-sam9x60-pll.c | 170 +- drivers/clk/at91/clk-system.c | 20 - drivers/clk/at91/clk-usb.c | 27 - drivers/clk/at91/clk-utmi.c | 39 - drivers/clk/at91/dt-compat.c | 2 +- drivers/clk/at91/pmc.c | 177 +- drivers/clk/at91/pmc.h | 29 +- drivers/clk/at91/sam9x60.c | 6 +- drivers/clk/at91/sama5d2.c | 2 +- drivers/clk/at91/sama5d3.c | 2 +- drivers/clk/at91/sama5d4.c | 2 +- drivers/clk/at91/sama7g5.c | 18 +- drivers/clk/clk-composite.c | 70 +- drivers/clk/clk-gate.c | 35 - drivers/clk/clk-si5351.c | 8 +- drivers/clk/clk-si5351.h | 2 +- drivers/clk/clk-stm32mp1.c | 2 + drivers/clk/clk-versaclock5.c | 4 +- drivers/clk/clk.c | 67 +- drivers/clk/imx/Kconfig | 7 - drivers/clk/imx/Makefile | 2 - drivers/clk/imx/clk-composite-7ulp.c | 88 +- drivers/clk/imx/clk-composite-8m.c | 4 +- drivers/clk/imx/clk-imx6ul.c | 7 +- drivers/clk/imx/clk-imx7ulp.c | 20 +- drivers/clk/imx/clk-imx8mp.c | 2 +- drivers/clk/imx/clk-pfdv2.c | 23 +- drivers/clk/imx/clk-pllv1.c | 19 +- drivers/clk/imx/clk-pllv3.c | 6 +- drivers/clk/imx/clk-pllv4.c | 35 +- drivers/clk/imx/clk.h | 457 +- drivers/clk/ingenic/jz4725b-cgu.c | 2 +- drivers/clk/ingenic/jz4740-cgu.c | 2 +- drivers/clk/ingenic/jz4760-cgu.c | 12 +- drivers/clk/ingenic/jz4770-cgu.c | 7 +- drivers/clk/ingenic/jz4780-cgu.c | 2 +- drivers/clk/ingenic/x1000-cgu.c | 2 +- drivers/clk/ingenic/x1830-cgu.c | 2 +- drivers/clk/mediatek/Kconfig | 45 +- drivers/clk/mediatek/Makefile | 12 - drivers/clk/mediatek/clk-apmixed.c | 3 - drivers/clk/mediatek/clk-cpumux.c | 3 - drivers/clk/mediatek/clk-gate.c | 32 +- drivers/clk/mediatek/clk-mt6779-aud.c | 4 +- drivers/clk/mediatek/clk-mt6779-cam.c | 4 +- drivers/clk/mediatek/clk-mt6779-img.c | 4 +- drivers/clk/mediatek/clk-mt6779-ipe.c | 4 +- drivers/clk/mediatek/clk-mt6779-mfg.c | 4 +- drivers/clk/mediatek/clk-mt6779-mm.c | 4 +- drivers/clk/mediatek/clk-mt6779-vdec.c | 4 +- drivers/clk/mediatek/clk-mt6779-venc.c | 4 +- drivers/clk/mediatek/clk-mt6779.c | 2 - drivers/clk/mediatek/clk-mtk.c | 29 +- drivers/clk/mediatek/clk-mtk.h | 1 - drivers/clk/mediatek/clk-mux.c | 6 - drivers/clk/mediatek/clk-pll.c | 6 +- drivers/clk/mediatek/reset.c | 2 - drivers/clk/meson/meson8b.c | 163 +- drivers/clk/meson/meson8b.h | 26 +- drivers/clk/qcom/Kconfig | 67 +- drivers/clk/qcom/Makefile | 6 - drivers/clk/qcom/a53-pll.c | 4 +- drivers/clk/qcom/clk-alpha-pll.c | 166 +- drivers/clk/qcom/clk-alpha-pll.h | 3 - drivers/clk/qcom/clk-rpmh.c | 52 - drivers/clk/qcom/clk-smd-rpm.c | 150 +- drivers/clk/qcom/common.c | 8 +- drivers/clk/qcom/dispcc-sm8250.c | 27 +- drivers/clk/qcom/gcc-msm8953.c | 1 + drivers/clk/qcom/gcc-msm8994.c | 1303 +++-- drivers/clk/qcom/gcc-msm8998.c | 1149 +++-- drivers/clk/qcom/gcc-sc7280.c | 85 + drivers/clk/qcom/gcc-sdm660.c | 80 +- drivers/clk/qcom/gcc-sm6350.c | 1 - drivers/clk/qcom/gcc-sm8350.c | 1 - drivers/clk/qcom/gdsc.c | 51 +- drivers/clk/qcom/gdsc.h | 2 - drivers/clk/qcom/gpucc-msm8998.c | 13 +- drivers/clk/qcom/gpucc-sdm660.c | 15 +- drivers/clk/qcom/kpss-xcc.c | 4 +- drivers/clk/qcom/lpasscc-sdm845.c | 1 - drivers/clk/qcom/mmcc-apq8084.c | 1 - drivers/clk/qcom/mmcc-msm8998.c | 183 +- drivers/clk/qcom/mmcc-sdm660.c | 75 +- drivers/clk/qcom/q6sstop-qcs404.c | 1 - drivers/clk/qcom/turingcc-qcs404.c | 1 - drivers/clk/qcom/videocc-sm8250.c | 27 +- drivers/clk/renesas/Kconfig | 13 +- drivers/clk/renesas/Makefile | 2 - drivers/clk/renesas/r8a774a1-cpg-mssr.c | 12 +- drivers/clk/renesas/r8a774b1-cpg-mssr.c | 12 +- drivers/clk/renesas/r8a774c0-cpg-mssr.c | 9 +- drivers/clk/renesas/r8a774e1-cpg-mssr.c | 12 +- drivers/clk/renesas/r8a7795-cpg-mssr.c | 13 +- drivers/clk/renesas/r8a7796-cpg-mssr.c | 13 +- drivers/clk/renesas/r8a77965-cpg-mssr.c | 13 +- drivers/clk/renesas/r8a77980-cpg-mssr.c | 3 +- drivers/clk/renesas/r8a77990-cpg-mssr.c | 9 +- drivers/clk/renesas/r8a77995-cpg-mssr.c | 3 +- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 158 +- drivers/clk/renesas/r9a07g044-cpg.c | 164 +- drivers/clk/renesas/rcar-cpg-lib.c | 288 +- drivers/clk/renesas/rcar-cpg-lib.h | 14 +- drivers/clk/renesas/rcar-gen3-cpg.c | 113 +- drivers/clk/renesas/rcar-gen3-cpg.h | 4 - drivers/clk/renesas/renesas-cpg-mssr.c | 60 +- drivers/clk/renesas/renesas-cpg-mssr.h | 3 +- drivers/clk/renesas/rzg2l-cpg.c | 213 - drivers/clk/renesas/rzg2l-cpg.h | 54 +- drivers/clk/rockchip/Kconfig | 4 +- drivers/clk/rockchip/clk-rk3399.c | 19 +- drivers/clk/rockchip/clk-rk3568.c | 4 + drivers/clk/samsung/Kconfig | 30 +- drivers/clk/samsung/Makefile | 3 - drivers/clk/samsung/clk-cpu.c | 20 +- drivers/clk/samsung/clk-cpu.h | 7 + drivers/clk/samsung/clk-exynos-audss.c | 4 +- drivers/clk/samsung/clk-exynos3250.c | 54 +- drivers/clk/samsung/clk-exynos4.c | 41 +- drivers/clk/samsung/clk-exynos4412-isp.c | 4 +- drivers/clk/samsung/clk-exynos5250.c | 21 +- drivers/clk/samsung/clk-exynos5420.c | 29 +- drivers/clk/samsung/clk-exynos5433.c | 124 +- drivers/clk/samsung/clk-pll.c | 197 - drivers/clk/samsung/clk-pll.h | 3 - drivers/clk/samsung/clk-s3c2410.c | 6 +- drivers/clk/samsung/clk-s3c64xx.c | 8 +- drivers/clk/samsung/clk-s5pv210-audss.c | 4 +- drivers/clk/samsung/clk-s5pv210.c | 8 +- drivers/clk/samsung/clk.c | 16 +- drivers/clk/samsung/clk.h | 60 +- drivers/clk/socfpga/clk-agilex.c | 4 +- drivers/clk/socfpga/clk-gate.c | 4 +- drivers/clk/socfpga/clk-pll-s10.c | 2 +- drivers/clk/socfpga/clk-s10.c | 4 +- drivers/clk/st/clkgen-fsyn.c | 13 +- drivers/clk/st/clkgen-mux.c | 11 +- drivers/clk/sunxi-ng/Kconfig | 50 +- drivers/clk/sunxi-ng/Makefile | 101 +- drivers/clk/sunxi-ng/ccu-sun4i-a10.c | 58 +- drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c | 5 +- drivers/clk/sunxi-ng/ccu-sun50i-a100.c | 5 +- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 12 +- drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 2 + drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 56 +- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 12 +- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 33 +- drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 40 +- drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 35 +- drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 40 +- drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 12 +- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 13 +- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 62 +- drivers/clk/sunxi-ng/ccu-sun8i-h3.h | 2 + drivers/clk/sunxi-ng/ccu-sun8i-r.c | 65 +- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 11 +- drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 57 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c | 12 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c | 11 +- drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 12 +- drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c | 40 +- drivers/clk/sunxi-ng/ccu_common.c | 15 +- drivers/clk/sunxi-ng/ccu_div.c | 1 - drivers/clk/sunxi-ng/ccu_div.h | 78 - drivers/clk/sunxi-ng/ccu_frac.c | 6 - drivers/clk/sunxi-ng/ccu_gate.c | 4 - drivers/clk/sunxi-ng/ccu_gate.h | 32 +- drivers/clk/sunxi-ng/ccu_mp.c | 2 - drivers/clk/sunxi-ng/ccu_mp.h | 49 - drivers/clk/sunxi-ng/ccu_mult.c | 1 - drivers/clk/sunxi-ng/ccu_mux.c | 6 - drivers/clk/sunxi-ng/ccu_mux.h | 34 +- drivers/clk/sunxi-ng/ccu_nk.c | 1 - drivers/clk/sunxi-ng/ccu_nkm.c | 1 - drivers/clk/sunxi-ng/ccu_nkmp.c | 1 - drivers/clk/sunxi-ng/ccu_nm.c | 1 - drivers/clk/sunxi-ng/ccu_phase.c | 1 - drivers/clk/sunxi-ng/ccu_reset.c | 1 - drivers/clk/sunxi-ng/ccu_sdm.c | 6 - drivers/clk/sunxi/clk-mod0.c | 4 +- drivers/clk/sunxi/clk-sun6i-apb0-gates.c | 4 +- drivers/clk/sunxi/clk-sun6i-apb0.c | 4 +- drivers/clk/sunxi/clk-sun6i-ar100.c | 4 +- drivers/clk/sunxi/clk-sun8i-apb0.c | 4 +- drivers/clk/tegra/Makefile | 1 - drivers/clk/tegra/clk-pll.c | 2 +- drivers/clk/tegra/clk-super.c | 2 +- drivers/clk/tegra/clk-tegra114.c | 2 +- drivers/clk/tegra/clk-tegra20.c | 77 +- drivers/clk/tegra/clk-tegra30.c | 118 +- drivers/clk/tegra/clk.c | 75 +- drivers/clk/tegra/clk.h | 2 - drivers/clk/ti/adpll.c | 2 +- drivers/clk/ti/clk-43xx.c | 1 - drivers/clk/uniphier/clk-uniphier-core.c | 17 - drivers/clk/uniphier/clk-uniphier-sys.c | 47 - drivers/clk/uniphier/clk-uniphier.h | 6 - drivers/clk/ux500/Makefile | 3 - drivers/clk/ux500/u8500_of_clk.c | 30 +- drivers/clk/versatile/Kconfig | 3 +- drivers/clk/versatile/Makefile | 2 +- drivers/clk/versatile/clk-icst.c | 9 +- drivers/clk/x86/clk-fch.c | 48 +- drivers/clk/zynq/pll.c | 12 +- drivers/clocksource/Kconfig | 14 +- drivers/clocksource/Makefile | 1 - drivers/clocksource/arc_timer.c | 6 +- drivers/clocksource/arm_arch_timer.c | 250 +- drivers/clocksource/exynos_mct.c | 52 +- drivers/clocksource/renesas-ostm.c | 39 +- drivers/clocksource/timer-imx-sysctr.c | 6 +- drivers/clocksource/timer-pistachio.c | 3 +- drivers/clocksource/timer-riscv.c | 9 - drivers/clocksource/timer-ti-dm-systimer.c | 3 +- drivers/connector/cn_proc.c | 2 +- drivers/counter/104-quad-8.c | 782 ++- drivers/counter/Kconfig | 6 +- drivers/counter/Makefile | 1 - drivers/counter/ftm-quaddec.c | 96 +- drivers/counter/intel-qep.c | 192 +- drivers/counter/interrupt-cnt.c | 100 +- drivers/counter/microchip-tcb-capture.c | 135 +- drivers/counter/stm32-lptimer-cnt.c | 263 +- drivers/counter/stm32-timer-cnt.c | 243 +- drivers/counter/ti-eqep.c | 232 +- drivers/cpuidle/Kconfig.arm | 3 +- drivers/cpuidle/cpuidle-qcom-spm.c | 324 +- drivers/cpuidle/cpuidle-tegra.c | 3 - drivers/cpuidle/governors/menu.c | 2 +- drivers/cpuidle/sysfs.c | 8 +- drivers/crypto/Kconfig | 12 - .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 21 - drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h | 1 - drivers/crypto/cavium/cpt/cptvf_main.c | 5 +- drivers/crypto/ccp/ccp-dev-v3.c | 5 +- drivers/crypto/ccp/ccp-dev-v5.c | 5 +- drivers/crypto/ccp/ccp-dev.c | 2 +- drivers/crypto/ccp/sev-dev.c | 245 +- drivers/crypto/ccree/cc_request_mgr.c | 1 + drivers/crypto/chelsio/chcr_crypto.h | 14 +- drivers/crypto/hisilicon/hpre/hpre_crypto.c | 5 +- drivers/crypto/hisilicon/qm.c | 561 +-- drivers/crypto/hisilicon/zip/zip_main.c | 14 +- drivers/crypto/img-hash.c | 7 +- drivers/crypto/keembay/Kconfig | 19 - drivers/crypto/keembay/Makefile | 2 - drivers/crypto/marvell/cesa/cesa.c | 1 + .../crypto/marvell/octeontx/otx_cptvf_main.c | 4 +- drivers/crypto/marvell/octeontx2/Makefile | 2 +- .../marvell/octeontx2/otx2_cpt_common.h | 1 - drivers/crypto/marvell/octeontx2/otx2_cptpf.h | 3 - .../marvell/octeontx2/otx2_cptpf_main.c | 9 - .../marvell/octeontx2/otx2_cptpf_ucode.c | 313 +- .../marvell/octeontx2/otx2_cptpf_ucode.h | 7 +- .../marvell/octeontx2/otx2_cptvf_algs.c | 5 +- drivers/crypto/qat/Kconfig | 1 - .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 151 +- .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 2 - drivers/crypto/qat/qat_4xxx/adf_drv.c | 40 +- .../crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c | 93 +- .../crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.h | 13 +- drivers/crypto/qat/qat_c3xxx/adf_drv.c | 7 +- .../qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 15 +- .../qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.h | 1 + drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 6 +- .../crypto/qat/qat_c62x/adf_c62x_hw_data.c | 91 +- .../crypto/qat/qat_c62x/adf_c62x_hw_data.h | 12 + drivers/crypto/qat/qat_c62x/adf_drv.c | 7 +- .../qat/qat_c62xvf/adf_c62xvf_hw_data.c | 15 +- .../qat/qat_c62xvf/adf_c62xvf_hw_data.h | 1 + drivers/crypto/qat/qat_c62xvf/adf_drv.c | 6 +- drivers/crypto/qat/qat_common/Makefile | 6 +- .../crypto/qat/qat_common/adf_accel_devices.h | 65 +- .../crypto/qat/qat_common/adf_accel_engine.c | 8 +- drivers/crypto/qat/qat_common/adf_admin.c | 47 +- drivers/crypto/qat/qat_common/adf_aer.c | 10 +- drivers/crypto/qat/qat_common/adf_cfg.c | 1 - .../crypto/qat/qat_common/adf_cfg_common.h | 13 - .../crypto/qat/qat_common/adf_cfg_strings.h | 3 - .../crypto/qat/qat_common/adf_common_drv.h | 40 +- .../crypto/qat/qat_common/adf_gen2_hw_data.c | 85 +- .../crypto/qat/qat_common/adf_gen2_hw_data.h | 23 - .../crypto/qat/qat_common/adf_gen4_hw_data.c | 69 +- .../crypto/qat/qat_common/adf_gen4_hw_data.h | 17 - drivers/crypto/qat/qat_common/adf_init.c | 11 +- drivers/crypto/qat/qat_common/adf_isr.c | 299 +- drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 46 +- drivers/crypto/qat/qat_common/adf_sriov.c | 59 +- drivers/crypto/qat/qat_common/adf_vf_isr.c | 130 +- .../qat/qat_common/icp_qat_fw_init_admin.h | 4 +- drivers/crypto/qat/qat_common/icp_qat_hw.h | 13 +- drivers/crypto/qat/qat_common/qat_crypto.c | 25 - drivers/crypto/qat/qat_common/qat_hal.c | 41 +- .../qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 145 +- .../qat/qat_dh895xcc/adf_dh895xcc_hw_data.h | 16 +- drivers/crypto/qat/qat_dh895xcc/adf_drv.c | 7 +- .../qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 15 +- .../qat_dh895xccvf/adf_dh895xccvf_hw_data.h | 1 + drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 6 +- drivers/crypto/sa2ul.c | 32 +- drivers/crypto/stm32/stm32-cryp.c | 54 +- drivers/crypto/ux500/cryp/cryp.h | 2 - drivers/crypto/ux500/cryp/cryp_core.c | 26 +- drivers/crypto/virtio/virtio_crypto_core.c | 8 +- drivers/cxl/Kconfig | 1 - drivers/cxl/acpi.c | 296 +- drivers/cxl/core/Makefile | 3 +- drivers/cxl/core/bus.c | 131 +- drivers/cxl/core/core.h | 11 +- drivers/cxl/core/memdev.c | 145 +- drivers/cxl/core/pmem.c | 55 +- drivers/cxl/core/regs.c | 8 +- drivers/cxl/cxl.h | 127 +- drivers/cxl/cxlmem.h | 217 +- drivers/cxl/pci.c | 1312 ++++- drivers/cxl/pci.h | 14 +- drivers/cxl/pmem.c | 195 +- drivers/dax/Kconfig | 13 + drivers/dax/Makefile | 3 +- drivers/dax/bus.c | 62 +- drivers/dax/bus.h | 14 +- drivers/dax/device.c | 132 +- drivers/dax/pmem/Makefile | 1 + drivers/dax/pmem/pmem.c | 30 + drivers/dax/super.c | 342 +- drivers/dma-buf/Makefile | 5 +- drivers/dma-buf/dma-buf-sysfs-stats.c | 2 +- drivers/dma-buf/dma-buf.c | 137 +- drivers/dma-buf/dma-fence.c | 30 +- drivers/dma-buf/dma-resv.c | 527 +- drivers/dma-buf/heaps/system_heap.c | 5 +- drivers/dma-buf/selftests.h | 1 - drivers/extcon/Kconfig | 2 +- drivers/extcon/extcon-axp288.c | 31 +- drivers/extcon/extcon-max3355.c | 1 + drivers/extcon/extcon-usb-gpio.c | 5 +- drivers/extcon/extcon-usbc-tusb320.c | 163 +- drivers/extcon/extcon.c | 14 +- drivers/firmware/Kconfig | 1 - drivers/firmware/Makefile | 1 - drivers/firmware/arm_ffa/driver.c | 53 +- drivers/firmware/arm_scmi/driver.c | 2 +- drivers/firmware/dmi-sysfs.c | 7 +- drivers/firmware/edd.c | 9 + drivers/firmware/efi/efi.c | 5 +- drivers/firmware/efi/efivars.c | 3 +- drivers/firmware/efi/esrt.c | 4 +- .../firmware/efi/libstub/efi-stub-helper.c | 73 +- drivers/firmware/efi/libstub/efi-stub.c | 12 +- drivers/firmware/efi/libstub/efistub.h | 30 +- drivers/firmware/efi/libstub/riscv-stub.c | 17 +- drivers/firmware/efi/libstub/x86-stub.c | 26 +- drivers/firmware/efi/memmap.c | 2 +- drivers/firmware/efi/runtime-map.c | 3 +- drivers/firmware/efi/vars.c | 5 +- drivers/firmware/memmap.c | 3 +- drivers/firmware/qcom_scm.c | 4 - drivers/firmware/qemu_fw_cfg.c | 6 +- drivers/firmware/stratix10-svc.c | 4 +- drivers/firmware/tegra/bpmp-debugfs.c | 29 +- drivers/firmware/tegra/bpmp-tegra210.c | 7 +- drivers/firmware/ti_sci.c | 2 +- drivers/firmware/xilinx/zynqmp.c | 108 +- drivers/fpga/altera-cvp.c | 12 +- drivers/fpga/altera-fpga2sdram.c | 12 +- drivers/fpga/altera-freeze-bridge.c | 10 +- drivers/fpga/altera-hps2fpga.c | 12 +- drivers/fpga/altera-pr-ip-core.c | 7 +- drivers/fpga/altera-ps-spi.c | 9 +- drivers/fpga/dfl-fme-br.c | 10 +- drivers/fpga/dfl-fme-mgr.c | 22 +- drivers/fpga/dfl-fme-region.c | 17 +- drivers/fpga/dfl.c | 12 +- drivers/fpga/fpga-bridge.c | 122 +- drivers/fpga/fpga-mgr.c | 215 +- drivers/fpga/fpga-region.c | 119 +- drivers/fpga/ice40-spi.c | 9 +- drivers/fpga/machxo2-spi.c | 9 +- drivers/fpga/of-fpga-region.c | 12 +- drivers/fpga/socfpga-a10.c | 16 +- drivers/fpga/socfpga.c | 9 +- drivers/fpga/stratix10-soc.c | 18 +- drivers/fpga/ts73xx-fpga.c | 9 +- drivers/fpga/versal-fpga.c | 9 +- drivers/fpga/xilinx-pr-decoupler.c | 17 +- drivers/fpga/xilinx-spi.c | 11 +- drivers/fpga/zynq-fpga.c | 18 +- drivers/fpga/zynqmp-fpga.c | 9 +- drivers/fsi/fsi-occ.c | 218 +- drivers/fsi/fsi-sbefifo.c | 28 +- drivers/gnss/Kconfig | 11 - drivers/gnss/Makefile | 3 - drivers/gnss/mtk.c | 2 +- drivers/gnss/serial.c | 2 +- drivers/gnss/sirf.c | 2 +- drivers/gnss/ubx.c | 2 +- drivers/gpio/Kconfig | 152 +- drivers/gpio/Makefile | 3 +- drivers/gpio/gpio-adnp.c | 1 + drivers/gpio/gpio-aggregator.c | 36 +- drivers/gpio/gpio-amdpt.c | 16 +- drivers/gpio/gpio-arizona.c | 5 +- drivers/gpio/gpio-bcm-kona.c | 2 +- drivers/gpio/gpio-bd71828.c | 1 + drivers/gpio/gpio-brcmstb.c | 3 +- drivers/gpio/gpio-creg-snps.c | 2 +- drivers/gpio/gpio-davinci.c | 1 + drivers/gpio/gpio-dwapb.c | 15 +- drivers/gpio/gpio-eic-sprd.c | 1 + drivers/gpio/gpio-em.c | 1 + drivers/gpio/gpio-ge.c | 1 + drivers/gpio/gpio-grgpio.c | 1 + drivers/gpio/gpio-gw-pld.c | 2 + drivers/gpio/gpio-lpc32xx.c | 2 +- drivers/gpio/gpio-max3191x.c | 2 +- drivers/gpio/gpio-max7300.c | 4 +- drivers/gpio/gpio-max7301.c | 4 +- drivers/gpio/gpio-max730x.c | 6 +- drivers/gpio/gpio-max77620.c | 1 + drivers/gpio/gpio-mc33880.c | 2 + drivers/gpio/gpio-ml-ioh.c | 52 +- drivers/gpio/gpio-mlxbf2.c | 142 +- drivers/gpio/gpio-mockup.c | 23 +- drivers/gpio/gpio-msc313.c | 266 +- drivers/gpio/gpio-mt7621.c | 6 +- drivers/gpio/gpio-mvebu.c | 1 + drivers/gpio/gpio-omap.c | 3 + drivers/gpio/gpio-palmas.c | 4 +- drivers/gpio/gpio-pch.c | 42 +- drivers/gpio/gpio-pmic-eic-sprd.c | 1 + drivers/gpio/gpio-pxa.c | 8 +- drivers/gpio/gpio-raspberrypi-exp.c | 1 + drivers/gpio/gpio-rcar.c | 16 +- drivers/gpio/gpio-rda.c | 3 + drivers/gpio/gpio-regmap.c | 6 +- drivers/gpio/gpio-rockchip.c | 21 +- drivers/gpio/gpio-sama5d2-piobu.c | 1 + drivers/gpio/gpio-sch.c | 2 +- drivers/gpio/gpio-sprd.c | 1 + drivers/gpio/gpio-sta2x11.c | 2 +- drivers/gpio/gpio-stmpe.c | 1 + drivers/gpio/gpio-tc3589x.c | 1 + drivers/gpio/gpio-tegra186.c | 243 +- drivers/gpio/gpio-tps65218.c | 4 + drivers/gpio/gpio-tps6586x.c | 5 +- drivers/gpio/gpio-tps65910.c | 6 +- drivers/gpio/gpio-ts5500.c | 11 +- drivers/gpio/gpio-twl6040.c | 5 +- drivers/gpio/gpio-uniphier.c | 18 +- drivers/gpio/gpio-vf610.c | 1 + drivers/gpio/gpio-virtio.c | 304 +- drivers/gpio/gpio-wm831x.c | 5 +- drivers/gpio/gpio-xilinx.c | 6 +- drivers/gpio/gpio-xlp.c | 147 +- drivers/gpio/gpiolib-acpi.c | 44 +- drivers/gpio/gpiolib-of.c | 3 - drivers/gpio/gpiolib.c | 92 +- drivers/gpu/drm/Kconfig | 52 +- drivers/gpu/drm/Makefile | 33 +- drivers/gpu/drm/amd/amdgpu/Makefile | 8 +- drivers/gpu/drm/amd/amdgpu/aldebaran.c | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu.h | 19 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 148 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 101 +- .../drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 18 +- .../drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h | 9 +- .../drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c | 126 +- .../drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c | 143 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 128 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 124 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 155 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h | 35 +- .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 280 +- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 12 - drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h | 2 - .../gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c | 4 +- .../gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 3 +- .../gpu/drm/amd/amdgpu/amdgpu_connectors.c | 17 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 143 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 179 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 400 +- drivers/gpu/drm/amd/amdgpu/amdgpu_df.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 1021 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 21 +- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 70 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h | 3 - drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 140 +- .../gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c | 25 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 95 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 33 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 7 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 19 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 17 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 9 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 55 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 16 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c | 7 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 58 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 20 + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 78 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c | 19 - .../gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 801 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 44 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 466 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 41 +- .../gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 22 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 18 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 23 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 44 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 42 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 108 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 15 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 175 +- drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c | 169 +- drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h | 9 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 119 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 44 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 208 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 5 - drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 82 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 67 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 63 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 40 +- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 12 +- drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h | 7 +- drivers/gpu/drm/amd/amdgpu/athub_v2_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/athub_v2_1.c | 9 +- .../gpu/drm/amd/amdgpu/atombios_encoders.c | 6 +- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 4 + drivers/gpu/drm/amd/amdgpu/df_v3_6.c | 31 - drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 411 +- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 4 - drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 4 - drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 365 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c | 5 - drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | 4 - drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c | 18 +- drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c | 11 +- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 105 +- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 229 +- drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c | 15 +- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 20 + drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h | 20 - drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c | 40 +- drivers/gpu/drm/amd/amdgpu/mca_v3_0.c | 9 +- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c | 73 +- drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c | 6 +- drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 16 +- drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h | 4 +- drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c | 5 +- drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 48 +- drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 35 - drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h | 1 - drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | 4 - drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 4 - drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 73 +- drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h | 1 - drivers/gpu/drm/amd/amdgpu/nv.c | 390 +- drivers/gpu/drm/amd/amdgpu/nv.h | 12 +- drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 22 +- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 181 +- drivers/gpu/drm/amd/amdgpu/psp_v12_0.c | 14 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 14 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 100 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 34 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 144 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 367 +- drivers/gpu/drm/amd/amdgpu/soc15.h | 5 +- drivers/gpu/drm/amd/amdgpu/soc15_common.h | 5 - drivers/gpu/drm/amd/amdgpu/ta_ras_if.h | 51 +- drivers/gpu/drm/amd/amdgpu/umc_v6_7.c | 195 - drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 11 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 11 +- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 15 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 22 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 29 +- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 62 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 1 - drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 1 - .../gpu/drm/amd/amdkfd/cik_event_interrupt.c | 8 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 131 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 148 +- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c | 18 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1049 ++-- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 160 +- .../drm/amd/amdkfd/kfd_device_queue_manager.h | 7 +- .../amd/amdkfd/kfd_device_queue_manager_v9.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 8 +- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 6 +- drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c | 33 +- .../gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 47 +- drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c | 18 +- drivers/gpu/drm/amd/amdkfd/kfd_iommu.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c | 9 +- drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 199 +- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 3 +- .../gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 44 +- .../gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c | 33 +- .../gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 37 +- .../gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 47 +- .../gpu/drm/amd/amdkfd/kfd_packet_manager.c | 35 +- .../drm/amd/amdkfd/kfd_packet_manager_vi.c | 4 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 48 +- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 172 +- .../amd/amdkfd/kfd_process_queue_manager.c | 35 +- drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 6 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 550 +-- drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 8 +- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 111 +- drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 46 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1449 ++---- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 108 +- .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 4 - .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 233 +- .../amd/display/amdgpu_dm/amdgpu_dm_hdcp.c | 16 +- .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 88 +- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 156 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 109 +- .../gpu/drm/amd/display/amdgpu_dm/dc_fpu.c | 2 +- drivers/gpu/drm/amd/display/dc/Makefile | 3 +- .../drm/amd/display/dc/bios/bios_parser2.c | 108 +- .../drm/amd/display/dc/bios/command_table2.c | 14 +- .../display/dc/bios/command_table_helper2.c | 1 - .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 56 +- .../gpu/drm/amd/display/dc/clk_mgr/Makefile | 9 - .../gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c | 21 +- .../display/dc/clk_mgr/dcn10/rv1_clk_mgr.c | 2 +- .../dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c | 2 - .../display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c | 3 +- .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 31 +- .../dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c | 6 +- .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c | 44 +- .../display/dc/clk_mgr/dcn301/dcn301_smu.c | 6 +- .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c | 22 +- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 26 +- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h | 7 - .../amd/display/dc/clk_mgr/dcn31/dcn31_smu.c | 6 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 541 +-- .../gpu/drm/amd/display/dc/core/dc_debug.c | 2 - drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1329 +----- .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 26 +- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 2846 ++--------- .../drm/amd/display/dc/core/dc_link_dpcd.c | 11 +- .../drm/amd/display/dc/core/dc_link_enc_cfg.c | 547 +-- .../drm/amd/display/dc/core/dc_link_hwss.c | 382 +- .../gpu/drm/amd/display/dc/core/dc_resource.c | 379 +- drivers/gpu/drm/amd/display/dc/core/dc_sink.c | 10 +- drivers/gpu/drm/amd/display/dc/core/dc_stat.c | 8 - .../gpu/drm/amd/display/dc/core/dc_stream.c | 4 - drivers/gpu/drm/amd/display/dc/dc.h | 140 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 37 +- drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h | 2 - drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 345 +- drivers/gpu/drm/amd/display/dc/dc_dsc.h | 11 +- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 - drivers/gpu/drm/amd/display/dc/dc_link.h | 63 +- drivers/gpu/drm/amd/display/dc/dc_stream.h | 13 - drivers/gpu/drm/amd/display/dc/dc_types.h | 25 - drivers/gpu/drm/amd/display/dc/dce/dce_abm.h | 16 - .../gpu/drm/amd/display/dc/dce/dce_audio.c | 12 +- .../gpu/drm/amd/display/dc/dce/dce_audio.h | 2 - drivers/gpu/drm/amd/display/dc/dce/dce_aux.c | 49 +- .../drm/amd/display/dc/dce/dce_clock_source.h | 9 - .../gpu/drm/amd/display/dc/dce/dce_hwseq.h | 44 +- .../drm/amd/display/dc/dce/dce_link_encoder.c | 5 +- .../amd/display/dc/dce/dce_stream_encoder.c | 2 - drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 21 - .../drm/amd/display/dc/dce/dmub_hw_lock_mgr.c | 3 - drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 34 - drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 1 - .../display/dc/dce110/dce110_hw_sequencer.c | 213 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 8 + .../drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 123 +- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 238 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h | 33 +- .../amd/display/dc/dcn10/dcn10_link_encoder.c | 14 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_opp.c | 30 + .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 22 +- .../drm/amd/display/dc/dcn10/dcn10_resource.c | 40 +- .../display/dc/dcn10/dcn10_stream_encoder.c | 31 - .../display/dc/dcn10/dcn10_stream_encoder.h | 2 - .../gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h | 34 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c | 14 + .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c | 2 - .../drm/amd/display/dc/dcn20/dcn20_dwb_scl.c | 4 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 21 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h | 1 - .../drm/amd/display/dc/dcn20/dcn20_hwseq.c | 70 +- .../drm/amd/display/dc/dcn20/dcn20_hwseq.h | 4 - .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 2 - .../gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c | 9 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 76 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.h | 3 - .../drm/amd/display/dc/dcn20/dcn20_resource.c | 40 +- .../display/dc/dcn20/dcn20_stream_encoder.c | 17 +- .../display/dc/dcn20/dcn20_stream_encoder.h | 1 - .../drm/amd/display/dc/dcn21/dcn21_hubbub.c | 2 +- .../gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 15 +- .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 2 - .../amd/display/dc/dcn21/dcn21_link_encoder.c | 9 +- .../drm/amd/display/dc/dcn21/dcn21_resource.c | 35 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c | 24 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h | 24 - .../display/dc/dcn30/dcn30_dio_link_encoder.c | 4 - .../dc/dcn30/dcn30_dio_stream_encoder.c | 36 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c | 95 +- .../drm/amd/display/dc/dcn30/dcn30_dpp_cm.c | 8 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c | 7 +- .../drm/amd/display/dc/dcn30/dcn30_hwseq.c | 50 +- .../drm/amd/display/dc/dcn30/dcn30_hwseq.h | 5 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c | 4 - .../drm/amd/display/dc/dcn30/dcn30_mmhubbub.c | 2 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c | 9 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_optc.c | 18 +- .../drm/amd/display/dc/dcn30/dcn30_resource.c | 66 +- .../drm/amd/display/dc/dcn30/dcn30_resource.h | 7 - .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c | 200 +- .../gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h | 15 +- .../gpu/drm/amd/display/dc/dcn301/Makefile | 26 + .../drm/amd/display/dc/dcn301/dcn301_init.c | 2 - .../amd/display/dc/dcn301/dcn301_panel_cntl.c | 10 +- .../amd/display/dc/dcn301/dcn301_resource.c | 418 +- .../amd/display/dc/dcn301/dcn301_resource.h | 3 - .../drm/amd/display/dc/dcn302/dcn302_init.c | 2 - .../amd/display/dc/dcn302/dcn302_resource.c | 28 +- .../drm/amd/display/dc/dcn303/dcn303_dccg.h | 20 +- .../drm/amd/display/dc/dcn303/dcn303_init.c | 2 - .../amd/display/dc/dcn303/dcn303_resource.c | 35 +- drivers/gpu/drm/amd/display/dc/dcn31/Makefile | 4 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 385 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h | 52 +- .../display/dc/dcn31/dcn31_dio_link_encoder.c | 299 +- .../drm/amd/display/dc/dcn31/dcn31_hwseq.c | 193 +- .../drm/amd/display/dc/dcn31/dcn31_hwseq.h | 3 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_init.c | 11 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_optc.c | 1 - .../amd/display/dc/dcn31/dcn31_panel_cntl.c | 10 +- .../drm/amd/display/dc/dcn31/dcn31_resource.c | 359 +- .../drm/amd/display/dc/dcn31/dcn31_resource.h | 10 - drivers/gpu/drm/amd/display/dc/dm_cp_psp.h | 3 - drivers/gpu/drm/amd/display/dc/dm_helpers.h | 13 +- drivers/gpu/drm/amd/display/dc/dml/Makefile | 7 +- .../dc/dml/dcn20/display_rq_dlg_calc_20.c | 156 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 154 +- .../dc/dml/dcn21/display_mode_vba_21.c | 236 +- .../dc/dml/dcn21/display_rq_dlg_calc_21.c | 106 +- .../dc/dml/dcn30/display_mode_vba_30.c | 13 +- .../dc/dml/dcn30/display_rq_dlg_calc_30.c | 64 +- .../dc/dml/dcn31/display_mode_vba_31.c | 503 +- .../dc/dml/dcn31/display_rq_dlg_calc_31.c | 100 +- .../drm/amd/display/dc/dml/display_mode_lib.c | 1 - .../drm/amd/display/dc/dml/display_mode_lib.h | 2 - .../amd/display/dc/dml/display_mode_structs.h | 1 + .../display/dc/dml/display_rq_dlg_helpers.c | 257 +- .../display/dc/dml/display_rq_dlg_helpers.h | 20 +- .../display/dc/dml/dml1_display_rq_dlg_calc.c | 242 +- .../display/dc/dml/dml1_display_rq_dlg_calc.h | 10 +- .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.c | 33 +- .../drm/amd/display/dc/dml/dsc/rc_calc_fpu.h | 4 + drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 205 +- drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c | 28 + drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h | 1 + .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c | 6 +- .../gpu/drm/amd/display/dc/gpio/hw_factory.c | 1 - .../drm/amd/display/dc/gpio/hw_translate.c | 1 - .../gpu/drm/amd/display/dc/inc/core_status.h | 2 - .../gpu/drm/amd/display/dc/inc/core_types.h | 54 +- .../gpu/drm/amd/display/dc/inc/dc_link_ddc.h | 1 - .../gpu/drm/amd/display/dc/inc/dc_link_dp.h | 58 +- .../gpu/drm/amd/display/dc/inc/dcn_calcs.h | 2 +- drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 1 - .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 7 - .../amd/display/dc/inc/hw/clk_mgr_internal.h | 13 - drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 32 - drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h | 14 - drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h | 3 - drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h | 5 +- drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 1 - .../gpu/drm/amd/display/dc/inc/hw/hw_shared.h | 4 - .../drm/amd/display/dc/inc/hw/link_encoder.h | 98 - drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 2 - .../amd/display/dc/inc/hw/stream_encoder.h | 87 +- .../amd/display/dc/inc/hw/timing_generator.h | 5 - .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 3 +- .../amd/display/dc/inc/hw_sequencer_private.h | 8 - .../gpu/drm/amd/display/dc/inc/link_enc_cfg.h | 28 +- .../gpu/drm/amd/display/dc/inc/link_hwss.h | 11 +- drivers/gpu/drm/amd/display/dc/inc/resource.h | 34 - drivers/gpu/drm/amd/display/dc/irq/Makefile | 10 - .../dc/irq/dce110/irq_service_dce110.c | 10 +- .../display/dc/irq/dcn10/irq_service_dcn10.c | 7 +- .../display/dc/irq/dcn21/irq_service_dcn21.c | 7 +- .../display/dc/irq/dcn31/irq_service_dcn31.c | 7 +- drivers/gpu/drm/amd/display/dc/os_types.h | 2 - .../dc/virtual/virtual_stream_encoder.c | 5 +- drivers/gpu/drm/amd/display/dmub/dmub_srv.h | 53 - .../gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 326 +- .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 13 - .../gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 2 - .../gpu/drm/amd/display/dmub/src/dmub_srv.c | 110 +- .../drm/amd/display/dmub/src/dmub_srv_stat.c | 16 - .../amd/display/include/bios_parser_types.h | 8 - .../gpu/drm/amd/display/include/dal_asic_id.h | 1 - .../gpu/drm/amd/display/include/dal_types.h | 1 - .../amd/display/include/ddc_service_types.h | 4 - .../gpu/drm/amd/display/include/dpcd_defs.h | 17 - .../display/include/grph_object_ctrl_defs.h | 1 - .../amd/display/include/grph_object_defs.h | 12 - .../drm/amd/display/include/grph_object_id.h | 8 - .../amd/display/include/i2caux_interface.h | 3 - .../amd/display/include/link_service_types.h | 86 +- .../drm/amd/display/include/logger_types.h | 3 +- .../amd/display/modules/color/color_gamma.c | 32 +- .../amd/display/modules/freesync/freesync.c | 15 +- .../drm/amd/display/modules/inc/mod_hdcp.h | 2 - drivers/gpu/drm/amd/include/amd_shared.h | 7 +- .../include/asic_reg/dcn/dcn_3_1_2_offset.h | 2 - .../include/asic_reg/dcn/dcn_3_1_2_sh_mask.h | 8 - .../amd/include/asic_reg/df/df_3_6_offset.h | 5 - .../amd/include/asic_reg/df/df_3_6_sh_mask.h | 132 - .../amd/include/asic_reg/mp/mp_11_0_offset.h | 7 - .../amd/include/asic_reg/mp/mp_11_0_sh_mask.h | 12 - .../include/asic_reg/nbio/nbio_7_2_0_offset.h | 2 + .../asic_reg/nbio/nbio_7_2_0_sh_mask.h | 12 + drivers/gpu/drm/amd/include/atombios.h | 2 +- drivers/gpu/drm/amd/include/atomfirmware.h | 4 - .../amd/include/cyan_skillfish_ip_offset.h | 10 +- .../gpu/drm/amd/include/kgd_kfd_interface.h | 57 +- .../gpu/drm/amd/include/kgd_pp_interface.h | 4 - drivers/gpu/drm/amd/include/soc15_hw_ip.h | 2 - .../gpu/drm/amd/include/yellow_carp_offset.h | 4 +- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 41 +- drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h | 4 +- drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 8 - drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h | 35 +- .../amd/pm/inc/smu13_driver_if_aldebaran.h | 18 +- drivers/gpu/drm/amd/pm/inc/smu_types.h | 3 +- drivers/gpu/drm/amd/pm/inc/smu_v11_0.h | 6 +- drivers/gpu/drm/amd/pm/inc/smu_v13_0.h | 9 +- .../gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h | 4 +- .../gpu/drm/amd/pm/powerplay/amd_powerplay.c | 35 +- .../drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h | 4 +- .../drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 9 +- .../drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 14 +- .../drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 12 +- .../drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 10 +- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 291 +- .../gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c | 36 +- .../amd/pm/swsmu/smu11/cyan_skillfish_ppt.c | 39 +- .../gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c | 74 +- .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c | 206 +- .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 175 +- .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 43 +- .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 10 +- .../drm/amd/pm/swsmu/smu13/aldebaran_ppt.c | 154 +- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 64 +- .../drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 114 +- .../drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h | 1 - drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 42 +- drivers/gpu/drm/arm/Kconfig | 2 + drivers/gpu/drm/arm/display/Kconfig | 1 + drivers/gpu/drm/arm/malidp_planes.c | 2 +- drivers/gpu/drm/armada/armada_gem.c | 9 +- drivers/gpu/drm/ast/Makefile | 2 +- drivers/gpu/drm/ast/ast_drv.c | 3 +- drivers/gpu/drm/ast/ast_drv.h | 5 +- drivers/gpu/drm/ast/ast_mm.c | 27 +- drivers/gpu/drm/ast/ast_mode.c | 151 +- drivers/gpu/drm/atmel-hlcdc/Kconfig | 1 + drivers/gpu/drm/bridge/Kconfig | 1 - drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 15 +- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 15 +- drivers/gpu/drm/bridge/adv7511/adv7533.c | 20 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 510 +- drivers/gpu/drm/bridge/analogix/anx7625.h | 23 +- drivers/gpu/drm/bridge/cdns-dsi.c | 4 +- drivers/gpu/drm/bridge/display-connector.c | 86 - drivers/gpu/drm/bridge/lontium-lt8912b.c | 31 +- drivers/gpu/drm/bridge/lontium-lt9611.c | 66 +- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 65 +- drivers/gpu/drm/bridge/lvds-codec.c | 84 +- drivers/gpu/drm/bridge/panel.c | 40 +- drivers/gpu/drm/bridge/parade-ps8640.c | 601 +-- drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c | 6 +- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 - drivers/gpu/drm/bridge/tc358762.c | 2 +- drivers/gpu/drm/bridge/tc358768.c | 90 +- drivers/gpu/drm/bridge/tc358775.c | 50 +- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 127 +- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 508 +- drivers/gpu/drm/drm_atomic.c | 180 +- drivers/gpu/drm/drm_atomic_helper.c | 243 +- drivers/gpu/drm/drm_atomic_uapi.c | 6 +- drivers/gpu/drm/drm_auth.c | 12 +- drivers/gpu/drm/drm_bridge.c | 218 +- drivers/gpu/drm/drm_cache.c | 4 +- drivers/gpu/drm/drm_connector.c | 318 +- drivers/gpu/drm/drm_crtc_internal.h | 2 - drivers/gpu/drm/drm_dp_helper.c | 271 +- drivers/gpu/drm/drm_dp_mst_topology.c | 48 +- drivers/gpu/drm/drm_drv.c | 4 - drivers/gpu/drm/drm_edid.c | 367 +- drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/gpu/drm/drm_format_helper.c | 373 +- drivers/gpu/drm/drm_fourcc.c | 5 +- drivers/gpu/drm/drm_gem.c | 26 +- drivers/gpu/drm/drm_gem_atomic_helper.c | 14 +- drivers/gpu/drm/drm_gem_cma_helper.c | 95 +- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 3 - drivers/gpu/drm/drm_gem_shmem_helper.c | 179 +- drivers/gpu/drm/drm_gem_vram_helper.c | 5 +- drivers/gpu/drm/drm_hashtab.c | 10 +- drivers/gpu/drm/drm_ioctl.c | 21 +- drivers/gpu/drm/drm_irq.c | 2 + drivers/gpu/drm/drm_kms_helper_common.c | 11 + drivers/gpu/drm/drm_lease.c | 41 +- drivers/gpu/drm/drm_legacy.h | 40 +- drivers/gpu/drm/drm_mipi_dbi.c | 40 +- drivers/gpu/drm/drm_mipi_dsi.c | 81 - drivers/gpu/drm/drm_mm.c | 9 +- drivers/gpu/drm/drm_modeset_lock.c | 60 +- drivers/gpu/drm/drm_of.c | 36 - .../gpu/drm/drm_panel_orientation_quirks.c | 14 - drivers/gpu/drm/drm_prime.c | 3 - drivers/gpu/drm/drm_probe_helper.c | 87 +- drivers/gpu/drm/drm_property.c | 9 +- drivers/gpu/drm/drm_sysfs.c | 112 +- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 41 +- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 33 +- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 3 - drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 4 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 7 +- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_drv.c | 13 +- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 49 +- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 20 +- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_gem.c | 46 +- drivers/gpu/drm/exynos/exynos_drm_gem.h | 5 + drivers/gpu/drm/gma500/backlight.c | 12 +- drivers/gpu/drm/gma500/cdv_device.c | 24 +- drivers/gpu/drm/gma500/cdv_intel_display.c | 10 +- drivers/gpu/drm/gma500/cdv_intel_dp.c | 12 +- drivers/gpu/drm/gma500/cdv_intel_lvds.c | 22 +- drivers/gpu/drm/gma500/framebuffer.c | 68 +- drivers/gpu/drm/gma500/gem.c | 236 +- drivers/gpu/drm/gma500/gem.h | 28 +- drivers/gpu/drm/gma500/gma_device.c | 2 +- drivers/gpu/drm/gma500/gma_display.c | 65 +- drivers/gpu/drm/gma500/gtt.c | 342 +- drivers/gpu/drm/gma500/gtt.h | 33 +- drivers/gpu/drm/gma500/intel_bios.c | 10 +- drivers/gpu/drm/gma500/intel_gmbus.c | 12 +- drivers/gpu/drm/gma500/mid_bios.c | 11 +- drivers/gpu/drm/gma500/mmu.c | 12 +- drivers/gpu/drm/gma500/oaktrail_crtc.c | 11 +- drivers/gpu/drm/gma500/oaktrail_device.c | 20 +- drivers/gpu/drm/gma500/oaktrail_hdmi.c | 18 +- drivers/gpu/drm/gma500/oaktrail_lvds.c | 14 +- drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c | 2 +- drivers/gpu/drm/gma500/opregion.c | 14 +- drivers/gpu/drm/gma500/power.c | 20 +- drivers/gpu/drm/gma500/psb_device.c | 16 +- drivers/gpu/drm/gma500/psb_drv.c | 157 +- drivers/gpu/drm/gma500/psb_drv.h | 24 +- drivers/gpu/drm/gma500/psb_intel_display.c | 27 +- drivers/gpu/drm/gma500/psb_intel_drv.h | 2 +- drivers/gpu/drm/gma500/psb_intel_lvds.c | 31 +- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 10 +- drivers/gpu/drm/gma500/psb_irq.c | 26 +- drivers/gpu/drm/gma500/psb_lid.c | 2 +- drivers/gpu/drm/gud/Kconfig | 2 +- drivers/gpu/drm/gud/gud_drv.c | 6 - drivers/gpu/drm/gud/gud_internal.h | 12 - drivers/gpu/drm/gud/gud_pipe.c | 14 +- drivers/gpu/drm/hisilicon/kirin/Kconfig | 1 + drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 52 +- drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 5 +- drivers/gpu/drm/i915/Kconfig | 14 +- drivers/gpu/drm/i915/Makefile | 43 +- drivers/gpu/drm/i915/display/g4x_dp.c | 91 +- drivers/gpu/drm/i915/display/g4x_hdmi.c | 3 +- drivers/gpu/drm/i915/display/i9xx_plane.c | 141 +- drivers/gpu/drm/i915/display/icl_dsi.c | 176 +- drivers/gpu/drm/i915/display/intel_acpi.c | 46 - drivers/gpu/drm/i915/display/intel_acpi.h | 3 - drivers/gpu/drm/i915/display/intel_atomic.c | 1 - .../gpu/drm/i915/display/intel_atomic_plane.c | 304 +- .../gpu/drm/i915/display/intel_atomic_plane.h | 23 +- drivers/gpu/drm/i915/display/intel_audio.c | 170 +- drivers/gpu/drm/i915/display/intel_audio.h | 4 +- drivers/gpu/drm/i915/display/intel_bios.c | 407 +- drivers/gpu/drm/i915/display/intel_bw.c | 221 +- drivers/gpu/drm/i915/display/intel_cdclk.c | 551 +-- drivers/gpu/drm/i915/display/intel_cdclk.h | 12 +- drivers/gpu/drm/i915/display/intel_color.c | 291 +- .../gpu/drm/i915/display/intel_combo_phy.c | 10 +- .../gpu/drm/i915/display/intel_connector.c | 6 +- drivers/gpu/drm/i915/display/intel_crt.c | 23 +- drivers/gpu/drm/i915/display/intel_crtc.c | 155 +- drivers/gpu/drm/i915/display/intel_crtc.h | 14 - drivers/gpu/drm/i915/display/intel_cursor.c | 80 +- drivers/gpu/drm/i915/display/intel_ddi.c | 884 ++-- drivers/gpu/drm/i915/display/intel_ddi.h | 12 +- .../drm/i915/display/intel_ddi_buf_trans.c | 766 ++- .../drm/i915/display/intel_ddi_buf_trans.h | 23 +- drivers/gpu/drm/i915/display/intel_display.c | 4236 +++++++++++++---- drivers/gpu/drm/i915/display/intel_display.h | 94 +- .../drm/i915/display/intel_display_debugfs.c | 235 +- .../drm/i915/display/intel_display_debugfs.h | 10 +- .../drm/i915/display/intel_display_power.c | 151 +- .../drm/i915/display/intel_display_power.h | 106 +- .../drm/i915/display/intel_display_types.h | 175 +- drivers/gpu/drm/i915/display/intel_dmc.c | 24 +- drivers/gpu/drm/i915/display/intel_dmc.h | 2 - drivers/gpu/drm/i915/display/intel_dp.c | 476 +- drivers/gpu/drm/i915/display/intel_dp.h | 11 +- drivers/gpu/drm/i915/display/intel_dp_aux.c | 6 +- .../drm/i915/display/intel_dp_aux_backlight.c | 94 +- drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 80 +- .../drm/i915/display/intel_dp_link_training.c | 504 +- .../drm/i915/display/intel_dp_link_training.h | 1 - drivers/gpu/drm/i915/display/intel_dp_mst.c | 81 +- drivers/gpu/drm/i915/display/intel_dp_mst.h | 4 +- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 33 +- drivers/gpu/drm/i915/display/intel_dpio_phy.h | 5 +- drivers/gpu/drm/i915/display/intel_dpll.c | 676 ++- drivers/gpu/drm/i915/display/intel_dpll.h | 26 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 53 +- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 13 +- drivers/gpu/drm/i915/display/intel_dpt.c | 104 +- drivers/gpu/drm/i915/display/intel_dpt.h | 4 - drivers/gpu/drm/i915/display/intel_drrs.c | 224 +- drivers/gpu/drm/i915/display/intel_drrs.h | 34 +- drivers/gpu/drm/i915/display/intel_dsb.c | 4 +- drivers/gpu/drm/i915/display/intel_dsi.c | 18 +- drivers/gpu/drm/i915/display/intel_dsi.h | 39 + .../i915/display/intel_dsi_dcs_backlight.c | 37 +- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 5 +- drivers/gpu/drm/i915/display/intel_dvo.c | 24 +- drivers/gpu/drm/i915/display/intel_fb.c | 1190 +---- drivers/gpu/drm/i915/display/intel_fb.h | 53 +- drivers/gpu/drm/i915/display/intel_fbc.c | 1974 ++++---- drivers/gpu/drm/i915/display/intel_fbc.h | 19 +- drivers/gpu/drm/i915/display/intel_fbdev.c | 4 +- drivers/gpu/drm/i915/display/intel_fdi.c | 264 +- drivers/gpu/drm/i915/display/intel_fdi.h | 17 +- .../drm/i915/display/intel_fifo_underrun.c | 12 +- .../gpu/drm/i915/display/intel_frontbuffer.c | 11 +- .../gpu/drm/i915/display/intel_frontbuffer.h | 6 +- drivers/gpu/drm/i915/display/intel_gmbus.c | 13 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 70 +- drivers/gpu/drm/i915/display/intel_hdmi.c | 121 +- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 +- drivers/gpu/drm/i915/display/intel_lvds.c | 33 +- drivers/gpu/drm/i915/display/intel_opregion.c | 5 +- drivers/gpu/drm/i915/display/intel_overlay.c | 2 +- drivers/gpu/drm/i915/display/intel_panel.c | 1837 ++++++- drivers/gpu/drm/i915/display/intel_panel.h | 48 +- drivers/gpu/drm/i915/display/intel_pps.c | 59 - drivers/gpu/drm/i915/display/intel_pps.h | 3 - drivers/gpu/drm/i915/display/intel_psr.c | 563 +-- drivers/gpu/drm/i915/display/intel_psr.h | 25 +- drivers/gpu/drm/i915/display/intel_quirks.c | 1 - drivers/gpu/drm/i915/display/intel_sdvo.c | 21 +- drivers/gpu/drm/i915/display/intel_snps_phy.c | 227 +- drivers/gpu/drm/i915/display/intel_snps_phy.h | 4 +- drivers/gpu/drm/i915/display/intel_sprite.c | 299 +- drivers/gpu/drm/i915/display/intel_sprite.h | 4 + drivers/gpu/drm/i915/display/intel_tc.c | 312 +- drivers/gpu/drm/i915/display/intel_tc.h | 6 +- drivers/gpu/drm/i915/display/intel_tv.c | 10 +- drivers/gpu/drm/i915/display/intel_vbt_defs.h | 7 +- drivers/gpu/drm/i915/display/intel_vdsc.c | 159 +- drivers/gpu/drm/i915/display/intel_vdsc.h | 16 +- drivers/gpu/drm/i915/display/intel_vrr.c | 18 +- drivers/gpu/drm/i915/display/intel_vrr.h | 1 - drivers/gpu/drm/i915/display/skl_scaler.c | 1 - .../drm/i915/display/skl_universal_plane.c | 497 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 61 +- drivers/gpu/drm/i915/display/vlv_dsi_pll.c | 26 +- drivers/gpu/drm/i915/gem/i915_gem_busy.c | 90 +- drivers/gpu/drm/i915/gem/i915_gem_clflush.c | 18 +- drivers/gpu/drm/i915/gem/i915_gem_context.c | 526 +- drivers/gpu/drm/i915/gem/i915_gem_context.h | 19 +- .../gpu/drm/i915/gem/i915_gem_context_types.h | 58 +- drivers/gpu/drm/i915/gem/i915_gem_create.c | 75 +- drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 25 +- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 22 - .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 990 +--- drivers/gpu/drm/i915/gem/i915_gem_internal.c | 78 +- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 33 +- drivers/gpu/drm/i915/gem/i915_gem_lmem.h | 4 - drivers/gpu/drm/i915/gem/i915_gem_mman.c | 16 +- drivers/gpu/drm/i915/gem/i915_gem_object.c | 158 +- drivers/gpu/drm/i915/gem/i915_gem_object.h | 73 +- .../gpu/drm/i915/gem/i915_gem_object_types.h | 106 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 23 +- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 6 +- drivers/gpu/drm/i915/gem/i915_gem_pm.c | 97 +- drivers/gpu/drm/i915/gem/i915_gem_pm.h | 1 - drivers/gpu/drm/i915/gem/i915_gem_region.c | 74 +- drivers/gpu/drm/i915/gem/i915_gem_region.h | 37 - drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 224 +- drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 137 +- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 19 +- drivers/gpu/drm/i915/gem/i915_gem_throttle.c | 3 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 807 ++-- drivers/gpu/drm/i915/gem/i915_gem_ttm.h | 47 +- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_wait.c | 104 +- drivers/gpu/drm/i915/gem/i915_gemfs.c | 21 +- .../gpu/drm/i915/gem/selftests/huge_pages.c | 174 +- .../i915/gem/selftests/i915_gem_client_blt.c | 31 +- .../drm/i915/gem/selftests/i915_gem_context.c | 105 +- .../drm/i915/gem/selftests/i915_gem_dmabuf.c | 4 +- .../drm/i915/gem/selftests/i915_gem_migrate.c | 26 +- .../drm/i915/gem/selftests/i915_gem_mman.c | 46 +- .../gpu/drm/i915/gem/selftests/mock_context.c | 5 +- drivers/gpu/drm/i915/gt/debugfs_gt.c | 2 +- drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 153 +- drivers/gpu/drm/i915/gt/gen6_ppgtt.h | 2 + drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 2 +- drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 41 +- drivers/gpu/drm/i915/gt/gen8_ppgtt.h | 4 +- drivers/gpu/drm/i915/gt/intel_context.c | 79 +- drivers/gpu/drm/i915/gt/intel_context.h | 59 +- drivers/gpu/drm/i915/gt/intel_context_types.h | 156 +- drivers/gpu/drm/i915/gt/intel_engine.h | 19 +- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 218 +- .../gpu/drm/i915/gt/intel_engine_heartbeat.c | 2 +- drivers/gpu/drm/i915/gt/intel_engine_pm.c | 76 +- drivers/gpu/drm/i915/gt/intel_engine_pm.h | 39 - drivers/gpu/drm/i915/gt/intel_engine_stats.h | 33 +- drivers/gpu/drm/i915/gt/intel_engine_types.h | 115 +- drivers/gpu/drm/i915/gt/intel_engine_user.c | 2 +- .../drm/i915/gt/intel_execlists_submission.c | 50 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 427 +- drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 22 +- drivers/gpu/drm/i915/gt/intel_gt.c | 41 +- drivers/gpu/drm/i915/gt/intel_gt.h | 1 - .../gpu/drm/i915/gt/intel_gt_buffer_pool.c | 9 +- drivers/gpu/drm/i915/gt/intel_gt_irq.c | 7 - drivers/gpu/drm/i915/gt/intel_gt_pm.c | 25 +- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 14 - drivers/gpu/drm/i915/gt/intel_gt_types.h | 12 - drivers/gpu/drm/i915/gt/intel_gtt.c | 40 +- drivers/gpu/drm/i915/gt/intel_gtt.h | 25 +- drivers/gpu/drm/i915/gt/intel_llc.c | 3 +- drivers/gpu/drm/i915/gt/intel_lrc.c | 98 +- drivers/gpu/drm/i915/gt/intel_migrate.c | 34 +- drivers/gpu/drm/i915/gt/intel_migrate.h | 9 +- drivers/gpu/drm/i915/gt/intel_mocs.c | 176 +- drivers/gpu/drm/i915/gt/intel_mocs.h | 1 - drivers/gpu/drm/i915/gt/intel_ppgtt.c | 25 +- drivers/gpu/drm/i915/gt/intel_rc6.c | 17 +- drivers/gpu/drm/i915/gt/intel_region_lmem.c | 21 +- drivers/gpu/drm/i915/gt/intel_reset.c | 60 +- drivers/gpu/drm/i915/gt/intel_ring.c | 3 +- .../gpu/drm/i915/gt/intel_ring_submission.c | 9 +- drivers/gpu/drm/i915/gt/intel_rps.c | 165 +- drivers/gpu/drm/i915/gt/intel_rps.h | 6 - drivers/gpu/drm/i915/gt/intel_sseu.c | 65 +- drivers/gpu/drm/i915/gt/intel_sseu.h | 11 +- drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c | 10 +- drivers/gpu/drm/i915/gt/intel_workarounds.c | 753 +-- drivers/gpu/drm/i915/gt/intel_workarounds.h | 2 +- drivers/gpu/drm/i915/gt/mock_engine.c | 52 +- drivers/gpu/drm/i915/gt/selftest_context.c | 2 +- drivers/gpu/drm/i915/gt/selftest_engine.c | 2 +- drivers/gpu/drm/i915/gt/selftest_engine_cs.c | 4 +- .../drm/i915/gt/selftest_engine_heartbeat.c | 8 +- drivers/gpu/drm/i915/gt/selftest_engine_pm.c | 35 +- drivers/gpu/drm/i915/gt/selftest_execlists.c | 34 +- drivers/gpu/drm/i915/gt/selftest_gt_pm.c | 12 +- drivers/gpu/drm/i915/gt/selftest_hangcheck.c | 32 +- drivers/gpu/drm/i915/gt/selftest_lrc.c | 2 +- drivers/gpu/drm/i915/gt/selftest_migrate.c | 7 +- drivers/gpu/drm/i915/gt/selftest_mocs.c | 2 +- drivers/gpu/drm/i915/gt/selftest_reset.c | 2 +- .../drm/i915/gt/selftest_ring_submission.c | 4 +- drivers/gpu/drm/i915/gt/selftest_slpc.c | 6 +- drivers/gpu/drm/i915/gt/selftest_timeline.c | 6 +- .../gpu/drm/i915/gt/selftest_workarounds.c | 6 +- .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h | 2 - drivers/gpu/drm/i915/gt/uc/intel_guc.c | 39 +- drivers/gpu/drm/i915/gt/uc/intel_guc.h | 164 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 49 +- drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h | 5 - drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 78 +- .../gpu/drm/i915/gt/uc/intel_guc_debugfs.c | 18 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 42 +- drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 45 +- drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 5 +- .../drm/i915/gt/uc/intel_guc_log_debugfs.c | 66 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 159 +- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.h | 3 - .../gpu/drm/i915/gt/uc/intel_guc_slpc_types.h | 13 - .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 2556 ++-------- .../gpu/drm/i915/gt/uc/intel_guc_submission.h | 2 - drivers/gpu/drm/i915/gt/uc/intel_huc.c | 67 +- drivers/gpu/drm/i915/gt/uc/intel_huc.h | 2 + .../gpu/drm/i915/gt/uc/intel_huc_debugfs.c | 6 +- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 11 +- drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c | 6 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 279 +- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 27 +- drivers/gpu/drm/i915/gvt/fb_decoder.c | 2 +- drivers/gpu/drm/i915/gvt/gtt.c | 33 +- drivers/gpu/drm/i915/gvt/gvt.c | 2 +- drivers/gpu/drm/i915/gvt/kvmgt.c | 4 +- drivers/gpu/drm/i915/gvt/scheduler.c | 2 +- drivers/gpu/drm/i915/i915_active.c | 28 +- drivers/gpu/drm/i915/i915_active.h | 17 +- drivers/gpu/drm/i915/i915_active_types.h | 2 + drivers/gpu/drm/i915/i915_buddy.c | 45 - drivers/gpu/drm/i915/i915_buddy.h | 8 - drivers/gpu/drm/i915/i915_config.c | 2 +- drivers/gpu/drm/i915/i915_debugfs.c | 319 +- drivers/gpu/drm/i915/i915_debugfs_params.c | 4 +- drivers/gpu/drm/i915/i915_drv.h | 522 +- drivers/gpu/drm/i915/i915_gem.c | 53 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 4 +- drivers/gpu/drm/i915/i915_gem_ww.h | 25 +- drivers/gpu/drm/i915/i915_getparam.c | 10 +- drivers/gpu/drm/i915/i915_gpu_error.c | 282 +- drivers/gpu/drm/i915/i915_gpu_error.h | 4 +- drivers/gpu/drm/i915/i915_irq.c | 178 +- drivers/gpu/drm/i915/i915_irq.h | 51 +- drivers/gpu/drm/i915/i915_mm.c | 28 +- drivers/gpu/drm/i915/i915_module.c | 12 +- drivers/gpu/drm/i915/i915_params.c | 3 - drivers/gpu/drm/i915/i915_params.h | 3 +- drivers/gpu/drm/i915/i915_pci.c | 141 +- drivers/gpu/drm/i915/i915_pci.h | 12 +- drivers/gpu/drm/i915/i915_perf.c | 24 +- drivers/gpu/drm/i915/i915_pmu.c | 14 +- drivers/gpu/drm/i915/i915_query.c | 7 +- drivers/gpu/drm/i915/i915_reg.h | 749 +-- drivers/gpu/drm/i915/i915_request.c | 351 +- drivers/gpu/drm/i915/i915_request.h | 79 +- drivers/gpu/drm/i915/i915_scatterlist.c | 62 +- drivers/gpu/drm/i915/i915_scatterlist.h | 76 +- drivers/gpu/drm/i915/i915_sw_fence.c | 81 +- drivers/gpu/drm/i915/i915_sw_fence.h | 25 +- drivers/gpu/drm/i915/i915_sw_fence_work.c | 2 +- drivers/gpu/drm/i915/i915_switcheroo.c | 5 +- drivers/gpu/drm/i915/i915_sysfs.c | 42 +- drivers/gpu/drm/i915/i915_trace.h | 518 +- drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 20 +- drivers/gpu/drm/i915/i915_utils.h | 14 +- drivers/gpu/drm/i915/i915_vma.c | 547 +-- drivers/gpu/drm/i915/i915_vma.h | 27 +- drivers/gpu/drm/i915/i915_vma_types.h | 28 +- drivers/gpu/drm/i915/intel_device_info.c | 64 +- drivers/gpu/drm/i915/intel_device_info.h | 26 +- drivers/gpu/drm/i915/intel_dram.c | 6 +- drivers/gpu/drm/i915/intel_gvt.c | 2 +- drivers/gpu/drm/i915/intel_memory_region.c | 166 +- drivers/gpu/drm/i915/intel_memory_region.h | 13 +- drivers/gpu/drm/i915/intel_pch.c | 3 +- drivers/gpu/drm/i915/intel_pch.h | 3 +- drivers/gpu/drm/i915/intel_pm.c | 488 +- drivers/gpu/drm/i915/intel_pm.h | 4 +- drivers/gpu/drm/i915/intel_region_ttm.c | 50 +- drivers/gpu/drm/i915/intel_region_ttm.h | 7 +- drivers/gpu/drm/i915/intel_runtime_pm.c | 24 +- drivers/gpu/drm/i915/intel_runtime_pm.h | 2 + drivers/gpu/drm/i915/intel_step.c | 77 +- drivers/gpu/drm/i915/intel_step.h | 3 +- drivers/gpu/drm/i915/intel_uncore.c | 477 +- drivers/gpu/drm/i915/intel_uncore.h | 25 +- drivers/gpu/drm/i915/intel_wakeref.h | 12 - drivers/gpu/drm/i915/intel_wopcm.c | 2 +- drivers/gpu/drm/i915/selftests/i915_active.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem.c | 2 +- .../gpu/drm/i915/selftests/i915_gem_evict.c | 25 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 22 +- .../drm/i915/selftests/i915_live_selftests.h | 2 - drivers/gpu/drm/i915/selftests/i915_perf.c | 2 +- drivers/gpu/drm/i915/selftests/i915_request.c | 24 +- .../gpu/drm/i915/selftests/i915_selftest.c | 4 +- .../gpu/drm/i915/selftests/i915_sw_fence.c | 2 +- drivers/gpu/drm/i915/selftests/i915_vma.c | 21 +- .../gpu/drm/i915/selftests/igt_flush_test.c | 2 +- .../gpu/drm/i915/selftests/igt_live_test.c | 4 +- drivers/gpu/drm/i915/selftests/igt_reset.c | 2 +- .../drm/i915/selftests/intel_memory_region.c | 12 +- .../i915/selftests/intel_scheduler_helpers.c | 12 - .../i915/selftests/intel_scheduler_helpers.h | 2 - drivers/gpu/drm/i915/selftests/intel_uncore.c | 38 +- drivers/gpu/drm/i915/selftests/lib_sw_fence.c | 8 +- .../gpu/drm/i915/selftests/mock_gem_device.c | 34 +- drivers/gpu/drm/i915/selftests/mock_gtt.c | 12 +- drivers/gpu/drm/i915/selftests/mock_region.c | 21 +- drivers/gpu/drm/i915/selftests/mock_uncore.c | 2 +- drivers/gpu/drm/imx/Kconfig | 2 +- drivers/gpu/drm/imx/dcss/Kconfig | 3 +- drivers/gpu/drm/ingenic/Kconfig | 1 + drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 283 +- drivers/gpu/drm/ingenic/ingenic-ipu.c | 127 +- drivers/gpu/drm/kmb/Kconfig | 1 + drivers/gpu/drm/kmb/kmb_drv.c | 4 - drivers/gpu/drm/lima/lima_device.c | 1 - drivers/gpu/drm/lima/lima_gem.c | 29 +- drivers/gpu/drm/lima/lima_sched.c | 32 +- drivers/gpu/drm/lima/lima_sched.h | 6 +- drivers/gpu/drm/mcde/Kconfig | 1 + drivers/gpu/drm/mcde/mcde_drv.c | 4 +- drivers/gpu/drm/mcde/mcde_dsi.c | 4 +- drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 6 - drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 20 - drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 6 - drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 175 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 261 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 23 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 142 +- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 3 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +- drivers/gpu/drm/meson/Kconfig | 3 +- drivers/gpu/drm/meson/Makefile | 3 +- drivers/gpu/drm/meson/meson_drv.c | 74 +- drivers/gpu/drm/meson/meson_dw_hdmi.c | 346 +- drivers/gpu/drm/mga/mga_ioc32.c | 27 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 3 +- drivers/gpu/drm/mgag200/mgag200_drv.h | 2 + drivers/gpu/drm/mgag200/mgag200_mm.c | 35 +- drivers/gpu/drm/mgag200/mgag200_mode.c | 4 +- drivers/gpu/drm/msm/Kconfig | 6 +- drivers/gpu/drm/msm/Makefile | 15 +- drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 3 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 3 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 3 +- drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 10 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 55 +- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 29 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 17 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 10 + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 106 +- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 10 - drivers/gpu/drm/msm/adreno/a6xx_hfi.h | 11 - drivers/gpu/drm/msm/adreno/adreno_device.c | 56 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 7 - drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 188 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 24 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 61 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 4 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 17 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 14 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 13 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 - .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 285 +- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 95 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 56 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 13 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 98 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 44 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 214 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 53 +- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 25 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 570 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 4 + drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 18 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 89 - drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 40 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 68 +- drivers/gpu/drm/msm/disp/msm_disp_snapshot.c | 27 +- drivers/gpu/drm/msm/disp/msm_disp_snapshot.h | 14 +- .../gpu/drm/msm/disp/msm_disp_snapshot_util.c | 17 +- drivers/gpu/drm/msm/dp/dp_catalog.c | 64 +- drivers/gpu/drm/msm/dp/dp_ctrl.c | 23 +- drivers/gpu/drm/msm/dp/dp_debug.c | 304 +- drivers/gpu/drm/msm/dp/dp_debug.h | 4 +- drivers/gpu/drm/msm/dp/dp_display.c | 200 +- drivers/gpu/drm/msm/dp/dp_display.h | 3 - drivers/gpu/drm/msm/dp/dp_drm.c | 88 +- drivers/gpu/drm/msm/dp/dp_hpd.c | 2 + drivers/gpu/drm/msm/dp/dp_hpd.h | 2 + drivers/gpu/drm/msm/dp/dp_link.c | 19 +- drivers/gpu/drm/msm/dp/dp_panel.c | 2 +- drivers/gpu/drm/msm/dp/dp_parser.c | 138 +- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +- drivers/gpu/drm/msm/dsi/dsi.c | 68 +- drivers/gpu/drm/msm/dsi/dsi.h | 6 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 152 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 70 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 15 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 25 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 4 +- drivers/gpu/drm/msm/hdmi/hdmi.c | 57 +- drivers/gpu/drm/msm/hdmi/hdmi.h | 25 +- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 103 +- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 33 +- drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 4 +- drivers/gpu/drm/msm/msm_atomic.c | 21 +- drivers/gpu/drm/msm/msm_debugfs.c | 127 +- drivers/gpu/drm/msm/msm_drv.c | 153 +- drivers/gpu/drm/msm/msm_drv.h | 68 +- drivers/gpu/drm/msm/msm_fbdev.c | 13 +- drivers/gpu/drm/msm/msm_fence.h | 12 - drivers/gpu/drm/msm/msm_gem.c | 34 +- drivers/gpu/drm/msm/msm_gem.h | 5 + drivers/gpu/drm/msm/msm_gem_shrinker.c | 3 - drivers/gpu/drm/msm/msm_gem_submit.c | 35 +- drivers/gpu/drm/msm/msm_gpu.c | 25 +- drivers/gpu/drm/msm/msm_gpu.h | 70 +- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 140 +- drivers/gpu/drm/msm/msm_kms.h | 14 +- drivers/gpu/drm/msm/msm_perf.c | 9 +- drivers/gpu/drm/msm/msm_rd.c | 16 +- drivers/gpu/drm/msm/msm_ringbuffer.c | 16 +- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/Kbuild | 1 - drivers/gpu/drm/nouveau/dispnv50/base907c.c | 6 +- drivers/gpu/drm/nouveau/dispnv50/crc.c | 64 +- drivers/gpu/drm/nouveau/dispnv50/crc.h | 7 +- drivers/gpu/drm/nouveau/dispnv50/crc907d.c | 8 +- drivers/gpu/drm/nouveau/dispnv50/crcc37d.c | 45 +- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 15 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 11 +- drivers/gpu/drm/nouveau/dispnv50/head.c | 38 +- drivers/gpu/drm/nouveau/dispnv50/head.h | 2 - drivers/gpu/drm/nouveau/dispnv50/head907d.c | 6 - drivers/gpu/drm/nouveau/dispnv50/head917d.c | 1 - drivers/gpu/drm/nouveau/dispnv50/headc37d.c | 1 - drivers/gpu/drm/nouveau/dispnv50/headc57d.c | 3 +- drivers/gpu/drm/nouveau/dispnv50/wndw.c | 15 +- drivers/gpu/drm/nouveau/dispnv50/wndw.h | 4 +- drivers/gpu/drm/nouveau/dispnv50/wndwc37e.c | 6 +- drivers/gpu/drm/nouveau/dispnv50/wndwc57e.c | 7 +- .../drm/nouveau/include/nvhw/class/cl907d.h | 3 - .../drm/nouveau/include/nvhw/class/clc57d.h | 69 - drivers/gpu/drm/nouveau/nouveau_acpi.c | 9 +- drivers/gpu/drm/nouveau/nouveau_backlight.c | 5 +- drivers/gpu/drm/nouveau/nouveau_bios.c | 3 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 12 +- drivers/gpu/drm/nouveau/nouveau_display.c | 5 +- drivers/gpu/drm/nouveau/nouveau_dmem.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 4 +- drivers/gpu/drm/nouveau/nouveau_fence.c | 76 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 2 + drivers/gpu/drm/nouveau/nouveau_svm.c | 2 +- drivers/gpu/drm/nouveau/nvkm/core/client.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/device/user.c | 4 +- .../drm/nouveau/nvkm/engine/disp/coregv100.c | 2 - .../gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 2 +- .../gpu/drm/nouveau/nvkm/engine/nvenc/base.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/bios/init.c | 2 +- .../drm/nouveau/nvkm/subdev/devinit/mcp89.c | 3 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c | 2 +- .../drm/nouveau/nvkm/subdev/mmu/vmmgp100.c | 4 +- drivers/gpu/drm/omapdrm/Kconfig | 3 +- drivers/gpu/drm/omapdrm/Makefile | 1 - drivers/gpu/drm/omapdrm/dss/dispc.c | 44 +- drivers/gpu/drm/omapdrm/dss/dsi.c | 18 +- drivers/gpu/drm/omapdrm/dss/dss.c | 11 +- drivers/gpu/drm/omapdrm/dss/dss.h | 5 - drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 14 +- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.h | 14 +- drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 4 +- drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 5 +- drivers/gpu/drm/omapdrm/dss/hdmi_phy.c | 5 +- drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 4 +- drivers/gpu/drm/omapdrm/dss/venc.c | 11 +- drivers/gpu/drm/omapdrm/dss/video-pll.c | 8 +- drivers/gpu/drm/omapdrm/omap_dmm_priv.h | 10 +- drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 10 +- drivers/gpu/drm/omapdrm/omap_dmm_tiler.h | 10 +- drivers/gpu/drm/omapdrm/omap_drv.c | 198 +- drivers/gpu/drm/omapdrm/omap_drv.h | 24 - drivers/gpu/drm/omapdrm/omap_fb.c | 33 +- drivers/gpu/drm/omapdrm/omap_fb.h | 4 +- drivers/gpu/drm/omapdrm/omap_gem.c | 79 +- drivers/gpu/drm/omapdrm/omap_gem.h | 2 - drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | 36 +- drivers/gpu/drm/omapdrm/omap_plane.c | 351 +- drivers/gpu/drm/omapdrm/omap_plane.h | 1 - drivers/gpu/drm/omapdrm/tcm-sita.c | 10 +- drivers/gpu/drm/panel/Kconfig | 98 +- drivers/gpu/drm/panel/Makefile | 7 - drivers/gpu/drm/panel/panel-abt-y030xx067a.c | 14 +- .../gpu/drm/panel/panel-boe-tv101wum-nl6.c | 783 +-- drivers/gpu/drm/panel/panel-dsi-cm.c | 4 +- .../gpu/drm/panel/panel-feixin-k101-im2ba02.c | 13 +- .../drm/panel/panel-feiyang-fy07024di26a30d.c | 21 +- drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 275 +- drivers/gpu/drm/panel/panel-innolux-ej030na.c | 14 +- drivers/gpu/drm/panel/panel-lvds.c | 18 +- .../gpu/drm/panel/panel-mantix-mlaf057we51.c | 9 - .../gpu/drm/panel/panel-novatek-nt36672a.c | 2 +- drivers/gpu/drm/panel/panel-novatek-nt39016.c | 20 +- .../gpu/drm/panel/panel-orisetech-otm8009a.c | 83 +- .../gpu/drm/panel/panel-samsung-s6e63j0x03.c | 21 +- .../gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 3 +- .../gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 3 +- drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 4 +- drivers/gpu/drm/panel/panel-samsung-s6e63m0.h | 2 +- drivers/gpu/drm/panel/panel-samsung-sofef00.c | 16 +- .../gpu/drm/panel/panel-sharp-ls037v7dw01.c | 21 +- drivers/gpu/drm/panel/panel-simple.c | 1205 ++++- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 8 - drivers/gpu/drm/panel/panel-tpo-td043mtea1.c | 14 +- .../gpu/drm/panel/panel-xinpeng-xpp055c272.c | 25 +- drivers/gpu/drm/panfrost/panfrost_device.c | 10 +- drivers/gpu/drm/panfrost/panfrost_drv.c | 35 +- drivers/gpu/drm/panfrost/panfrost_gem.c | 22 +- .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 2 +- drivers/gpu/drm/panfrost/panfrost_job.c | 48 +- drivers/gpu/drm/panfrost/panfrost_job.h | 5 +- drivers/gpu/drm/panfrost/panfrost_mmu.c | 47 +- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 10 +- drivers/gpu/drm/pl111/Kconfig | 1 + drivers/gpu/drm/qxl/qxl_debugfs.c | 15 +- drivers/gpu/drm/qxl/qxl_drv.c | 3 +- drivers/gpu/drm/qxl/qxl_release.c | 4 +- drivers/gpu/drm/qxl/qxl_ttm.c | 1 + drivers/gpu/drm/r128/ati_pcigart.c | 11 +- drivers/gpu/drm/radeon/atombios.h | 2 +- drivers/gpu/drm/radeon/ci_dpm.c | 3 +- drivers/gpu/drm/radeon/r600_dpm.c | 10 +- drivers/gpu/drm/radeon/radeon_dp_mst.c | 4 +- drivers/gpu/drm/radeon/radeon_drv.c | 9 +- drivers/gpu/drm/radeon/radeon_fence.c | 24 +- drivers/gpu/drm/radeon/radeon_kms.c | 2 +- drivers/gpu/drm/radeon/radeon_sync.c | 22 +- drivers/gpu/drm/radeon/radeon_ttm.c | 15 +- drivers/gpu/drm/radeon/radeon_uvd.c | 19 +- drivers/gpu/drm/radeon/radeon_vce.c | 2 +- drivers/gpu/drm/rcar-du/Kconfig | 31 +- drivers/gpu/drm/rcar-du/Makefile | 1 - drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 20 +- drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 11 + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 110 +- drivers/gpu/drm/rcar-du/rcar_du_drv.h | 26 +- drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 12 +- drivers/gpu/drm/rcar-du/rcar_du_group.c | 6 +- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 50 +- drivers/gpu/drm/rcar-du/rcar_du_kms.h | 7 - drivers/gpu/drm/rcar-du/rcar_du_regs.h | 9 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 36 +- drivers/gpu/drm/rcar-du/rcar_lvds.c | 4 +- drivers/gpu/drm/rockchip/Kconfig | 1 + drivers/gpu/drm/rockchip/Makefile | 1 + .../gpu/drm/rockchip/analogix_dp-rockchip.c | 2 +- drivers/gpu/drm/rockchip/cdn-dp-core.c | 4 +- .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 3 +- drivers/gpu/drm/rockchip/inno_hdmi.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 37 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 + drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 44 +- drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 7 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +- drivers/gpu/drm/rockchip/rockchip_lvds.c | 33 +- drivers/gpu/drm/rockchip/rockchip_rgb.c | 26 +- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 2 +- drivers/gpu/drm/scheduler/sched_entity.c | 157 +- drivers/gpu/drm/scheduler/sched_fence.c | 64 +- drivers/gpu/drm/scheduler/sched_main.c | 189 +- drivers/gpu/drm/shmobile/Kconfig | 1 + drivers/gpu/drm/shmobile/shmob_drm_drv.c | 4 +- drivers/gpu/drm/sti/Kconfig | 1 + drivers/gpu/drm/sti/sti_hqvdp.c | 4 +- drivers/gpu/drm/stm/Kconfig | 1 + drivers/gpu/drm/stm/ltdc.c | 7 +- drivers/gpu/drm/sun4i/Kconfig | 1 + drivers/gpu/drm/sun4i/sun4i_backend.c | 4 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +- drivers/gpu/drm/sun4i/sun4i_frontend.c | 4 +- drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 4 +- drivers/gpu/drm/sun4i/sun4i_tcon.c | 4 +- drivers/gpu/drm/sun4i/sun4i_tv.c | 4 +- drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 18 +- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 21 +- drivers/gpu/drm/sun4i/sun8i_mixer.c | 4 +- drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 4 +- drivers/gpu/drm/tegra/Kconfig | 4 - drivers/gpu/drm/tegra/Makefile | 3 +- drivers/gpu/drm/tegra/dc.c | 194 +- drivers/gpu/drm/tegra/dc.h | 3 - drivers/gpu/drm/tegra/dpaux.c | 7 - drivers/gpu/drm/tegra/drm.c | 15 +- drivers/gpu/drm/tegra/drm.h | 1 - drivers/gpu/drm/tegra/falcon.c | 2 +- drivers/gpu/drm/tegra/fb.c | 2 +- drivers/gpu/drm/tegra/gem.c | 176 +- drivers/gpu/drm/tegra/gr2d.c | 174 +- drivers/gpu/drm/tegra/gr3d.c | 353 +- drivers/gpu/drm/tegra/hdmi.c | 183 +- drivers/gpu/drm/tegra/hub.h | 1 + drivers/gpu/drm/tegra/plane.c | 67 +- drivers/gpu/drm/tegra/plane.h | 2 +- drivers/gpu/drm/tegra/rgb.c | 53 +- drivers/gpu/drm/tegra/submit.c | 79 +- drivers/gpu/drm/tegra/uapi.c | 70 +- drivers/gpu/drm/tegra/uapi.h | 5 +- drivers/gpu/drm/tegra/vic.c | 54 +- drivers/gpu/drm/tidss/Kconfig | 1 + drivers/gpu/drm/tidss/tidss_drv.c | 13 +- drivers/gpu/drm/tilcdc/Kconfig | 1 + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 +- drivers/gpu/drm/tiny/Kconfig | 35 +- drivers/gpu/drm/tiny/Makefile | 1 - drivers/gpu/drm/tiny/bochs.c | 11 +- drivers/gpu/drm/tiny/cirrus.c | 28 +- drivers/gpu/drm/tiny/repaper.c | 2 +- drivers/gpu/drm/tiny/simpledrm.c | 41 +- drivers/gpu/drm/tiny/st7586.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 94 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 21 +- drivers/gpu/drm/ttm/ttm_bo_vm.c | 10 +- drivers/gpu/drm/ttm/ttm_device.c | 48 - drivers/gpu/drm/ttm/ttm_module.c | 16 +- drivers/gpu/drm/ttm/ttm_pool.c | 42 +- drivers/gpu/drm/ttm/ttm_range_manager.c | 19 +- drivers/gpu/drm/ttm/ttm_resource.c | 49 - drivers/gpu/drm/ttm/ttm_tt.c | 70 +- drivers/gpu/drm/tve200/Kconfig | 1 + drivers/gpu/drm/udl/Kconfig | 1 - drivers/gpu/drm/v3d/v3d_bo.c | 26 +- drivers/gpu/drm/v3d/v3d_drv.c | 15 +- drivers/gpu/drm/v3d/v3d_drv.h | 30 +- drivers/gpu/drm/v3d/v3d_gem.c | 469 +- drivers/gpu/drm/v3d/v3d_mmu.c | 2 + drivers/gpu/drm/v3d/v3d_sched.c | 44 +- drivers/gpu/drm/vboxvideo/vbox_drv.c | 10 +- drivers/gpu/drm/vboxvideo/vbox_drv.h | 1 + drivers/gpu/drm/vboxvideo/vbox_ttm.c | 17 +- drivers/gpu/drm/vc4/Kconfig | 1 + drivers/gpu/drm/vc4/vc4_bo.c | 10 +- drivers/gpu/drm/vc4/vc4_crtc.c | 38 +- drivers/gpu/drm/vc4/vc4_dpi.c | 15 +- drivers/gpu/drm/vc4/vc4_drv.c | 6 +- drivers/gpu/drm/vc4/vc4_dsi.c | 28 +- drivers/gpu/drm/vc4/vc4_hvs.c | 26 +- drivers/gpu/drm/vc4/vc4_kms.c | 39 +- drivers/gpu/drm/vc4/vc4_txp.c | 4 +- drivers/gpu/drm/vgem/vgem_drv.c | 350 +- drivers/gpu/drm/virtio/virtgpu_debugfs.c | 1 - drivers/gpu/drm/virtio/virtgpu_display.c | 4 +- drivers/gpu/drm/virtio/virtgpu_drv.c | 6 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 35 +- drivers/gpu/drm/virtio/virtgpu_fence.c | 30 +- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 195 +- drivers/gpu/drm/virtio/virtgpu_kms.c | 28 +- drivers/gpu/drm/virtio/virtgpu_object.c | 29 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 3 +- drivers/gpu/drm/virtio/virtgpu_prime.c | 32 +- drivers/gpu/drm/virtio/virtgpu_vq.c | 19 +- drivers/gpu/drm/virtio/virtgpu_vram.c | 61 - drivers/gpu/drm/vmwgfx/Kconfig | 1 - drivers/gpu/drm/vmwgfx/Makefile | 5 +- .../drm/vmwgfx/device_include/svga3d_cmd.h | 6 +- .../vmwgfx/device_include/svga3d_devcaps.h | 10 +- .../gpu/drm/vmwgfx/device_include/svga3d_dx.h | 12 +- .../drm/vmwgfx/device_include/svga3d_limits.h | 8 +- .../drm/vmwgfx/device_include/svga3d_reg.h | 6 +- .../drm/vmwgfx/device_include/svga3d_types.h | 7 +- .../drm/vmwgfx/device_include/svga_escape.h | 6 +- .../drm/vmwgfx/device_include/svga_overlay.h | 6 +- .../gpu/drm/vmwgfx/device_include/svga_reg.h | 14 +- drivers/gpu/drm/vmwgfx/ttm_memory.c | 99 +- drivers/gpu/drm/vmwgfx/ttm_memory.h | 6 +- drivers/gpu/drm/vmwgfx/ttm_object.c | 183 +- drivers/gpu/drm/vmwgfx/ttm_object.h | 59 +- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 45 +- drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 603 ++- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c | 43 +- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 30 +- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 26 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 56 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 134 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 84 +- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 13 +- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 43 +- drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 16 +- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 3 - drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 45 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 13 +- drivers/gpu/drm/vmwgfx/vmwgfx_msg.c | 6 +- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 20 +- drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 17 +- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 10 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 91 +- .../gpu/drm/vmwgfx/vmwgfx_simple_resource.c | 29 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 21 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.h | 6 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c | 21 + drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 162 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 87 +- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 74 +- drivers/gpu/drm/vmwgfx/vmwgfx_va.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 35 +- drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 53 +- drivers/gpu/drm/xen/xen_drm_front.c | 17 +- drivers/gpu/drm/xen/xen_drm_front_gem.c | 108 +- drivers/gpu/drm/xen/xen_drm_front_gem.h | 7 + drivers/gpu/drm/xlnx/Kconfig | 1 + drivers/gpu/drm/xlnx/zynqmp_disp.c | 9 +- drivers/gpu/host1x/bus.c | 80 +- drivers/gpu/host1x/channel.c | 8 - drivers/gpu/host1x/debug.c | 15 - drivers/gpu/host1x/dev.c | 170 +- drivers/gpu/host1x/dev.h | 5 +- drivers/gpu/host1x/hw/channel_hw.c | 44 +- drivers/gpu/host1x/intr.c | 3 + drivers/gpu/host1x/job.c | 164 +- drivers/gpu/host1x/job.h | 6 +- drivers/gpu/host1x/syncpt.c | 21 +- drivers/gpu/ipu-v3/ipu-csi.c | 31 +- drivers/greybus/es2.c | 2 +- drivers/hid/Kconfig | 46 - drivers/hid/Makefile | 3 - drivers/hid/amd-sfh-hid/amd_sfh_client.c | 3 +- drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 2 - drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 2 - drivers/hid/amd-sfh-hid/amd_sfh_pcie.c | 24 +- drivers/hid/amd-sfh-hid/amd_sfh_pcie.h | 3 +- .../hid_descriptor/amd_sfh_hid_desc.c | 3 +- .../hid_descriptor/amd_sfh_hid_desc.h | 3 +- .../hid_descriptor/amd_sfh_hid_report_desc.h | 3 +- drivers/hid/hid-apple.c | 216 +- drivers/hid/hid-core.c | 93 - drivers/hid/hid-cougar.c | 3 +- drivers/hid/hid-cp2112.c | 14 +- drivers/hid/hid-debug.c | 50 +- drivers/hid/hid-ft260.c | 11 +- drivers/hid/hid-ids.h | 23 +- drivers/hid/hid-input.c | 26 +- drivers/hid/hid-magicmouse.c | 20 +- drivers/hid/hid-multitouch.c | 8 +- drivers/hid/hid-playstation.c | 159 +- drivers/hid/hid-quirks.c | 4 +- drivers/hid/hid-roccat-kone.c | 2 +- drivers/hid/hid-roccat-kone.h | 12 +- drivers/hid/hid-thrustmaster.c | 6 +- drivers/hid/hid-tmff.c | 8 +- drivers/hid/hid-u2fzero.c | 45 +- drivers/hid/hid-vivaldi.c | 7 +- drivers/hid/hidraw.c | 34 +- drivers/hid/i2c-hid/i2c-hid-core.c | 20 +- drivers/hid/intel-ish-hid/ipc/ipc.c | 6 +- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 17 +- drivers/hid/intel-ish-hid/ishtp-hid-client.c | 14 +- drivers/hid/intel-ish-hid/ishtp/bus.c | 6 +- drivers/hid/surface-hid/surface_hid_core.c | 25 +- drivers/hid/uhid.c | 20 +- drivers/hid/usbhid/hid-core.c | 19 +- drivers/hid/wacom_sys.c | 15 +- drivers/hsi/clients/cmt_speech.c | 4 +- drivers/hsi/clients/ssi_protocol.c | 4 +- drivers/hv/Kconfig | 2 - drivers/hv/channel.c | 72 +- drivers/hv/channel_mgmt.c | 36 +- drivers/hv/connection.c | 101 +- drivers/hv/hv.c | 82 +- drivers/hv/hv_common.c | 27 +- drivers/hv/hv_utils_transport.c | 2 +- drivers/hv/hyperv_vmbus.h | 2 - drivers/hv/ring_buffer.c | 57 +- drivers/hv/vmbus_drv.c | 6 +- drivers/hwmon/Kconfig | 64 +- drivers/hwmon/Makefile | 5 - drivers/hwmon/abituguru3.c | 6 +- drivers/hwmon/acpi_power_meter.c | 13 +- drivers/hwmon/ad7414.c | 4 +- drivers/hwmon/ad7418.c | 6 +- drivers/hwmon/adm1021.c | 27 +- drivers/hwmon/adm1025.c | 4 +- drivers/hwmon/adm1026.c | 4 +- drivers/hwmon/adm1029.c | 4 +- drivers/hwmon/adm1031.c | 9 +- drivers/hwmon/adt7310.c | 3 +- drivers/hwmon/adt7410.c | 3 +- drivers/hwmon/adt7x10.c | 3 +- drivers/hwmon/adt7x10.h | 2 +- drivers/hwmon/amc6821.c | 8 +- drivers/hwmon/applesmc.c | 2 +- drivers/hwmon/asb100.c | 4 +- drivers/hwmon/asc7621.c | 4 +- drivers/hwmon/atxp1.c | 10 +- drivers/hwmon/coretemp.c | 2 +- drivers/hwmon/dell-smm-hwmon.c | 161 +- drivers/hwmon/dme1737.c | 4 +- drivers/hwmon/ds1621.c | 4 +- drivers/hwmon/ds620.c | 4 +- drivers/hwmon/emc6w201.c | 4 +- drivers/hwmon/f71805f.c | 4 +- drivers/hwmon/f71882fg.c | 6 +- drivers/hwmon/f75375s.c | 4 +- drivers/hwmon/fschmd.c | 4 +- drivers/hwmon/g760a.c | 2 +- drivers/hwmon/gl518sm.c | 4 +- drivers/hwmon/gl520sm.c | 4 +- drivers/hwmon/i5500_temp.c | 118 +- drivers/hwmon/ibmpex.c | 4 +- drivers/hwmon/it87.c | 12 +- drivers/hwmon/jc42.c | 4 - drivers/hwmon/k10temp.c | 36 +- drivers/hwmon/lineage-pem.c | 2 +- drivers/hwmon/lm63.c | 6 +- drivers/hwmon/lm77.c | 4 +- drivers/hwmon/lm78.c | 4 +- drivers/hwmon/lm80.c | 6 +- drivers/hwmon/lm83.c | 4 +- drivers/hwmon/lm85.c | 4 +- drivers/hwmon/lm87.c | 4 +- drivers/hwmon/lm92.c | 4 +- drivers/hwmon/lm93.c | 4 +- drivers/hwmon/lm95241.c | 8 +- drivers/hwmon/ltc2992.c | 3 +- drivers/hwmon/ltc4151.c | 2 +- drivers/hwmon/ltc4215.c | 2 +- drivers/hwmon/ltc4261.c | 4 +- drivers/hwmon/max16065.c | 2 +- drivers/hwmon/max1619.c | 4 +- drivers/hwmon/max1668.c | 4 +- drivers/hwmon/max31722.c | 8 +- drivers/hwmon/max6639.c | 4 +- drivers/hwmon/max6642.c | 2 +- drivers/hwmon/mlxreg-fan.c | 138 +- drivers/hwmon/nct6683.c | 3 - drivers/hwmon/nct6775.c | 729 +-- drivers/hwmon/nct7802.c | 131 +- drivers/hwmon/ntc_thermistor.c | 301 +- drivers/hwmon/occ/common.c | 30 +- drivers/hwmon/occ/p8_i2c.c | 15 +- drivers/hwmon/occ/p9_sbe.c | 91 +- drivers/hwmon/pc87360.c | 4 +- drivers/hwmon/pmbus/Kconfig | 29 +- drivers/hwmon/pmbus/Makefile | 2 - drivers/hwmon/pmbus/ibm-cffps.c | 23 +- drivers/hwmon/pmbus/ir38064.c | 28 +- drivers/hwmon/pmbus/lm25066.c | 65 +- drivers/hwmon/pmbus/pmbus_core.c | 5 - drivers/hwmon/raspberrypi-hwmon.c | 9 +- drivers/hwmon/sch5636.c | 4 +- drivers/hwmon/sht21.c | 4 +- drivers/hwmon/sht4x.c | 11 +- drivers/hwmon/sis5595.c | 4 +- drivers/hwmon/smm665.c | 2 +- drivers/hwmon/smsc47b397.c | 4 +- drivers/hwmon/smsc47m192.c | 4 +- drivers/hwmon/thmc50.c | 4 +- drivers/hwmon/tmp103.c | 103 +- drivers/hwmon/tmp401.c | 906 ++-- drivers/hwmon/tmp421.c | 186 +- drivers/hwmon/via686a.c | 4 +- drivers/hwmon/vt1211.c | 4 +- drivers/hwmon/vt8231.c | 4 +- drivers/hwmon/w83627ehf.c | 8 +- drivers/hwmon/w83627hf.c | 6 +- drivers/hwmon/w83781d.c | 4 +- drivers/hwmon/w83791d.c | 4 +- drivers/hwmon/w83792d.c | 6 +- drivers/hwmon/w83793.c | 6 +- drivers/hwmon/w83795.c | 6 +- drivers/hwmon/w83l785ts.c | 4 +- drivers/hwmon/w83l786ng.c | 4 +- drivers/hwmon/xgene-hwmon.c | 41 +- drivers/hwspinlock/stm32_hwspinlock.c | 62 +- drivers/hwtracing/coresight/Kconfig | 13 - .../coresight/coresight-cfg-preload.c | 9 +- .../hwtracing/coresight/coresight-config.h | 9 +- drivers/hwtracing/coresight/coresight-core.c | 2 +- .../hwtracing/coresight/coresight-cpu-debug.c | 2 +- drivers/hwtracing/coresight/coresight-etb10.c | 5 +- .../hwtracing/coresight/coresight-etm-perf.c | 56 +- .../coresight/coresight-etm4x-core.c | 112 +- drivers/hwtracing/coresight/coresight-etm4x.h | 9 +- drivers/hwtracing/coresight/coresight-stm.c | 10 +- .../coresight/coresight-syscfg-configfs.c | 87 - .../coresight/coresight-syscfg-configfs.h | 4 - .../hwtracing/coresight/coresight-syscfg.c | 315 +- .../hwtracing/coresight/coresight-syscfg.h | 39 +- .../hwtracing/coresight/coresight-tmc-core.c | 21 +- .../hwtracing/coresight/coresight-tmc-etf.c | 10 +- .../hwtracing/coresight/coresight-tmc-etr.c | 52 +- drivers/hwtracing/coresight/coresight-tmc.h | 6 +- drivers/hwtracing/coresight/coresight-trbe.c | 524 +- drivers/i2c/busses/Kconfig | 44 +- drivers/i2c/busses/Makefile | 4 +- drivers/i2c/busses/i2c-amd-mp2-pci.c | 4 +- drivers/i2c/busses/i2c-amd-mp2-plat.c | 5 +- drivers/i2c/busses/i2c-aspeed.c | 2 + drivers/i2c/busses/i2c-bcm-kona.c | 2 +- drivers/i2c/busses/i2c-bcm2835.c | 11 +- drivers/i2c/busses/i2c-designware-core.h | 13 +- drivers/i2c/busses/i2c-designware-master.c | 7 +- drivers/i2c/busses/i2c-designware-pcidrv.c | 43 +- drivers/i2c/busses/i2c-designware-platdrv.c | 2 - drivers/i2c/busses/i2c-exynos5.c | 110 +- drivers/i2c/busses/i2c-i801.c | 379 +- drivers/i2c/busses/i2c-imx.c | 92 +- drivers/i2c/busses/i2c-ismt.c | 12 +- drivers/i2c/busses/i2c-kempld.c | 3 +- drivers/i2c/busses/i2c-mlxcpld.c | 14 +- drivers/i2c/busses/i2c-mt65xx.c | 80 - drivers/i2c/busses/i2c-pxa.c | 1 + drivers/i2c/busses/i2c-qup.c | 6 +- drivers/i2c/busses/i2c-rcar.c | 32 +- drivers/i2c/busses/i2c-riic.c | 10 +- drivers/i2c/busses/i2c-rk3x.c | 7 - drivers/i2c/busses/i2c-sh_mobile.c | 60 +- drivers/i2c/busses/i2c-stm32f7.c | 30 +- drivers/i2c/busses/i2c-tegra.c | 73 +- drivers/i2c/busses/i2c-virtio.c | 58 +- drivers/i2c/busses/i2c-xgene-slimpro.c | 33 +- drivers/i2c/busses/i2c-xiic.c | 161 +- drivers/i2c/busses/i2c-xlp9xx.c | 7 + drivers/i2c/busses/i2c-xlr.c | 6 +- drivers/i2c/i2c-core-acpi.c | 61 +- drivers/i2c/i2c-core-base.c | 9 +- drivers/i2c/muxes/i2c-mux-gpio.c | 53 +- drivers/i3c/master/mipi-i3c-hci/core.c | 2 +- drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +- drivers/i3c/master/mipi-i3c-hci/hci.h | 2 +- drivers/i3c/master/svc-i3c-master.c | 341 +- drivers/idle/intel_idle.c | 13 +- drivers/iio/Kconfig | 2 - drivers/iio/Makefile | 2 - drivers/iio/accel/Kconfig | 62 - drivers/iio/accel/Makefile | 6 - drivers/iio/accel/adxl372.c | 1 - drivers/iio/accel/bma180.c | 4 +- drivers/iio/accel/bma220_spi.c | 6 +- drivers/iio/accel/bma400.h | 2 +- drivers/iio/accel/bma400_core.c | 7 +- drivers/iio/accel/bma400_i2c.c | 4 +- drivers/iio/accel/bma400_spi.c | 4 +- drivers/iio/accel/bmc150-accel-core.c | 7 +- drivers/iio/accel/bmc150-accel-i2c.c | 4 +- drivers/iio/accel/bmc150-accel-spi.c | 4 +- drivers/iio/accel/bmc150-accel.h | 2 +- drivers/iio/accel/bmi088-accel-core.c | 4 +- drivers/iio/accel/bmi088-accel-spi.c | 4 +- drivers/iio/accel/bmi088-accel.h | 2 +- drivers/iio/accel/fxls8962af-core.c | 347 +- drivers/iio/accel/kxcjk-1013.c | 5 +- drivers/iio/accel/kxsd9-i2c.c | 4 +- drivers/iio/accel/kxsd9-spi.c | 4 +- drivers/iio/accel/kxsd9.c | 4 +- drivers/iio/accel/kxsd9.h | 2 +- drivers/iio/accel/mma7455.h | 2 +- drivers/iio/accel/mma7455_core.c | 7 +- drivers/iio/accel/mma7455_i2c.c | 4 +- drivers/iio/accel/mma7455_spi.c | 4 +- drivers/iio/accel/mma7660.c | 10 +- drivers/iio/accel/mma8452.c | 2 +- drivers/iio/accel/mma9553.c | 2 +- drivers/iio/accel/sca3000.c | 18 +- drivers/iio/accel/st_accel_core.c | 31 +- drivers/iio/accel/st_accel_i2c.c | 23 +- drivers/iio/accel/st_accel_spi.c | 23 +- drivers/iio/accel/stk8312.c | 2 +- drivers/iio/accel/stk8ba50.c | 3 +- drivers/iio/adc/Kconfig | 39 +- drivers/iio/adc/Makefile | 2 - drivers/iio/adc/ab8500-gpadc.c | 22 +- drivers/iio/adc/ad7124.c | 2 +- drivers/iio/adc/ad7192.c | 3 +- drivers/iio/adc/ad7266.c | 3 +- drivers/iio/adc/ad7291.c | 80 +- drivers/iio/adc/ad7606.h | 2 +- drivers/iio/adc/ad7949.c | 254 +- drivers/iio/adc/ad799x.c | 68 +- drivers/iio/adc/ad_sigma_delta.c | 4 + drivers/iio/adc/aspeed_adc.c | 592 +-- drivers/iio/adc/at91-sama5d2_adc.c | 636 +-- drivers/iio/adc/axp20x_adc.c | 45 +- drivers/iio/adc/axp288_adc.c | 28 +- drivers/iio/adc/berlin2-adc.c | 34 +- drivers/iio/adc/da9150-gpadc.c | 27 +- drivers/iio/adc/envelope-detector.c | 3 +- drivers/iio/adc/ep93xx_adc.c | 4 +- drivers/iio/adc/fsl-imx25-gcq.c | 55 +- drivers/iio/adc/hi8435.c | 2 +- drivers/iio/adc/imx7d_adc.c | 23 +- drivers/iio/adc/ina2xx-adc.c | 15 +- drivers/iio/adc/intel_mrfld_adc.c | 24 +- drivers/iio/adc/lp8788_adc.c | 31 +- drivers/iio/adc/lpc18xx_adc.c | 81 +- drivers/iio/adc/max1027.c | 286 +- drivers/iio/adc/max1118.c | 7 +- drivers/iio/adc/max1241.c | 17 +- drivers/iio/adc/max1363.c | 82 +- drivers/iio/adc/max9611.c | 20 +- drivers/iio/adc/mcp3911.c | 9 +- drivers/iio/adc/meson_saradc.c | 39 +- drivers/iio/adc/nau7802.c | 50 +- drivers/iio/adc/qcom-pm8xxx-xoadc.c | 9 +- drivers/iio/adc/rcar-gyroadc.c | 3 +- drivers/iio/adc/rn5t618-adc.c | 13 +- drivers/iio/adc/rockchip_saradc.c | 31 +- drivers/iio/adc/rzg2l_adc.c | 4 +- drivers/iio/adc/stm32-adc-core.c | 1 - drivers/iio/adc/stm32-adc-core.h | 10 - drivers/iio/adc/stm32-adc.c | 465 +- drivers/iio/adc/stmpe-adc.c | 5 +- drivers/iio/adc/ti-adc108s102.c | 11 +- drivers/iio/adc/ti-adc12138.c | 14 +- drivers/iio/adc/ti-adc128s052.c | 33 +- drivers/iio/adc/ti-ads1015.c | 10 +- drivers/iio/adc/ti-ads124s08.c | 3 +- drivers/iio/adc/ti-ads7950.c | 4 +- drivers/iio/adc/ti-ads8344.c | 29 +- drivers/iio/adc/ti-ads8688.c | 4 +- drivers/iio/adc/ti_am335x_adc.c | 220 +- drivers/iio/adc/twl6030-gpadc.c | 6 +- drivers/iio/adc/xilinx-xadc-core.c | 67 +- drivers/iio/adc/xilinx-xadc.h | 1 + drivers/iio/amplifiers/hmc425a.c | 2 +- .../buffer/industrialio-buffer-dmaengine.c | 2 +- .../buffer/industrialio-triggered-buffer.c | 8 +- drivers/iio/buffer/kfifo_buf.c | 50 - drivers/iio/chemical/Kconfig | 24 - drivers/iio/chemical/Makefile | 2 - drivers/iio/chemical/atlas-sensor.c | 4 + drivers/iio/chemical/vz89x.c | 2 +- .../cros_ec_sensors/cros_ec_sensors_core.c | 3 +- .../common/hid-sensors/hid-sensor-trigger.c | 5 +- drivers/iio/common/scmi_sensors/scmi_iio.c | 57 +- .../iio/common/st_sensors/st_sensors_core.c | 52 +- .../iio/common/st_sensors/st_sensors_i2c.c | 1 + .../iio/common/st_sensors/st_sensors_spi.c | 1 + .../common/st_sensors/st_sensors_trigger.c | 53 +- drivers/iio/dac/Kconfig | 22 +- drivers/iio/dac/Makefile | 2 - drivers/iio/dac/ad5064.c | 53 +- drivers/iio/dac/ad5380.c | 17 +- drivers/iio/dac/ad5446.c | 14 +- drivers/iio/dac/ad5504.c | 2 +- drivers/iio/dac/ad5592r-base.c | 4 +- drivers/iio/dac/ad5592r-base.h | 2 +- drivers/iio/dac/ad5592r.c | 4 +- drivers/iio/dac/ad5593r.c | 4 +- drivers/iio/dac/ad5624r_spi.c | 2 +- drivers/iio/dac/ad5686-spi.c | 4 +- drivers/iio/dac/ad5686.c | 6 +- drivers/iio/dac/ad5686.h | 2 +- drivers/iio/dac/ad5696-i2c.c | 4 +- drivers/iio/dac/ad5755.c | 152 +- drivers/iio/dac/ad5758.c | 3 +- drivers/iio/dac/ad5766.c | 55 +- drivers/iio/dac/ad5791.c | 2 +- drivers/iio/dac/ad7303.c | 47 +- drivers/iio/dac/ad8801.c | 11 +- drivers/iio/dac/dpot-dac.c | 2 +- drivers/iio/dac/ds4424.c | 9 +- drivers/iio/dac/ltc1660.c | 7 +- drivers/iio/dac/max5821.c | 11 +- drivers/iio/dac/mcp4725.c | 10 +- drivers/iio/dac/mcp4922.c | 7 +- drivers/iio/dac/stm32-dac-core.c | 18 +- drivers/iio/dac/stm32-dac.c | 2 +- drivers/iio/dac/ti-dac082s085.c | 2 +- drivers/iio/dac/ti-dac5571.c | 2 +- drivers/iio/dac/ti-dac7311.c | 9 +- drivers/iio/dummy/iio_simple_dummy_buffer.c | 2 + drivers/iio/frequency/Kconfig | 22 - drivers/iio/frequency/Makefile | 2 - drivers/iio/gyro/Kconfig | 1 + drivers/iio/gyro/adis16080.c | 11 +- drivers/iio/gyro/mpu3050-core.c | 24 +- drivers/iio/gyro/st_gyro_core.c | 27 +- drivers/iio/gyro/st_gyro_i2c.c | 23 +- drivers/iio/gyro/st_gyro_spi.c | 23 +- drivers/iio/health/afe4403.c | 19 +- drivers/iio/health/afe4404.c | 13 +- drivers/iio/iio_core.h | 6 +- drivers/iio/imu/adis.c | 15 +- drivers/iio/imu/adis16400.c | 20 +- drivers/iio/imu/adis16460.c | 18 +- drivers/iio/imu/adis16475.c | 19 +- drivers/iio/imu/adis_trigger.c | 4 - .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 2 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 2 +- drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 4 +- drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c | 36 +- drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 4 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 20 +- drivers/iio/imu/st_lsm9ds0/st_lsm9ds0.h | 1 + drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_core.c | 29 +- drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c | 6 + drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c | 6 + drivers/iio/industrialio-buffer.c | 193 +- drivers/iio/industrialio-core.c | 7 +- drivers/iio/inkern.c | 17 - drivers/iio/light/cm3605.c | 35 +- drivers/iio/light/cm36651.c | 7 +- drivers/iio/light/gp2ap002.c | 24 +- drivers/iio/light/gp2ap020a00f.c | 5 + drivers/iio/light/ltr501.c | 79 +- drivers/iio/light/max44000.c | 17 +- drivers/iio/light/noa1305.c | 7 +- drivers/iio/magnetometer/Kconfig | 2 +- drivers/iio/magnetometer/ak8975.c | 37 +- drivers/iio/magnetometer/hmc5843.h | 2 +- drivers/iio/magnetometer/hmc5843_core.c | 8 +- drivers/iio/magnetometer/hmc5843_i2c.c | 4 +- drivers/iio/magnetometer/hmc5843_spi.c | 4 +- drivers/iio/magnetometer/mag3110.c | 6 +- drivers/iio/magnetometer/st_magn_core.c | 29 +- drivers/iio/magnetometer/st_magn_i2c.c | 23 +- drivers/iio/magnetometer/st_magn_spi.c | 23 +- drivers/iio/multiplexer/iio-mux.c | 7 +- drivers/iio/potentiometer/max5487.c | 7 +- drivers/iio/potentiometer/mcp41010.c | 6 +- drivers/iio/potentiostat/lmp91000.c | 4 + drivers/iio/pressure/bmp280-core.c | 11 +- drivers/iio/pressure/bmp280-i2c.c | 2 +- drivers/iio/pressure/bmp280-spi.c | 2 +- drivers/iio/pressure/mpl3115.c | 16 +- drivers/iio/pressure/ms5611.h | 8 +- drivers/iio/pressure/ms5611_core.c | 11 +- drivers/iio/pressure/ms5611_i2c.c | 15 +- drivers/iio/pressure/ms5611_spi.c | 21 +- drivers/iio/pressure/st_pressure_core.c | 27 +- drivers/iio/pressure/st_pressure_i2c.c | 23 +- drivers/iio/pressure/st_pressure_spi.c | 23 +- drivers/iio/proximity/as3935.c | 6 +- drivers/iio/temperature/Kconfig | 10 - drivers/iio/temperature/Makefile | 1 - drivers/iio/temperature/ltc2983.c | 16 - drivers/iio/test/iio-test-format.c | 123 +- drivers/iio/trigger/iio-trig-interrupt.c | 4 + drivers/iio/trigger/iio-trig-sysfs.c | 4 + drivers/iio/trigger/stm32-timer-trigger.c | 4 +- drivers/infiniband/core/cache.c | 13 +- drivers/infiniband/core/cma.c | 34 +- drivers/infiniband/core/cma_priv.h | 11 +- drivers/infiniband/core/counters.c | 40 +- drivers/infiniband/core/device.c | 1 - drivers/infiniband/core/iwpm_util.c | 2 +- drivers/infiniband/core/nldev.c | 279 +- drivers/infiniband/core/rw.c | 66 +- drivers/infiniband/core/sa_query.c | 1 + drivers/infiniband/core/sysfs.c | 57 +- drivers/infiniband/core/umem_dmabuf.c | 54 - drivers/infiniband/core/umem_odp.c | 3 +- drivers/infiniband/core/uverbs_cmd.c | 1 + drivers/infiniband/core/verbs.c | 49 - drivers/infiniband/hw/bnxt_re/bnxt_re.h | 19 +- drivers/infiniband/hw/bnxt_re/hw_counters.c | 380 +- drivers/infiniband/hw/bnxt_re/hw_counters.h | 30 +- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 42 +- drivers/infiniband/hw/bnxt_re/ib_verbs.h | 1 + drivers/infiniband/hw/bnxt_re/main.c | 19 +- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 23 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 12 +- drivers/infiniband/hw/bnxt_re/qplib_rcfw.h | 2 +- drivers/infiniband/hw/bnxt_re/qplib_res.c | 72 +- drivers/infiniband/hw/bnxt_re/qplib_res.h | 17 +- drivers/infiniband/hw/bnxt_re/qplib_sp.c | 156 +- drivers/infiniband/hw/bnxt_re/qplib_sp.h | 42 +- drivers/infiniband/hw/bnxt_re/roce_hsi.h | 85 - drivers/infiniband/hw/cxgb4/cm.c | 6 +- drivers/infiniband/hw/cxgb4/device.c | 1 + drivers/infiniband/hw/cxgb4/id_table.c | 17 +- drivers/infiniband/hw/cxgb4/provider.c | 30 +- drivers/infiniband/hw/efa/efa.h | 23 +- .../infiniband/hw/efa/efa_admin_cmds_defs.h | 100 +- drivers/infiniband/hw/efa/efa_admin_defs.h | 41 - drivers/infiniband/hw/efa/efa_com.c | 164 - drivers/infiniband/hw/efa/efa_com.h | 38 +- drivers/infiniband/hw/efa/efa_com_cmd.c | 35 +- drivers/infiniband/hw/efa/efa_com_cmd.h | 10 +- drivers/infiniband/hw/efa/efa_main.c | 182 +- drivers/infiniband/hw/efa/efa_regs_defs.h | 7 +- drivers/infiniband/hw/efa/efa_verbs.c | 213 +- drivers/infiniband/hw/hfi1/Kconfig | 4 +- drivers/infiniband/hw/hfi1/chip.c | 3 +- drivers/infiniband/hw/hfi1/driver.c | 3 +- drivers/infiniband/hw/hfi1/efivar.c | 10 +- drivers/infiniband/hw/hfi1/init.c | 3 +- drivers/infiniband/hw/hfi1/ipoib.h | 76 +- drivers/infiniband/hw/hfi1/ipoib_main.c | 2 +- drivers/infiniband/hw/hfi1/ipoib_tx.c | 350 +- drivers/infiniband/hw/hfi1/trace_tx.h | 71 +- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 5 +- drivers/infiniband/hw/hfi1/user_sdma.c | 8 +- drivers/infiniband/hw/hfi1/verbs.c | 52 +- drivers/infiniband/hw/hns/Kconfig | 17 +- drivers/infiniband/hw/hns/Makefile | 5 + drivers/infiniband/hw/hns/hns_roce_ah.c | 5 +- drivers/infiniband/hw/hns/hns_roce_alloc.c | 3 +- drivers/infiniband/hw/hns/hns_roce_cmd.c | 11 +- drivers/infiniband/hw/hns/hns_roce_common.h | 202 + drivers/infiniband/hw/hns/hns_roce_cq.c | 13 + drivers/infiniband/hw/hns/hns_roce_db.c | 1 + drivers/infiniband/hw/hns/hns_roce_device.h | 130 +- drivers/infiniband/hw/hns/hns_roce_hem.c | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 75 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 22 +- drivers/infiniband/hw/hns/hns_roce_main.c | 152 +- drivers/infiniband/hw/hns/hns_roce_mr.c | 32 +- drivers/infiniband/hw/hns/hns_roce_pd.c | 17 +- drivers/infiniband/hw/hns/hns_roce_qp.c | 93 +- drivers/infiniband/hw/irdma/cm.h | 12 +- drivers/infiniband/hw/irdma/ctrl.c | 45 +- drivers/infiniband/hw/irdma/hw.c | 27 +- drivers/infiniband/hw/irdma/i40iw_if.c | 2 +- drivers/infiniband/hw/irdma/main.c | 7 +- drivers/infiniband/hw/irdma/main.h | 5 +- drivers/infiniband/hw/irdma/osdep.h | 1 + drivers/infiniband/hw/irdma/pble.h | 2 +- drivers/infiniband/hw/irdma/protos.h | 2 + drivers/infiniband/hw/irdma/trace_cm.h | 8 +- drivers/infiniband/hw/irdma/type.h | 3 +- drivers/infiniband/hw/irdma/uda.c | 2 - drivers/infiniband/hw/irdma/uk.c | 101 +- drivers/infiniband/hw/irdma/user.h | 32 +- drivers/infiniband/hw/irdma/utils.c | 49 +- drivers/infiniband/hw/irdma/verbs.c | 175 +- drivers/infiniband/hw/mlx4/alias_GUID.c | 4 +- drivers/infiniband/hw/mlx4/main.c | 80 +- drivers/infiniband/hw/mlx4/mlx4_ib.h | 2 +- drivers/infiniband/hw/mlx4/qp.c | 2 +- drivers/infiniband/hw/mlx5/cmd.c | 26 - drivers/infiniband/hw/mlx5/cmd.h | 2 - drivers/infiniband/hw/mlx5/counters.c | 283 +- drivers/infiniband/hw/mlx5/cq.c | 5 +- drivers/infiniband/hw/mlx5/devx.c | 13 +- drivers/infiniband/hw/mlx5/devx.h | 2 +- drivers/infiniband/hw/mlx5/doorbell.c | 1 - drivers/infiniband/hw/mlx5/fs.c | 205 +- drivers/infiniband/hw/mlx5/mad.c | 23 +- drivers/infiniband/hw/mlx5/main.c | 63 +- drivers/infiniband/hw/mlx5/mlx5_ib.h | 74 +- drivers/infiniband/hw/mlx5/mr.c | 109 +- drivers/infiniband/hw/mlx5/odp.c | 83 +- drivers/infiniband/hw/mlx5/qp.c | 1 - drivers/infiniband/hw/mlx5/wr.c | 10 +- drivers/infiniband/hw/mthca/mthca_allocator.c | 15 +- drivers/infiniband/hw/mthca/mthca_mr.c | 25 +- drivers/infiniband/hw/mthca/mthca_provider.c | 20 +- drivers/infiniband/hw/ocrdma/ocrdma_hw.c | 16 +- drivers/infiniband/hw/ocrdma/ocrdma_main.c | 17 +- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 18 +- drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | 1 + drivers/infiniband/hw/qedr/main.c | 3 +- drivers/infiniband/hw/qedr/verbs.c | 10 + drivers/infiniband/hw/qedr/verbs.h | 1 + drivers/infiniband/hw/qib/qib.h | 2 +- drivers/infiniband/hw/qib/qib_driver.c | 5 +- drivers/infiniband/hw/qib/qib_file_ops.c | 2 +- drivers/infiniband/hw/qib/qib_iba6120.c | 2 +- drivers/infiniband/hw/qib/qib_iba7220.c | 2 +- drivers/infiniband/hw/qib/qib_iba7322.c | 2 +- drivers/infiniband/hw/qib/qib_verbs.c | 4 +- drivers/infiniband/hw/usnic/usnic_fwd.c | 2 +- drivers/infiniband/hw/usnic/usnic_fwd.h | 2 +- drivers/infiniband/hw/usnic/usnic_ib_sysfs.c | 3 +- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 +- .../hw/vmw_pvrdma/pvrdma_doorbell.c | 10 +- drivers/infiniband/sw/rxe/Makefile | 1 + drivers/infiniband/sw/rxe/rxe.c | 4 + drivers/infiniband/sw/rxe/rxe.h | 2 + drivers/infiniband/sw/rxe/rxe_av.c | 20 +- drivers/infiniband/sw/rxe/rxe_comp.c | 65 +- drivers/infiniband/sw/rxe/rxe_cq.c | 52 +- drivers/infiniband/sw/rxe/rxe_hw_counters.c | 42 +- drivers/infiniband/sw/rxe/rxe_loc.h | 11 +- drivers/infiniband/sw/rxe/rxe_mcast.c | 11 +- drivers/infiniband/sw/rxe/rxe_mr.c | 228 +- drivers/infiniband/sw/rxe/rxe_mw.c | 27 +- drivers/infiniband/sw/rxe/rxe_net.c | 9 +- drivers/infiniband/sw/rxe/rxe_opcode.c | 737 ++- drivers/infiniband/sw/rxe/rxe_opcode.h | 6 +- drivers/infiniband/sw/rxe/rxe_param.h | 32 +- drivers/infiniband/sw/rxe/rxe_pool.c | 204 +- drivers/infiniband/sw/rxe/rxe_pool.h | 69 +- drivers/infiniband/sw/rxe/rxe_qp.c | 25 +- drivers/infiniband/sw/rxe/rxe_queue.c | 39 +- drivers/infiniband/sw/rxe/rxe_queue.h | 374 +- drivers/infiniband/sw/rxe/rxe_req.c | 67 +- drivers/infiniband/sw/rxe/rxe_resp.c | 50 +- drivers/infiniband/sw/rxe/rxe_srq.c | 5 +- drivers/infiniband/sw/rxe/rxe_task.c | 18 +- drivers/infiniband/sw/rxe/rxe_verbs.c | 171 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 68 +- drivers/infiniband/sw/siw/siw_cm.c | 4 +- drivers/infiniband/sw/siw/siw_main.c | 7 +- drivers/infiniband/sw/siw/siw_verbs.c | 6 +- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 4 +- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 9 +- drivers/infiniband/ulp/ipoib/ipoib_main.c | 18 +- drivers/infiniband/ulp/iser/iscsi_iser.c | 76 +- drivers/infiniband/ulp/iser/iscsi_iser.h | 23 +- drivers/infiniband/ulp/iser/iser_initiator.c | 106 +- drivers/infiniband/ulp/iser/iser_memory.c | 58 +- drivers/infiniband/ulp/iser/iser_verbs.c | 138 +- drivers/infiniband/ulp/opa_vnic/Kconfig | 4 +- drivers/infiniband/ulp/opa_vnic/Makefile | 3 +- .../infiniband/ulp/opa_vnic/opa_vnic_vema.c | 7 +- drivers/infiniband/ulp/rtrs/rtrs-clt-stats.c | 66 +- drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c | 156 +- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 1087 +++-- drivers/infiniband/ulp/rtrs/rtrs-clt.h | 54 +- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 20 +- drivers/infiniband/ulp/rtrs/rtrs-srv-stats.c | 3 +- drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c | 123 +- drivers/infiniband/ulp/rtrs/rtrs-srv.c | 680 ++- drivers/infiniband/ulp/rtrs/rtrs-srv.h | 19 +- drivers/infiniband/ulp/rtrs/rtrs.c | 127 +- drivers/infiniband/ulp/rtrs/rtrs.h | 34 +- drivers/infiniband/ulp/srp/ib_srp.c | 59 +- drivers/infiniband/ulp/srpt/ib_srpt.c | 38 +- drivers/input/ff-core.c | 2 +- drivers/input/joydev.c | 10 - drivers/input/joystick/analog.c | 18 +- drivers/input/joystick/tmdc.c | 2 +- drivers/input/keyboard/Kconfig | 12 +- drivers/input/keyboard/Makefile | 1 - drivers/input/keyboard/cap11xx.c | 43 +- drivers/input/keyboard/ep93xx_keypad.c | 172 +- drivers/input/keyboard/gpio_keys.c | 2 +- drivers/input/keyboard/mpr121_touchkey.c | 4 +- drivers/input/keyboard/omap-keypad.c | 3 +- drivers/input/keyboard/tm2-touchkey.c | 7 - drivers/input/misc/adxl34x-i2c.c | 4 +- drivers/input/misc/adxl34x-spi.c | 4 +- drivers/input/misc/adxl34x.c | 6 +- drivers/input/misc/adxl34x.h | 2 +- drivers/input/misc/axp20x-pek.c | 98 +- drivers/input/misc/cpcap-pwrbutton.c | 7 +- drivers/input/misc/max77693-haptic.c | 1 + drivers/input/misc/max8925_onkey.c | 2 +- drivers/input/misc/palmas-pwrbutton.c | 14 +- drivers/input/misc/pm8941-pwrkey.c | 6 +- drivers/input/misc/xen-kbdfront.c | 1 - drivers/input/mouse/byd.c | 2 +- drivers/input/mouse/elan_i2c_core.c | 64 +- drivers/input/mouse/psmouse-smbus.c | 10 - drivers/input/rmi4/rmi_bus.c | 1 - drivers/input/serio/serport.c | 8 +- drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/Makefile | 3 +- drivers/input/touchscreen/ads7846.c | 200 +- drivers/input/touchscreen/elants_i2c.c | 4 +- drivers/input/touchscreen/goodix.c | 418 +- drivers/input/touchscreen/ili210x.c | 559 +-- drivers/input/touchscreen/raydium_i2c_ts.c | 54 +- drivers/input/touchscreen/silead.c | 172 +- drivers/input/touchscreen/st1232.c | 1 - drivers/input/touchscreen/ti_am335x_tsc.c | 12 +- drivers/input/touchscreen/tsc2004.c | 4 +- drivers/input/touchscreen/tsc2005.c | 4 +- drivers/input/touchscreen/tsc200x-core.c | 4 +- drivers/input/touchscreen/tsc200x-core.h | 2 +- drivers/input/touchscreen/ucb1400_ts.c | 4 +- drivers/input/touchscreen/wacom_i2c.c | 66 +- drivers/input/touchscreen/wm97xx-core.c | 12 +- drivers/input/touchscreen/zinitix.c | 34 +- drivers/interconnect/qcom/Kconfig | 27 - drivers/interconnect/qcom/Makefile | 6 - drivers/interconnect/qcom/icc-rpm.c | 314 +- drivers/interconnect/qcom/icc-rpm.h | 65 +- drivers/interconnect/qcom/msm8916.c | 1216 +---- drivers/interconnect/qcom/msm8939.c | 1286 +---- drivers/interconnect/qcom/osm-l3.c | 20 +- drivers/interconnect/qcom/qcs404.c | 967 +--- drivers/interconnect/qcom/sc7280.h | 2 - drivers/interconnect/qcom/sdm660.c | 1959 +++----- drivers/interconnect/qcom/sm8150.c | 1 + drivers/interconnect/qcom/sm8250.c | 1 + drivers/interconnect/qcom/sm8350.c | 1 + drivers/interconnect/samsung/Kconfig | 6 +- drivers/irqchip/Kconfig | 25 +- drivers/irqchip/Makefile | 1 - drivers/irqchip/irq-apple-aic.c | 23 +- drivers/irqchip/irq-armada-370-xp.c | 13 +- drivers/irqchip/irq-aspeed-vic.c | 2 +- drivers/irqchip/irq-ativic32.c | 22 +- drivers/irqchip/irq-atmel-aic.c | 2 +- drivers/irqchip/irq-atmel-aic5.c | 2 +- drivers/irqchip/irq-bcm2835.c | 2 +- drivers/irqchip/irq-bcm2836.c | 2 +- drivers/irqchip/irq-bcm6345-l1.c | 6 +- drivers/irqchip/irq-bcm7038-l1.c | 47 +- drivers/irqchip/irq-bcm7120-l2.c | 22 +- drivers/irqchip/irq-brcmstb-l2.c | 16 +- drivers/irqchip/irq-clps711x.c | 8 +- drivers/irqchip/irq-csky-apb-intc.c | 2 +- drivers/irqchip/irq-csky-mpintc.c | 12 +- drivers/irqchip/irq-davinci-aintc.c | 2 +- drivers/irqchip/irq-davinci-cp-intc.c | 2 +- drivers/irqchip/irq-digicolor.c | 2 +- drivers/irqchip/irq-dw-apb-ictl.c | 2 +- drivers/irqchip/irq-ftintc010.c | 2 +- drivers/irqchip/irq-gic-v2m.c | 3 +- drivers/irqchip/irq-gic-v3-its-pci-msi.c | 1 + drivers/irqchip/irq-gic-v3-its.c | 206 +- drivers/irqchip/irq-gic-v3-mbi.c | 1 + drivers/irqchip/irq-gic-v3.c | 5 +- drivers/irqchip/irq-gic.c | 2 +- drivers/irqchip/irq-hip04.c | 2 +- drivers/irqchip/irq-imx-gpcv2.c | 2 +- drivers/irqchip/irq-ingenic-tcu.c | 4 +- drivers/irqchip/irq-ixp4xx.c | 4 +- drivers/irqchip/irq-loongson-pch-msi.c | 2 +- drivers/irqchip/irq-lpc32xx.c | 2 +- drivers/irqchip/irq-mbigen.c | 4 +- drivers/irqchip/irq-meson-gpio.c | 15 +- drivers/irqchip/irq-mips-gic.c | 41 +- drivers/irqchip/irq-mmp.c | 4 +- drivers/irqchip/irq-mvebu-icu.c | 16 +- drivers/irqchip/irq-mvebu-pic.c | 4 +- drivers/irqchip/irq-mxs.c | 2 +- drivers/irqchip/irq-nvic.c | 17 +- drivers/irqchip/irq-omap-intc.c | 2 +- drivers/irqchip/irq-or1k-pic.c | 2 +- drivers/irqchip/irq-orion.c | 4 +- drivers/irqchip/irq-rda-intc.c | 2 +- drivers/irqchip/irq-renesas-intc-irqpin.c | 9 +- drivers/irqchip/irq-renesas-irqc.c | 9 +- drivers/irqchip/irq-riscv-intc.c | 2 +- drivers/irqchip/irq-sa11x0.c | 4 +- drivers/irqchip/irq-stm32-exti.c | 4 +- drivers/irqchip/irq-sun4i.c | 2 +- drivers/irqchip/irq-ti-sci-inta.c | 6 +- drivers/irqchip/irq-ts4800.c | 4 +- drivers/irqchip/irq-versatile-fpga.c | 2 +- drivers/irqchip/irq-vic.c | 2 +- drivers/irqchip/irq-vt8500.c | 2 +- drivers/irqchip/irq-wpcm450-aic.c | 2 +- drivers/irqchip/irq-zevio.c | 2 +- drivers/irqchip/spear-shirq.c | 2 - drivers/isdn/capi/kcapi.c | 2 +- drivers/leds/Kconfig | 10 +- drivers/leds/Makefile | 4 +- drivers/leds/blink/leds-lgm-sso.c | 1 + drivers/leds/flash/Kconfig | 13 - drivers/leds/flash/Makefile | 1 - drivers/leds/flash/leds-ktd2692.c | 2 +- drivers/leds/led-class.c | 6 +- drivers/leds/led-triggers.c | 41 +- drivers/leds/leds-lp50xx.c | 1 + drivers/leds/leds-tca6507.c | 7 +- drivers/leds/trigger/Kconfig | 1 - drivers/macintosh/mac_hid.c | 24 +- drivers/macintosh/mediabay.c | 2 +- drivers/macintosh/smu.c | 5 +- drivers/mailbox/Kconfig | 12 - drivers/mailbox/Makefile | 2 - drivers/mailbox/bcm-flexrm-mailbox.c | 13 +- drivers/mailbox/bcm2835-mailbox.c | 4 +- drivers/mailbox/hi3660-mailbox.c | 22 +- drivers/mailbox/hi6220-mailbox.c | 7 +- drivers/mailbox/imx-mailbox.c | 124 +- drivers/mailbox/mailbox-altera.c | 5 +- drivers/mailbox/mailbox-sti.c | 4 +- drivers/mailbox/mailbox-xgene-slimpro.c | 4 +- drivers/mailbox/mtk-cmdq-mailbox.c | 17 +- drivers/mailbox/omap-mailbox.c | 4 +- drivers/mailbox/pcc.c | 640 +-- drivers/mailbox/platform_mhu.c | 4 +- drivers/mailbox/qcom-apcs-ipc-mailbox.c | 31 +- drivers/mailbox/qcom-ipcc.c | 99 +- drivers/mailbox/stm32-ipcc.c | 4 +- drivers/mailbox/sun6i-msgbox.c | 9 +- drivers/mailbox/zynqmp-ipi-mailbox.c | 1 - drivers/md/Kconfig | 10 - drivers/md/Makefile | 4 - drivers/md/bcache/bcache.h | 6 +- drivers/md/bcache/bset.h | 2 +- drivers/md/bcache/btree.c | 2 +- drivers/md/bcache/debug.c | 15 +- drivers/md/bcache/features.c | 2 +- drivers/md/bcache/features.h | 3 +- drivers/md/bcache/io.c | 16 +- drivers/md/bcache/request.c | 19 +- drivers/md/bcache/request.h | 4 +- drivers/md/bcache/super.c | 92 +- drivers/md/bcache/sysfs.c | 2 +- drivers/md/bcache/sysfs.h | 18 +- drivers/md/bcache/util.h | 29 + drivers/md/bcache/writeback.c | 2 +- drivers/md/dm-bio-record.h | 1 - drivers/md/dm-bufio.c | 3 +- drivers/md/dm-cache-metadata.c | 2 +- drivers/md/dm-cache-target.c | 2 +- drivers/md/dm-clone-target.c | 2 +- drivers/md/dm-core.h | 4 +- drivers/md/dm-crypt.c | 26 +- drivers/md/dm-dust.c | 5 +- drivers/md/dm-ebs-target.c | 2 +- drivers/md/dm-era-target.c | 2 +- drivers/md/dm-exception-store.h | 2 +- drivers/md/dm-flakey.c | 3 +- drivers/md/dm-ima.c | 1 - drivers/md/dm-integrity.c | 50 +- drivers/md/dm-linear.c | 66 +- drivers/md/dm-log-writes.c | 118 +- drivers/md/dm-log.c | 2 +- drivers/md/dm-mpath.c | 7 +- drivers/md/dm-ps-historical-service-time.c | 1 - drivers/md/dm-raid.c | 6 +- drivers/md/dm-rq.c | 1 + drivers/md/dm-stripe.c | 89 +- drivers/md/dm-switch.c | 2 +- drivers/md/dm-sysfs.c | 3 +- drivers/md/dm-table.c | 200 +- drivers/md/dm-thin-metadata.c | 2 +- drivers/md/dm-thin.c | 2 +- drivers/md/dm-verity-target.c | 10 +- drivers/md/dm-writecache.c | 10 +- drivers/md/dm-zoned-target.c | 3 +- drivers/md/dm.c | 140 +- drivers/md/dm.h | 4 + drivers/md/md-bitmap.c | 19 - drivers/md/md-cluster.c | 2 +- drivers/md/md.c | 153 +- drivers/md/md.h | 2 +- drivers/md/persistent-data/dm-btree-remove.c | 173 +- drivers/md/persistent-data/dm-btree-spine.c | 12 +- drivers/md/raid1-10.c | 6 + drivers/md/raid1.c | 94 +- drivers/md/raid10.c | 109 +- drivers/md/raid5-ppl.c | 6 +- drivers/md/raid5.c | 33 +- drivers/md/raid5.h | 4 +- drivers/media/cec/Kconfig | 4 - drivers/media/cec/core/cec-adap.c | 8 +- drivers/media/cec/core/cec-api.c | 2 +- drivers/media/cec/core/cec-core.c | 2 +- drivers/media/cec/core/cec-pin-priv.h | 1 + drivers/media/cec/core/cec-pin.c | 5 +- .../media/cec/platform/meson/ao-cec-g12a.c | 4 +- drivers/media/cec/platform/meson/ao-cec.c | 4 +- drivers/media/cec/platform/s5p/s5p_cec.c | 4 +- drivers/media/cec/platform/sti/stih-cec.c | 4 +- drivers/media/cec/platform/stm32/stm32-cec.c | 4 +- drivers/media/common/b2c2/flexcop.c | 11 +- drivers/media/common/saa7146/saa7146_fops.c | 3 - drivers/media/common/siano/smscoreapi.c | 7 +- drivers/media/common/videobuf2/frame_vector.c | 15 +- .../media/common/videobuf2/videobuf2-core.c | 108 +- .../common/videobuf2/videobuf2-dma-contig.c | 168 +- .../media/common/videobuf2/videobuf2-dma-sg.c | 7 - .../media/common/videobuf2/videobuf2-v4l2.c | 59 +- .../common/videobuf2/videobuf2-vmalloc.c | 1 - drivers/media/dvb-core/dmxdev.c | 12 +- drivers/media/dvb-core/dvb_demux.c | 12 +- drivers/media/dvb-core/dvb_frontend.c | 21 +- drivers/media/dvb-core/dvb_net.c | 8 +- drivers/media/dvb-core/dvb_vb2.c | 6 +- drivers/media/dvb-core/dvbdev.c | 12 +- drivers/media/dvb-frontends/cx24113.c | 2 +- drivers/media/dvb-frontends/cxd2099.c | 9 + drivers/media/dvb-frontends/cxd2099.h | 9 + drivers/media/dvb-frontends/cxd2820r_priv.h | 2 +- .../dvb-frontends/cxd2880/cxd2880_common.h | 1 - drivers/media/dvb-frontends/dib9000.c | 4 +- drivers/media/dvb-frontends/drxd_hard.c | 8 + drivers/media/dvb-frontends/drxk_hard.c | 23 +- drivers/media/dvb-frontends/m88ds3103.c | 6 +- drivers/media/dvb-frontends/mb86a20s.c | 4 +- drivers/media/dvb-frontends/mxl5xx.c | 9 + drivers/media/dvb-frontends/mxl5xx.h | 9 + drivers/media/dvb-frontends/mxl5xx_defs.h | 4 + drivers/media/dvb-frontends/mxl5xx_regs.h | 10 + drivers/media/dvb-frontends/mxl692.c | 9 + drivers/media/dvb-frontends/mxl692.h | 9 + drivers/media/dvb-frontends/mxl692_defs.h | 9 + drivers/media/dvb-frontends/rtl2832_sdr.c | 5 +- drivers/media/dvb-frontends/si2168.c | 43 +- drivers/media/dvb-frontends/si2168_priv.h | 2 +- drivers/media/dvb-frontends/si21xx.c | 7 +- drivers/media/dvb-frontends/sp887x.c | 4 +- drivers/media/dvb-frontends/stb6100.c | 2 +- drivers/media/dvb-frontends/stv0367.c | 6 +- drivers/media/dvb-frontends/stv0910.c | 9 + drivers/media/dvb-frontends/stv0910.h | 9 + drivers/media/dvb-frontends/stv6111.c | 9 + drivers/media/dvb-frontends/stv6111.h | 9 + drivers/media/i2c/Kconfig | 38 - drivers/media/i2c/Makefile | 3 - drivers/media/i2c/adv7511-v4l2.c | 22 + drivers/media/i2c/adv7604.c | 33 +- drivers/media/i2c/adv7842.c | 10 + drivers/media/i2c/ccs/ccs-core.c | 12 +- drivers/media/i2c/cx25840/cx25840-ir.c | 20 + drivers/media/i2c/dw9714.c | 14 +- drivers/media/i2c/dw9768.c | 6 - drivers/media/i2c/hi556.c | 70 +- drivers/media/i2c/imx208.c | 82 +- drivers/media/i2c/imx274.c | 97 +- drivers/media/i2c/imx290.c | 2 +- drivers/media/i2c/imx319.c | 76 +- drivers/media/i2c/imx355.c | 2 +- drivers/media/i2c/max9286.c | 24 +- drivers/media/i2c/mt9p031.c | 56 +- drivers/media/i2c/ov13858.c | 13 +- drivers/media/i2c/ov2740.c | 69 +- drivers/media/i2c/ov5670.c | 89 +- drivers/media/i2c/ov5675.c | 71 +- drivers/media/i2c/ov8856.c | 245 +- drivers/media/i2c/ov8865.c | 468 +- drivers/media/i2c/s5c73m3/s5c73m3-spi.c | 6 + drivers/media/i2c/st-mipid02.c | 22 +- drivers/media/i2c/tda1997x.c | 119 +- drivers/media/i2c/tda1997x_regs.h | 3 - drivers/media/i2c/video-i2c.c | 21 +- drivers/media/mc/Kconfig | 8 + drivers/media/mc/mc-devnode.c | 2 +- drivers/media/mc/mc-entity.c | 22 +- drivers/media/pci/bt8xx/bttv-driver.c | 4 +- drivers/media/pci/cobalt/cobalt-cpld.c | 5 +- drivers/media/pci/cobalt/cobalt-driver.c | 4 +- drivers/media/pci/cx18/cx18-alsa-main.c | 6 + drivers/media/pci/cx18/cx18-driver.c | 2 +- drivers/media/pci/cx18/cx18-ioctl.c | 4 +- drivers/media/pci/cx18/cx18-queue.c | 13 +- drivers/media/pci/cx18/cx18-streams.c | 24 +- drivers/media/pci/cx25821/cx25821-core.c | 7 + drivers/media/pci/ddbridge/ddbridge-main.c | 4 +- drivers/media/pci/intel/ipu3/cio2-bridge.c | 158 +- drivers/media/pci/intel/ipu3/cio2-bridge.h | 23 +- drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 293 +- drivers/media/pci/intel/ipu3/ipu3-cio2.h | 4 - drivers/media/pci/ivtv/ivtv-alsa-main.c | 6 + drivers/media/pci/ivtv/ivtv-driver.c | 2 +- drivers/media/pci/ivtv/ivtv-ioctl.c | 8 +- drivers/media/pci/ivtv/ivtv-queue.c | 18 +- drivers/media/pci/ivtv/ivtv-streams.c | 22 +- drivers/media/pci/ivtv/ivtv-udma.c | 19 +- drivers/media/pci/ivtv/ivtv-yuv.c | 10 +- drivers/media/pci/ivtv/ivtvfb.c | 10 +- .../pci/netup_unidvb/netup_unidvb_core.c | 2 +- drivers/media/pci/pluto2/pluto2.c | 20 +- drivers/media/pci/pt1/pt1.c | 2 +- drivers/media/pci/pt3/pt3.c | 58 +- drivers/media/pci/saa7134/saa7134-cards.c | 53 - drivers/media/pci/saa7134/saa7134-dvb.c | 29 - drivers/media/pci/saa7134/saa7134-go7007.c | 7 +- drivers/media/pci/saa7134/saa7134.h | 1 - drivers/media/pci/saa7146/mxb.c | 3 +- drivers/media/pci/saa7164/saa7164-api.c | 2 + .../media/pci/solo6x10/solo6x10-v4l2-enc.c | 12 +- drivers/media/pci/tw5864/tw5864-core.c | 7 +- drivers/media/platform/Kconfig | 32 - drivers/media/platform/Makefile | 2 - .../media/platform/allegro-dvt/allegro-core.c | 304 +- .../media/platform/allegro-dvt/allegro-mail.c | 23 +- .../media/platform/allegro-dvt/allegro-mail.h | 10 +- drivers/media/platform/allegro-dvt/nal-h264.c | 74 + drivers/media/platform/allegro-dvt/nal-h264.h | 200 +- drivers/media/platform/allegro-dvt/nal-hevc.c | 202 +- drivers/media/platform/allegro-dvt/nal-hevc.h | 189 +- drivers/media/platform/am437x/am437x-vpfe.c | 23 +- drivers/media/platform/aspeed-video.c | 133 +- drivers/media/platform/atmel/atmel-isc-base.c | 4 +- drivers/media/platform/atmel/atmel-isi.c | 17 +- .../media/platform/atmel/atmel-sama5d2-isc.c | 15 +- .../media/platform/atmel/atmel-sama7g5-isc.c | 15 +- .../media/platform/bcm2835/bcm2835-unicam.c | 9 +- drivers/media/platform/cadence/cdns-csi2rx.c | 18 +- drivers/media/platform/cadence/cdns-csi2tx.c | 4 +- drivers/media/platform/coda/coda-common.c | 8 +- drivers/media/platform/coda/imx-vdoa.c | 3 +- drivers/media/platform/davinci/vpbe_osd.c | 2 +- drivers/media/platform/davinci/vpbe_venc.c | 9 +- drivers/media/platform/davinci/vpif.c | 5 +- drivers/media/platform/davinci/vpif_capture.c | 33 +- drivers/media/platform/davinci/vpss.c | 10 +- drivers/media/platform/exynos-gsc/gsc-core.c | 3 +- drivers/media/platform/exynos4-is/media-dev.c | 20 +- drivers/media/platform/exynos4-is/mipi-csis.c | 4 +- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 103 +- drivers/media/platform/imx-jpeg/mxc-jpeg.h | 2 - drivers/media/platform/imx-pxp.c | 35 +- .../media/platform/marvell-ccic/cafe-driver.c | 16 +- .../media/platform/marvell-ccic/mcam-core.c | 10 +- .../media/platform/marvell-ccic/mmp-driver.c | 6 +- drivers/media/platform/meson/ge2d/ge2d.c | 4 +- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 8 +- drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 2 +- drivers/media/platform/mtk-vcodec/Makefile | 3 - .../platform/mtk-vcodec/mtk_vcodec_dec.c | 820 +++- .../platform/mtk-vcodec/mtk_vcodec_dec.h | 28 +- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 71 +- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 59 +- .../platform/mtk-vcodec/mtk_vcodec_enc.c | 340 +- .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 79 +- .../platform/mtk-vcodec/mtk_vcodec_util.c | 10 + .../platform/mtk-vcodec/mtk_vcodec_util.h | 45 +- .../media/platform/mtk-vcodec/vdec_drv_if.c | 3 - .../media/platform/mtk-vcodec/vdec_drv_if.h | 1 - .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 23 +- .../media/platform/mtk-vcodec/vdec_vpu_if.c | 43 +- .../media/platform/mtk-vcodec/vdec_vpu_if.h | 5 - .../platform/mtk-vcodec/venc/venc_h264_if.c | 9 +- .../platform/mtk-vcodec/venc/venc_vp8_if.c | 3 +- .../media/platform/mtk-vcodec/venc_vpu_if.c | 1 + .../media/platform/mtk-vcodec/venc_vpu_if.h | 1 + drivers/media/platform/mtk-vpu/mtk_vpu.c | 4 +- drivers/media/platform/mx2_emmaprp.c | 4 +- drivers/media/platform/omap/omap_vout.c | 18 +- drivers/media/platform/omap/omap_vout_vrfb.c | 2 +- drivers/media/platform/omap/omap_voutdef.h | 2 +- drivers/media/platform/omap3isp/isp.c | 24 +- drivers/media/platform/omap3isp/isph3a_af.c | 2 +- drivers/media/platform/omap3isp/omap3isp.h | 2 - drivers/media/platform/pxa_camera.c | 26 +- .../media/platform/qcom/camss/camss-vfe-170.c | 14 +- .../media/platform/qcom/camss/camss-vfe-4-1.c | 28 +- .../media/platform/qcom/camss/camss-vfe-4-7.c | 18 +- .../media/platform/qcom/camss/camss-vfe-4-8.c | 17 +- drivers/media/platform/qcom/camss/camss-vfe.c | 4 +- drivers/media/platform/qcom/camss/camss-vfe.h | 2 +- drivers/media/platform/qcom/camss/camss.c | 18 +- drivers/media/platform/qcom/venus/core.c | 135 +- drivers/media/platform/qcom/venus/core.h | 9 +- drivers/media/platform/qcom/venus/firmware.c | 42 +- drivers/media/platform/qcom/venus/helpers.c | 81 +- drivers/media/platform/qcom/venus/helpers.h | 4 - drivers/media/platform/qcom/venus/hfi.c | 48 +- drivers/media/platform/qcom/venus/hfi_cmds.c | 7 - .../media/platform/qcom/venus/hfi_helper.h | 14 - drivers/media/platform/qcom/venus/hfi_msgs.c | 7 - .../platform/qcom/venus/hfi_plat_bufs_v6.c | 6 +- .../media/platform/qcom/venus/hfi_platform.c | 13 + .../media/platform/qcom/venus/hfi_platform.h | 2 + .../platform/qcom/venus/hfi_platform_v6.c | 6 + drivers/media/platform/qcom/venus/hfi_venus.c | 4 - .../media/platform/qcom/venus/hfi_venus_io.h | 2 - .../media/platform/qcom/venus/pm_helpers.c | 5 +- drivers/media/platform/qcom/venus/vdec.c | 69 +- drivers/media/platform/qcom/venus/venc.c | 116 +- drivers/media/platform/rcar-vin/rcar-core.c | 990 ++-- drivers/media/platform/rcar-vin/rcar-csi2.c | 244 +- drivers/media/platform/rcar-vin/rcar-dma.c | 52 +- drivers/media/platform/rcar-vin/rcar-v4l2.c | 25 - drivers/media/platform/rcar-vin/rcar-vin.h | 25 +- drivers/media/platform/rcar_drif.c | 17 +- drivers/media/platform/rcar_fdp1.c | 11 +- drivers/media/platform/rcar_jpu.c | 4 +- drivers/media/platform/renesas-ceu.c | 33 +- drivers/media/platform/rockchip/rga/rga.c | 5 +- .../platform/rockchip/rkisp1/rkisp1-capture.c | 9 +- .../platform/rockchip/rkisp1/rkisp1-common.h | 44 +- .../platform/rockchip/rkisp1/rkisp1-dev.c | 96 +- .../platform/rockchip/rkisp1/rkisp1-isp.c | 29 +- .../platform/rockchip/rkisp1/rkisp1-params.c | 557 +-- .../platform/rockchip/rkisp1/rkisp1-regs.h | 404 +- .../platform/rockchip/rkisp1/rkisp1-stats.c | 107 +- drivers/media/platform/s3c-camif/camif-core.c | 8 +- drivers/media/platform/s5p-g2d/g2d.c | 4 +- drivers/media/platform/s5p-jpeg/jpeg-core.c | 11 +- drivers/media/platform/s5p-jpeg/jpeg-core.h | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc.c | 12 +- drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 4 +- .../platform/sti/c8sectpfe/c8sectpfe-core.c | 13 +- .../platform/sti/c8sectpfe/c8sectpfe-dvb.c | 1 + drivers/media/platform/sti/hva/hva-hw.c | 8 +- drivers/media/platform/stm32/Makefile | 2 - drivers/media/platform/stm32/stm32-dcmi.c | 18 +- .../platform/sunxi/sun4i-csi/sun4i_csi.c | 16 +- .../platform/sunxi/sun6i-csi/sun6i_csi.c | 33 +- .../platform/sunxi/sun6i-csi/sun6i_csi.h | 2 +- .../platform/sunxi/sun6i-csi/sun6i_video.c | 2 +- .../media/platform/sunxi/sun8i-di/sun8i-di.c | 4 +- drivers/media/platform/ti-vpe/cal.c | 16 +- drivers/media/platform/via-camera.c | 6 +- drivers/media/platform/video-mux.c | 17 +- drivers/media/platform/vsp1/vsp1_drm.c | 8 +- drivers/media/platform/vsp1/vsp1_drv.c | 18 +- drivers/media/platform/vsp1/vsp1_regs.h | 11 +- drivers/media/platform/xilinx/xilinx-vip.c | 4 +- drivers/media/platform/xilinx/xilinx-vipp.c | 17 +- drivers/media/radio/radio-si476x.c | 6 + drivers/media/radio/si470x/radio-si470x-i2c.c | 17 +- drivers/media/radio/si470x/radio-si470x-usb.c | 16 +- drivers/media/rc/Kconfig | 10 +- drivers/media/rc/Makefile | 1 + drivers/media/rc/iguanair.c | 3 + drivers/media/rc/img-ir/img-ir-core.c | 4 +- drivers/media/rc/imon.c | 2 - drivers/media/rc/ir-hix5hd2.c | 4 +- drivers/media/rc/ir-rx51.c | 16 +- drivers/media/rc/ir-spi.c | 6 + drivers/media/rc/ir_toy.c | 61 +- drivers/media/rc/lirc_dev.c | 5 + drivers/media/rc/mceusb.c | 1 - drivers/media/rc/meson-ir-tx.c | 1 + drivers/media/rc/meson-ir.c | 4 +- drivers/media/rc/mtk-cir.c | 4 +- drivers/media/rc/pwm-ir-tx.c | 18 +- drivers/media/rc/st_rc.c | 5 +- drivers/media/rc/streamzap.c | 121 +- drivers/media/rc/sunxi-cir.c | 4 +- drivers/media/rc/winbond-cir.c | 1 + drivers/media/spi/cxd2880-spi.c | 13 +- .../media/test-drivers/vicodec/vicodec-core.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_psi.c | 12 +- drivers/media/test-drivers/vim2m.c | 5 + drivers/media/test-drivers/vimc/vimc-scaler.c | 360 +- drivers/media/test-drivers/vivid/vivid-cec.c | 339 +- drivers/media/test-drivers/vivid/vivid-cec.h | 9 +- drivers/media/test-drivers/vivid/vivid-core.c | 52 +- drivers/media/test-drivers/vivid/vivid-core.h | 23 +- drivers/media/tuners/mxl5005s.c | 14 +- drivers/media/tuners/mxl5007t.c | 9 + drivers/media/tuners/r820t.c | 24 +- drivers/media/tuners/si2157.c | 345 +- drivers/media/tuners/si2157_priv.h | 44 +- drivers/media/tuners/tua9001.c | 6 +- drivers/media/tuners/tuner-types.c | 4 - drivers/media/usb/airspy/airspy.c | 5 +- drivers/media/usb/au0828/au0828-i2c.c | 7 + drivers/media/usb/b2c2/flexcop-usb.c | 18 +- drivers/media/usb/dvb-usb-v2/lmedm04.c | 3 - drivers/media/usb/dvb-usb/dib0700_core.c | 30 +- drivers/media/usb/em28xx/em28xx-cards.c | 7 +- drivers/media/usb/go7007/go7007-driver.c | 2 +- drivers/media/usb/gspca/gl860/gl860-mi1320.c | 87 +- drivers/media/usb/gspca/gl860/gl860-ov9655.c | 169 +- drivers/media/usb/gspca/gspca.c | 2 - drivers/media/usb/gspca/m5602/m5602_ov7660.h | 1 + drivers/media/usb/gspca/m5602/m5602_s5k83a.c | 13 +- drivers/media/usb/gspca/sn9c20x.c | 22 +- drivers/media/usb/pvrusb2/pvrusb2-ctrl.c | 25 +- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 33 +- drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | 4 + drivers/media/usb/siano/smsusb.c | 4 + drivers/media/usb/stkwebcam/stk-webcam.c | 11 +- drivers/media/usb/uvc/uvc_ctrl.c | 260 +- drivers/media/usb/uvc/uvc_driver.c | 15 +- drivers/media/usb/uvc/uvc_metadata.c | 2 +- drivers/media/usb/uvc/uvc_v4l2.c | 98 +- drivers/media/usb/uvc/uvcvideo.h | 17 +- drivers/media/v4l2-core/Kconfig | 4 - drivers/media/v4l2-core/Makefile | 1 - drivers/media/v4l2-core/v4l2-async.c | 168 +- drivers/media/v4l2-core/v4l2-common.c | 3 - drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 9 +- drivers/media/v4l2-core/v4l2-ctrls-core.c | 186 +- drivers/media/v4l2-core/v4l2-ctrls-defs.c | 20 +- drivers/media/v4l2-core/v4l2-fwnode.c | 83 +- drivers/media/v4l2-core/v4l2-ioctl.c | 11 +- drivers/media/v4l2-core/v4l2-mem2mem.c | 21 - drivers/memory/Kconfig | 5 +- drivers/memory/jedec_ddr.h | 47 - drivers/memory/jedec_ddr_data.c | 41 - drivers/memory/mtk-smi.c | 594 +-- drivers/memory/of_memory.c | 87 - drivers/memory/of_memory.h | 9 - drivers/memory/omap-gpmc.c | 50 +- drivers/memory/renesas-rpc-if.c | 153 +- drivers/memory/samsung/Kconfig | 13 +- drivers/memory/tegra/Kconfig | 1 - drivers/memory/tegra/mc.c | 25 +- drivers/memory/tegra/tegra186-emc.c | 5 - drivers/memory/tegra/tegra20-emc.c | 199 +- drivers/memory/tegra/tegra210-emc-cc-r21021.c | 2 +- drivers/memory/tegra/tegra210-emc-core.c | 6 +- drivers/memory/tegra/tegra30-emc.c | 4 +- drivers/memstick/core/ms_block.c | 6 +- drivers/memstick/core/mspro_block.c | 6 +- drivers/memstick/host/jmb38x_ms.c | 3 +- drivers/message/fusion/mptbase.c | 162 +- drivers/message/fusion/mptbase.h | 2 +- drivers/message/fusion/mptctl.c | 86 +- drivers/message/fusion/mptfc.c | 8 +- drivers/message/fusion/mptlan.c | 94 +- drivers/message/fusion/mptsas.c | 98 +- drivers/message/fusion/mptscsih.c | 46 +- drivers/message/fusion/mptscsih.h | 2 +- drivers/message/fusion/mptspi.c | 6 +- drivers/mfd/Kconfig | 53 +- drivers/mfd/Makefile | 3 + drivers/mfd/altera-a10sr.c | 9 - drivers/mfd/arizona-core.c | 13 + drivers/mfd/arizona-i2c.c | 14 +- drivers/mfd/arizona-spi.c | 13 +- drivers/mfd/arizona.h | 2 + drivers/mfd/cros_ec_dev.c | 5 +- drivers/mfd/da9062-core.c | 12 - drivers/mfd/da9063-i2c.c | 2 - drivers/mfd/db8500-prcmu.c | 13 +- drivers/mfd/hi6421-spmi-pmic.c | 16 +- drivers/mfd/intel-lpss-pci.c | 21 - drivers/mfd/intel-lpss.c | 1 - drivers/mfd/intel-lpss.h | 1 - drivers/mfd/intel_soc_pmic_core.c | 28 +- drivers/mfd/janz-cmodio.c | 2 +- drivers/mfd/max14577.c | 6 +- drivers/mfd/max77686.c | 3 +- drivers/mfd/max77693.c | 12 +- drivers/mfd/mc13xxx-core.c | 4 +- drivers/mfd/mc13xxx-i2c.c | 3 +- drivers/mfd/mc13xxx-spi.c | 3 +- drivers/mfd/mc13xxx.h | 2 +- drivers/mfd/qcom-pm8xxx.c | 39 +- drivers/mfd/qcom-spmi-pmic.c | 57 +- drivers/mfd/rk808.c | 4 - drivers/mfd/sec-irq.c | 3 +- drivers/mfd/sprd-sc27xx-spi.c | 10 - drivers/mfd/stmpe-i2c.c | 4 +- drivers/mfd/stmpe-spi.c | 4 +- drivers/mfd/stmpe.c | 6 +- drivers/mfd/stmpe.h | 2 +- drivers/mfd/ti_am335x_tscadc.c | 273 +- drivers/mfd/tps65912-core.c | 4 +- drivers/mfd/tps65912-i2c.c | 4 +- drivers/mfd/tps65912-spi.c | 4 +- drivers/mfd/wcd934x.c | 21 +- drivers/misc/ad525x_dpot-i2c.c | 3 +- drivers/misc/ad525x_dpot-spi.c | 3 +- drivers/misc/ad525x_dpot.c | 4 +- drivers/misc/ad525x_dpot.h | 2 +- drivers/misc/cardreader/rtsx_pcr.c | 2 +- drivers/misc/cxl/Kconfig | 1 - drivers/misc/cxl/guest.c | 30 +- drivers/misc/cxl/pci.c | 35 +- drivers/misc/cxl/sysfs.c | 3 +- drivers/misc/eeprom/at24.c | 113 +- drivers/misc/eeprom/at25.c | 200 +- drivers/misc/enclosure.c | 16 +- drivers/misc/fastrpc.c | 21 +- drivers/misc/genwqe/card_utils.c | 10 +- drivers/misc/habanalabs/Kconfig | 2 - drivers/misc/habanalabs/common/Makefile | 2 +- .../misc/habanalabs/common/command_buffer.c | 46 +- .../habanalabs/common/command_submission.c | 474 +- drivers/misc/habanalabs/common/context.c | 47 +- drivers/misc/habanalabs/common/debugfs.c | 148 +- drivers/misc/habanalabs/common/device.c | 486 +- drivers/misc/habanalabs/common/firmware_if.c | 262 +- drivers/misc/habanalabs/common/habanalabs.h | 333 +- .../misc/habanalabs/common/habanalabs_drv.c | 172 +- .../misc/habanalabs/common/habanalabs_ioctl.c | 195 +- drivers/misc/habanalabs/common/hw_queue.c | 5 +- drivers/misc/habanalabs/common/hwmon.c | 379 +- drivers/misc/habanalabs/common/irq.c | 17 +- drivers/misc/habanalabs/common/memory.c | 593 +-- drivers/misc/habanalabs/common/mmu/mmu.c | 55 +- drivers/misc/habanalabs/common/mmu/mmu_v1.c | 18 +- drivers/misc/habanalabs/common/sysfs.c | 60 +- drivers/misc/habanalabs/gaudi/Makefile | 2 +- drivers/misc/habanalabs/gaudi/gaudi.c | 325 +- drivers/misc/habanalabs/gaudi/gaudiP.h | 8 +- .../misc/habanalabs/gaudi/gaudi_coresight.c | 4 +- drivers/misc/habanalabs/goya/goya.c | 172 +- drivers/misc/habanalabs/goya/goyaP.h | 15 +- drivers/misc/habanalabs/goya/goya_coresight.c | 4 +- drivers/misc/habanalabs/goya/goya_hwmgr.c | 62 +- .../misc/habanalabs/include/common/cpucp_if.h | 82 +- .../habanalabs/include/common/hl_boot_if.h | 191 +- .../habanalabs/include/gaudi/gaudi_fw_if.h | 10 +- .../habanalabs/include/gaudi/gaudi_reg_map.h | 1 - .../include/hw_ip/mmu/mmu_general.h | 19 +- .../habanalabs/include/hw_ip/mmu/mmu_v1_0.h | 18 +- .../habanalabs/include/hw_ip/mmu/mmu_v1_1.h | 20 +- drivers/misc/hi6421v600-irq.c | 9 +- drivers/misc/hisi_hikey_usb.c | 123 +- drivers/misc/lis3lv02d/lis3lv02d.c | 3 +- drivers/misc/lis3lv02d/lis3lv02d.h | 2 +- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 4 +- drivers/misc/lkdtm/Makefile | 2 +- drivers/misc/lkdtm/bugs.c | 93 +- drivers/misc/lkdtm/core.c | 9 +- drivers/misc/lkdtm/lkdtm.h | 1 - drivers/misc/mei/Kconfig | 2 - drivers/misc/mei/Makefile | 1 - drivers/misc/mei/bus.c | 67 +- drivers/misc/mei/client.c | 7 - drivers/misc/mei/hw-txe.c | 6 +- drivers/misc/mei/hw.h | 5 - drivers/misc/mei/init.c | 1 - drivers/misc/mei/pci-txe.c | 4 +- drivers/misc/ocxl/config.c | 13 +- drivers/misc/ocxl/file.c | 4 +- drivers/misc/pvpanic/pvpanic-mmio.c | 9 +- drivers/misc/pvpanic/pvpanic-pci.c | 26 +- drivers/misc/pvpanic/pvpanic.c | 16 +- drivers/misc/sgi-xp/xpnet.c | 9 +- drivers/misc/sram.c | 1 - drivers/misc/tifm_7xx1.c | 2 +- drivers/misc/tifm_core.c | 8 +- drivers/misc/uacce/uacce.c | 12 +- drivers/misc/vmw_vmci/vmci_context.c | 6 +- drivers/misc/vmw_vmci/vmci_event.c | 3 +- drivers/mmc/core/block.c | 69 +- drivers/mmc/core/bus.c | 11 + drivers/mmc/core/card.h | 36 - drivers/mmc/core/crypto.c | 11 +- drivers/mmc/core/mmc.c | 10 +- drivers/mmc/core/mmc_ops.c | 89 +- drivers/mmc/core/mmc_ops.h | 3 +- drivers/mmc/core/mmc_test.c | 1 + drivers/mmc/core/pwrseq_simple.c | 2 +- drivers/mmc/core/queue.c | 2 +- drivers/mmc/core/quirks.h | 64 +- drivers/mmc/core/sd.c | 3 +- drivers/mmc/core/sdio.c | 1 - drivers/mmc/core/slot-gpio.c | 40 +- drivers/mmc/host/Kconfig | 9 +- drivers/mmc/host/Makefile | 1 + drivers/mmc/host/au1xmmc.c | 4 +- drivers/mmc/host/bcm2835-mmc.c | 1 + drivers/mmc/host/bcm2835-sdhost.c | 1 + drivers/mmc/host/bcm2835.c | 2 + drivers/mmc/host/cqhci-core.c | 4 +- drivers/mmc/host/cqhci-crypto.c | 33 +- drivers/mmc/host/dw_mmc-exynos.c | 130 +- drivers/mmc/host/dw_mmc-hi3798cv200.c | 9 +- drivers/mmc/host/dw_mmc-rockchip.c | 11 +- drivers/mmc/host/dw_mmc.c | 95 +- drivers/mmc/host/dw_mmc.h | 13 - drivers/mmc/host/jz4740_mmc.c | 29 +- drivers/mmc/host/meson-mx-sdhc-clkc.c | 2 + drivers/mmc/host/mmc_spi.c | 16 +- drivers/mmc/host/mmci.c | 11 +- drivers/mmc/host/mmci_stm32_sdmmc.c | 5 +- drivers/mmc/host/mtk-sd.c | 562 +-- drivers/mmc/host/mxcmmc.c | 6 +- drivers/mmc/host/omap_hsmmc.c | 46 +- drivers/mmc/host/renesas_sdhi.h | 4 - drivers/mmc/host/renesas_sdhi_core.c | 47 +- drivers/mmc/host/renesas_sdhi_internal_dmac.c | 21 - drivers/mmc/host/sdhci-acpi.c | 92 +- drivers/mmc/host/sdhci-esdhc-imx.c | 21 +- drivers/mmc/host/sdhci-of-arasan.c | 29 +- drivers/mmc/host/sdhci-omap.c | 306 +- drivers/mmc/host/sdhci-pci-core.c | 152 +- drivers/mmc/host/sdhci-pci-gli.c | 23 - drivers/mmc/host/sdhci-pci-o2micro.c | 64 +- drivers/mmc/host/sdhci-pci.h | 5 + drivers/mmc/host/sdhci-s3c.c | 1 + drivers/mmc/host/sdhci-sprd.c | 13 - drivers/mmc/host/sdhci-tegra.c | 81 +- drivers/mmc/host/sdhci.c | 42 +- drivers/mmc/host/sdhci.h | 2 +- drivers/mmc/host/sh_mmcif.c | 3 - drivers/most/most_usb.c | 4 +- drivers/mtd/chips/gen_probe.c | 9 +- drivers/mtd/devices/block2mtd.c | 29 +- drivers/mtd/devices/mchp23k256.c | 4 +- drivers/mtd/devices/mchp48l640.c | 4 +- drivers/mtd/devices/mtd_dataflash.c | 10 +- drivers/mtd/devices/sst25l.c | 4 +- drivers/mtd/hyperbus/rpc-if.c | 4 +- drivers/mtd/maps/Kconfig | 6 + drivers/mtd/maps/Makefile | 1 + drivers/mtd/mtd_blkdevs.c | 32 +- drivers/mtd/mtdchar.c | 108 +- drivers/mtd/mtdcore.c | 18 +- drivers/mtd/mtdsuper.c | 1 - drivers/mtd/mtdswap.c | 1 + drivers/mtd/nand/core.c | 3 - drivers/mtd/nand/ecc-sw-hamming.c | 7 +- drivers/mtd/nand/onenand/Kconfig | 9 +- drivers/mtd/nand/onenand/onenand_bbt.c | 4 +- drivers/mtd/nand/raw/Kconfig | 15 +- drivers/mtd/nand/raw/Makefile | 1 - drivers/mtd/nand/raw/atmel/pmecc.c | 7 +- drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c | 5 +- drivers/mtd/nand/raw/cs553x_nand.c | 12 +- drivers/mtd/nand/raw/denali_dt.c | 7 +- drivers/mtd/nand/raw/gpio.c | 3 +- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 20 +- drivers/mtd/nand/raw/hisi504_nand.c | 7 +- drivers/mtd/nand/raw/lpc32xx_slc.c | 15 +- drivers/mtd/nand/raw/mtk_ecc.c | 4 +- drivers/mtd/nand/raw/mtk_nand.c | 4 +- drivers/mtd/nand/raw/nand_base.c | 3 - drivers/mtd/nand/raw/nand_bbt.c | 3 - drivers/mtd/nand/raw/nand_hynix.c | 14 - drivers/mtd/nand/raw/nand_ids.c | 4 - drivers/mtd/nand/raw/ndfc.c | 12 +- drivers/mtd/nand/raw/omap2.c | 507 +- drivers/mtd/nand/raw/omap_elm.c | 19 +- drivers/mtd/nand/raw/oxnas_nand.c | 4 +- drivers/mtd/nand/raw/plat_nand.c | 4 +- drivers/mtd/nand/raw/qcom_nandc.c | 14 +- drivers/mtd/nand/raw/sharpsl.c | 12 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 8 +- drivers/mtd/nand/raw/tegra_nand.c | 62 +- drivers/mtd/nand/raw/tmio_nand.c | 8 +- drivers/mtd/nand/raw/txx9ndfmc.c | 9 +- drivers/mtd/nand/raw/vf610_nfc.c | 4 +- drivers/mtd/nand/raw/xway_nand.c | 4 +- drivers/mtd/parsers/qcomsmempart.c | 3 +- drivers/mtd/spi-nor/atmel.c | 79 +- drivers/mtd/spi-nor/catalyst.c | 15 +- drivers/mtd/spi-nor/controllers/hisi-sfc.c | 7 +- drivers/mtd/spi-nor/controllers/nxp-spifi.c | 7 +- drivers/mtd/spi-nor/core.c | 594 ++- drivers/mtd/spi-nor/core.h | 209 +- drivers/mtd/spi-nor/eon.c | 33 +- drivers/mtd/spi-nor/esmt.c | 15 +- drivers/mtd/spi-nor/everspin.c | 12 +- drivers/mtd/spi-nor/fujitsu.c | 3 +- drivers/mtd/spi-nor/gigadevice.c | 59 +- drivers/mtd/spi-nor/intel.c | 12 +- drivers/mtd/spi-nor/issi.c | 62 +- drivers/mtd/spi-nor/macronix.c | 107 +- drivers/mtd/spi-nor/micron-st.c | 222 +- drivers/mtd/spi-nor/otp.c | 2 +- drivers/mtd/spi-nor/sfdp.c | 20 - drivers/mtd/spi-nor/spansion.c | 184 +- drivers/mtd/spi-nor/sst.c | 96 +- drivers/mtd/spi-nor/swp.c | 2 +- drivers/mtd/spi-nor/winbond.c | 168 +- drivers/mtd/spi-nor/xilinx.c | 22 +- drivers/mtd/spi-nor/xmc.c | 10 +- drivers/mtd/ubi/block.c | 15 +- drivers/mtd/ubi/debug.c | 2 +- drivers/mux/core.c | 38 +- drivers/nfc/fdp/i2c.c | 5 +- drivers/nfc/microread/i2c.c | 4 + drivers/nfc/microread/mei.c | 6 +- drivers/nfc/nfcmrvl/fw_dnld.c | 4 +- drivers/nfc/pn533/i2c.c | 6 +- drivers/nfc/pn533/pn533.c | 6 +- drivers/nfc/pn533/pn533.h | 4 +- drivers/nfc/pn533/uart.c | 4 +- drivers/nfc/pn533/usb.c | 2 +- drivers/nfc/pn544/i2c.c | 2 +- drivers/nfc/pn544/mei.c | 8 +- drivers/nfc/s3fwrn5/firmware.c | 29 +- drivers/nfc/s3fwrn5/nci.c | 18 +- drivers/nfc/st-nci/i2c.c | 4 + drivers/nfc/st-nci/ndlc.c | 4 + drivers/nfc/st-nci/se.c | 6 + drivers/nfc/st-nci/spi.c | 4 + drivers/nfc/st21nfca/i2c.c | 8 +- drivers/nfc/st21nfca/se.c | 14 +- drivers/nfc/trf7970a.c | 8 + drivers/nfc/virtual_ncidev.c | 2 +- drivers/ntb/hw/amd/ntb_hw_amd.c | 2 - drivers/ntb/hw/intel/ntb_hw_gen4.c | 17 +- drivers/ntb/hw/intel/ntb_hw_gen4.h | 16 + drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 16 +- drivers/ntb/msi.c | 24 +- drivers/nubus/proc.c | 36 +- drivers/nvdimm/Kconfig | 2 +- drivers/nvdimm/blk.c | 32 +- drivers/nvdimm/btt.c | 36 +- drivers/nvdimm/btt_devs.c | 14 +- drivers/nvdimm/core.c | 41 +- drivers/nvdimm/label.c | 139 +- drivers/nvdimm/label.h | 94 +- drivers/nvdimm/namespace_devs.c | 95 +- drivers/nvdimm/nd-core.h | 5 +- drivers/nvdimm/nd.h | 185 +- drivers/nvdimm/pfn_devs.c | 2 +- drivers/nvdimm/pmem.c | 90 +- drivers/nvmem/core.c | 174 +- drivers/nvmem/imx-ocotp.c | 25 - drivers/nvmem/mtk-efuse.c | 13 +- drivers/of/base.c | 180 +- drivers/of/device.c | 2 +- drivers/of/fdt.c | 191 +- drivers/of/irq.c | 55 +- drivers/of/kexec.c | 4 +- drivers/of/kobj.c | 4 +- drivers/of/of_numa.c | 2 - drivers/of/of_private.h | 10 +- drivers/of/of_reserved_mem.c | 5 +- drivers/of/platform.c | 21 +- drivers/of/property.c | 17 +- drivers/of/unittest-data/Makefile | 8 +- .../of/unittest-data/tests-interrupts.dtsi | 19 - drivers/of/unittest.c | 180 +- drivers/opp/core.c | 6 +- drivers/opp/of.c | 48 +- drivers/parisc/pdc_stable.c | 3 +- drivers/pci/Kconfig | 2 +- drivers/pci/Makefile | 3 +- drivers/pci/access.c | 36 +- drivers/pci/controller/Kconfig | 37 +- drivers/pci/controller/Makefile | 3 - drivers/pci/controller/cadence/pci-j721e.c | 103 +- .../controller/cadence/pcie-cadence-plat.c | 6 +- drivers/pci/controller/cadence/pcie-cadence.h | 2 +- drivers/pci/controller/dwc/Kconfig | 30 +- drivers/pci/controller/dwc/Makefile | 1 - drivers/pci/controller/dwc/pci-dra7xx.c | 30 +- drivers/pci/controller/dwc/pci-exynos.c | 5 +- drivers/pci/controller/dwc/pci-imx6.c | 83 +- drivers/pci/controller/dwc/pci-keystone.c | 37 +- drivers/pci/controller/dwc/pci-layerscape.c | 152 +- drivers/pci/controller/dwc/pcie-artpec6.c | 6 +- .../pci/controller/dwc/pcie-designware-ep.c | 3 - .../pci/controller/dwc/pcie-designware-host.c | 19 +- .../pci/controller/dwc/pcie-designware-plat.c | 6 +- drivers/pci/controller/dwc/pcie-designware.c | 1 - drivers/pci/controller/dwc/pcie-hisi.c | 32 +- drivers/pci/controller/dwc/pcie-histb.c | 4 +- drivers/pci/controller/dwc/pcie-intel-gw.c | 204 +- drivers/pci/controller/dwc/pcie-kirin.c | 649 +-- drivers/pci/controller/dwc/pcie-qcom.c | 98 +- drivers/pci/controller/dwc/pcie-spear13xx.c | 8 +- drivers/pci/controller/dwc/pcie-uniphier.c | 147 +- drivers/pci/controller/dwc/pcie-visconti.c | 5 +- drivers/pci/controller/pci-aardvark.c | 69 +- drivers/pci/controller/pci-hyperv.c | 333 +- drivers/pci/controller/pci-mvebu.c | 294 +- drivers/pci/controller/pci-rcar-gen2.c | 14 +- drivers/pci/controller/pci-thunder-ecam.c | 50 +- drivers/pci/controller/pci-thunder-pem.c | 4 +- drivers/pci/controller/pci-xgene-msi.c | 8 +- drivers/pci/controller/pci-xgene.c | 59 +- drivers/pci/controller/pcie-altera.c | 12 +- drivers/pci/controller/pcie-brcmstb.c | 394 +- drivers/pci/controller/pcie-iproc.c | 6 +- drivers/pci/controller/pcie-mediatek-gen3.c | 378 +- drivers/pci/controller/pcie-mediatek.c | 18 +- drivers/pci/controller/pcie-rcar-ep.c | 5 +- drivers/pci/controller/pcie-rcar-host.c | 6 +- drivers/pci/controller/pcie-rockchip-host.c | 4 +- drivers/pci/controller/pcie-xilinx-cpm.c | 44 +- drivers/pci/controller/pcie-xilinx-nwl.c | 30 +- drivers/pci/controller/pcie-xilinx.c | 158 +- drivers/pci/controller/vmd.c | 122 +- drivers/pci/endpoint/functions/pci-epf-ntb.c | 24 +- drivers/pci/endpoint/pci-ep-cfs.c | 48 +- drivers/pci/endpoint/pci-epc-core.c | 4 +- drivers/pci/endpoint/pci-epf-core.c | 4 +- drivers/pci/hotplug/TODO | 5 + drivers/pci/hotplug/acpiphp_glue.c | 2 +- drivers/pci/hotplug/cpqphp.h | 2 +- drivers/pci/hotplug/cpqphp_ctrl.c | 8 +- drivers/pci/hotplug/cpqphp_pci.c | 6 +- drivers/pci/hotplug/ibmphp.h | 4 +- drivers/pci/hotplug/ibmphp_core.c | 74 + drivers/pci/hotplug/pciehp.h | 2 - drivers/pci/hotplug/pciehp_core.c | 2 - drivers/pci/hotplug/pciehp_hpc.c | 36 +- drivers/pci/hotplug/s390_pci_hpc.c | 24 - drivers/pci/hotplug/shpchp_hpc.c | 2 +- drivers/pci/iov.c | 14 +- drivers/pci/msi.c | 80 +- drivers/pci/of.c | 12 +- drivers/pci/p2pdma.c | 12 +- drivers/pci/pci-acpi.c | 74 +- drivers/pci/pci-bridge-emul.c | 49 +- drivers/pci/pci-driver.c | 22 +- drivers/pci/pci-mid.c | 37 +- drivers/pci/pci-sysfs.c | 54 +- drivers/pci/pci.c | 262 +- drivers/pci/pci.h | 97 +- drivers/pci/pcie/aer.c | 2 +- drivers/pci/pcie/aspm.c | 98 +- drivers/pci/pcie/dpc.c | 4 +- drivers/pci/pcie/err.c | 40 +- drivers/pci/pcie/pme.c | 4 +- drivers/pci/pcie/portdrv.h | 6 +- drivers/pci/pcie/portdrv_core.c | 20 +- drivers/pci/pcie/portdrv_pci.c | 27 +- drivers/pci/probe.c | 96 +- drivers/pci/quirks.c | 108 +- drivers/pci/rom.c | 2 +- drivers/pci/setup-bus.c | 2 +- drivers/pci/setup-irq.c | 26 +- drivers/pci/setup-res.c | 8 +- drivers/pci/slot.c | 3 +- drivers/pci/switch/switchtec.c | 106 +- drivers/pci/vpd.c | 93 +- drivers/pci/xen-pcifront.c | 60 +- drivers/perf/Kconfig | 21 +- drivers/perf/Makefile | 1 - drivers/perf/arm-cmn.c | 1094 ++--- drivers/perf/arm_smmuv3_pmu.c | 73 +- drivers/perf/hisilicon/Kconfig | 9 - drivers/perf/hisilicon/Makefile | 2 - drivers/perf/qcom_l2_pmu.c | 7 +- drivers/perf/thunderx2_pmu.c | 2 +- drivers/pinctrl/Kconfig | 537 +-- drivers/pinctrl/Makefile | 48 +- drivers/pinctrl/actions/pinctrl-owl.c | 1 + drivers/pinctrl/aspeed/Kconfig | 2 +- drivers/pinctrl/bcm/Kconfig | 4 +- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 24 +- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 1 + drivers/pinctrl/bcm/pinctrl-ns.c | 169 +- drivers/pinctrl/bcm/pinctrl-nsp-gpio.c | 1 + drivers/pinctrl/cirrus/pinctrl-lochnagar.c | 3 + drivers/pinctrl/cirrus/pinctrl-madera-core.c | 5 +- drivers/pinctrl/freescale/Kconfig | 7 - drivers/pinctrl/freescale/Makefile | 1 - drivers/pinctrl/freescale/pinctrl-imx.c | 17 +- drivers/pinctrl/intel/Kconfig | 6 +- drivers/pinctrl/intel/pinctrl-baytrail.c | 2 +- drivers/pinctrl/intel/pinctrl-cherryview.c | 131 +- drivers/pinctrl/intel/pinctrl-tigerlake.c | 1 + drivers/pinctrl/mediatek/Kconfig | 7 - drivers/pinctrl/mediatek/Makefile | 1 - drivers/pinctrl/mediatek/pinctrl-moore.c | 25 +- drivers/pinctrl/mediatek/pinctrl-mt8195.c | 134 - .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 233 +- .../pinctrl/mediatek/pinctrl-mtk-common-v2.h | 46 - drivers/pinctrl/mediatek/pinctrl-paris.c | 73 +- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 85 +- drivers/pinctrl/nomadik/Kconfig | 1 + drivers/pinctrl/pinconf-generic.c | 2 - drivers/pinctrl/pinctrl-amd.c | 3 + drivers/pinctrl/pinctrl-as3722.c | 13 +- drivers/pinctrl/pinctrl-at91-pio4.c | 1 + drivers/pinctrl/pinctrl-at91.c | 1 + drivers/pinctrl/pinctrl-da9062.c | 6 +- drivers/pinctrl/pinctrl-digicolor.c | 5 +- drivers/pinctrl/pinctrl-keembay.c | 83 +- drivers/pinctrl/pinctrl-max77620.c | 11 +- drivers/pinctrl/pinctrl-mcp23s08.c | 1 + drivers/pinctrl/pinctrl-microchip-sgpio.c | 55 +- drivers/pinctrl/pinctrl-ocelot.c | 486 +- drivers/pinctrl/pinctrl-oxnas.c | 1 + drivers/pinctrl/pinctrl-pic32.c | 2 +- drivers/pinctrl/pinctrl-rk805.c | 12 +- drivers/pinctrl/pinctrl-rockchip.c | 159 +- drivers/pinctrl/pinctrl-st.c | 116 +- drivers/pinctrl/pinctrl-stmfx.c | 1 + drivers/pinctrl/pinctrl-sx150x.c | 3 + drivers/pinctrl/pinctrl-xway.c | 1 + drivers/pinctrl/pinmux.c | 2 +- drivers/pinctrl/pinmux.h | 4 +- drivers/pinctrl/qcom/Kconfig | 35 - drivers/pinctrl/qcom/Makefile | 4 - drivers/pinctrl/qcom/pinctrl-msm.c | 16 +- drivers/pinctrl/qcom/pinctrl-msm.h | 10 - drivers/pinctrl/qcom/pinctrl-msm8226.c | 74 +- drivers/pinctrl/qcom/pinctrl-sc7280.c | 75 +- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 9 - drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 111 +- drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 1 + drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c | 134 +- drivers/pinctrl/renesas/core.c | 83 +- drivers/pinctrl/renesas/pfc-r8a77950.c | 14 - drivers/pinctrl/renesas/pfc-r8a77951.c | 22 +- drivers/pinctrl/renesas/pfc-r8a7796.c | 22 +- drivers/pinctrl/renesas/pfc-r8a77965.c | 22 +- drivers/pinctrl/renesas/pfc-r8a779a0.c | 4 +- drivers/pinctrl/renesas/pinctrl-rza1.c | 6 +- drivers/pinctrl/renesas/pinctrl-rza2.c | 1 + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 308 +- drivers/pinctrl/renesas/pinctrl.c | 9 +- .../pinctrl/samsung/pinctrl-exynos-arm64.c | 189 - drivers/pinctrl/samsung/pinctrl-samsung.c | 13 +- drivers/pinctrl/samsung/pinctrl-samsung.h | 2 - drivers/pinctrl/spear/pinctrl-plgpio.c | 149 +- drivers/pinctrl/spear/pinctrl-spear.c | 10 +- drivers/pinctrl/spear/pinctrl-spear.h | 12 +- drivers/pinctrl/stm32/pinctrl-stm32.c | 16 +- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 17 +- drivers/pinctrl/tegra/pinctrl-tegra.c | 32 +- drivers/pinctrl/tegra/pinctrl-tegra.h | 2 - drivers/pinctrl/tegra/pinctrl-tegra194.c | 1789 +------ drivers/pinctrl/tegra/pinctrl-tegra210.c | 330 +- drivers/pinctrl/uniphier/Kconfig | 4 - drivers/pinctrl/uniphier/Makefile | 1 - .../pinctrl/uniphier/pinctrl-uniphier-ld11.c | 18 - .../pinctrl/uniphier/pinctrl-uniphier-ld20.c | 35 - .../pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 40 - drivers/pinctrl/vt8500/pinctrl-wmt.c | 1 + drivers/platform/chrome/cros_ec_ishtp.c | 14 +- drivers/platform/chrome/cros_ec_lpc.c | 4 +- drivers/platform/chrome/cros_ec_proto.c | 79 +- drivers/platform/chrome/cros_ec_sensorhub.c | 6 +- drivers/platform/chrome/cros_ec_typec.c | 74 +- drivers/platform/chrome/cros_usbpd_notify.c | 50 +- drivers/platform/mellanox/Kconfig | 12 - drivers/platform/mellanox/Makefile | 1 - drivers/platform/mellanox/mlxreg-hotplug.c | 125 +- drivers/platform/mips/Kconfig | 6 - drivers/platform/mips/Makefile | 1 - drivers/platform/surface/Kconfig | 8 +- drivers/platform/surface/aggregator/Kconfig | 1 - drivers/platform/surface/aggregator/bus.c | 24 +- drivers/platform/surface/aggregator/bus.h | 3 + drivers/platform/surface/aggregator/core.c | 3 +- drivers/platform/surface/surface3-wmi.c | 9 +- drivers/platform/surface/surface3_power.c | 3 +- .../surface/surface_aggregator_registry.c | 44 +- drivers/platform/surface/surface_gpe.c | 13 - drivers/platform/x86/Kconfig | 94 +- drivers/platform/x86/Makefile | 10 - drivers/platform/x86/acer-wmi.c | 14 +- drivers/platform/x86/amd-pmc.c | 343 +- drivers/platform/x86/asus-wmi.c | 617 +-- drivers/platform/x86/dell/dell-wmi-base.c | 76 +- drivers/platform/x86/hp-wmi.c | 337 +- drivers/platform/x86/hp_accel.c | 30 +- drivers/platform/x86/i2c-multi-instantiate.c | 31 +- drivers/platform/x86/ideapad-laptop.c | 35 +- drivers/platform/x86/intel/Kconfig | 27 - drivers/platform/x86/intel/Makefile | 5 - drivers/platform/x86/intel/hid.c | 7 + drivers/platform/x86/intel/int0002_vgpio.c | 14 +- drivers/platform/x86/intel/int3472/Makefile | 9 +- drivers/platform/x86/intel/pmt/Kconfig | 4 +- drivers/platform/x86/intel/pmt/class.c | 21 +- drivers/platform/x86/intel/pmt/class.h | 5 +- drivers/platform/x86/intel/pmt/crashlog.c | 47 +- drivers/platform/x86/intel/pmt/telemetry.c | 46 +- drivers/platform/x86/intel/uncore-frequency.c | 3 +- drivers/platform/x86/lg-laptop.c | 23 +- drivers/platform/x86/mlx-platform.c | 1958 +------- drivers/platform/x86/panasonic-laptop.c | 18 +- drivers/platform/x86/pmc_atom.c | 54 +- drivers/platform/x86/samsung-laptop.c | 2 +- drivers/platform/x86/sony-laptop.c | 46 +- drivers/platform/x86/system76_acpi.c | 425 +- drivers/platform/x86/think-lmi.c | 327 +- drivers/platform/x86/think-lmi.h | 28 +- drivers/platform/x86/thinkpad_acpi.c | 1364 +++--- drivers/platform/x86/touchscreen_dmi.c | 81 +- drivers/platform/x86/uv_sysfs.c | 6 +- drivers/platform/x86/wmi.c | 389 +- drivers/pnp/pnpbios/core.c | 6 +- drivers/pnp/system.c | 2 +- drivers/power/reset/ltc2952-poweroff.c | 4 +- drivers/power/supply/Kconfig | 35 +- drivers/power/supply/Makefile | 1 - drivers/power/supply/ab8500-bm.h | 123 +- drivers/power/supply/ab8500-chargalg.h | 8 +- drivers/power/supply/ab8500_bmdata.c | 570 ++- drivers/power/supply/ab8500_btemp.c | 65 +- drivers/power/supply/ab8500_chargalg.c | 315 +- drivers/power/supply/ab8500_charger.c | 544 +-- drivers/power/supply/ab8500_fg.c | 373 +- drivers/power/supply/axp20x_battery.c | 6 +- drivers/power/supply/axp288_charger.c | 176 +- drivers/power/supply/bd99954-charger.c | 24 +- drivers/power/supply/bq24190_charger.c | 6 +- drivers/power/supply/bq2515x_charger.c | 8 +- drivers/power/supply/bq256xx_charger.c | 27 +- drivers/power/supply/bq25890_charger.c | 104 +- drivers/power/supply/bq25980_charger.c | 6 +- drivers/power/supply/bq27xxx_battery.c | 38 +- drivers/power/supply/cpcap-battery.c | 15 +- drivers/power/supply/cw2015_battery.c | 20 +- drivers/power/supply/ingenic-battery.c | 14 +- drivers/power/supply/power_supply_core.c | 143 +- drivers/power/supply/power_supply_sysfs.c | 57 - drivers/power/supply/qcom_smbb.c | 5 +- drivers/power/supply/sc2731_charger.c | 8 +- drivers/power/supply/sc27xx_fuel_gauge.c | 22 +- drivers/power/supply/smb347-charger.c | 34 +- drivers/power/supply/wm831x_power.c | 12 +- drivers/powercap/dtpm.c | 85 +- drivers/powercap/dtpm_cpu.c | 255 +- drivers/powercap/idle_inject.c | 2 +- drivers/powercap/intel_rapl_common.c | 61 +- drivers/ptp/ptp_clock.c | 6 +- drivers/ptp/ptp_clockmatrix.c | 1467 +++--- drivers/ptp/ptp_clockmatrix.h | 109 +- drivers/ptp/ptp_ines.c | 4 + drivers/ptp/ptp_ocp.c | 1316 +---- drivers/pwm/Kconfig | 4 +- drivers/pwm/core.c | 174 +- drivers/pwm/pwm-atmel.c | 1 + drivers/pwm/pwm-img.c | 35 +- drivers/pwm/pwm-pxa.c | 16 +- drivers/pwm/pwm-samsung.c | 30 +- drivers/pwm/pwm-tegra.c | 82 +- drivers/pwm/pwm-twl.c | 62 +- drivers/pwm/pwm-visconti.c | 14 +- drivers/pwm/pwm-vt8500.c | 73 +- drivers/rapidio/devices/rio_mport_cdev.c | 9 +- drivers/rapidio/switches/Kconfig | 11 + drivers/rapidio/switches/Makefile | 2 + drivers/ras/cec.c | 2 +- drivers/regulator/Kconfig | 30 +- drivers/regulator/Makefile | 3 +- drivers/regulator/bd71815-regulator.c | 4 +- drivers/regulator/bd718x7-regulator.c | 29 +- drivers/regulator/core.c | 14 +- drivers/regulator/da9121-regulator.c | 108 +- drivers/regulator/da9121-regulator.h | 21 +- drivers/regulator/dummy.c | 3 +- drivers/regulator/hi6421v600-regulator.c | 10 +- drivers/regulator/irq_helpers.c | 41 +- drivers/regulator/lp872x.c | 52 +- drivers/regulator/max8973-regulator.c | 4 +- drivers/regulator/mt6380-regulator.c | 6 +- drivers/regulator/pwm-regulator.c | 12 +- drivers/regulator/qcom-rpmh-regulator.c | 59 - drivers/regulator/qcom_smd-regulator.c | 49 - drivers/regulator/qcom_spmi-regulator.c | 39 - drivers/regulator/rohm-regulator.c | 16 - drivers/regulator/rtq6752-regulator.c | 22 +- drivers/regulator/sy7636a-regulator.c | 2 +- drivers/regulator/ti-abb-regulator.c | 31 +- drivers/regulator/tps62360-regulator.c | 59 +- drivers/regulator/twl-regulator.c | 10 +- drivers/regulator/uniphier-regulator.c | 4 - drivers/regulator/vqmmc-ipq4019-regulator.c | 4 +- drivers/remoteproc/Kconfig | 47 +- drivers/remoteproc/Makefile | 3 - drivers/remoteproc/imx_rproc.c | 38 +- drivers/remoteproc/ingenic_rproc.c | 5 +- drivers/remoteproc/mtk_common.h | 1 - drivers/remoteproc/mtk_scp.c | 48 +- drivers/remoteproc/omap_remoteproc.c | 6 +- drivers/remoteproc/qcom_q6v5.c | 58 +- drivers/remoteproc/qcom_q6v5.h | 7 +- drivers/remoteproc/qcom_q6v5_adsp.c | 7 +- drivers/remoteproc/qcom_q6v5_mss.c | 304 +- drivers/remoteproc/qcom_q6v5_pas.c | 266 +- drivers/remoteproc/qcom_q6v5_wcss.c | 5 +- drivers/remoteproc/qcom_wcnss.c | 1 + drivers/remoteproc/remoteproc_core.c | 4 +- drivers/remoteproc/remoteproc_coredump.c | 2 +- drivers/remoteproc/remoteproc_virtio.c | 12 - drivers/remoteproc/stm32_rproc.c | 2 +- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 3 +- drivers/remoteproc/ti_k3_r5_remoteproc.c | 7 +- drivers/reset/Kconfig | 11 +- drivers/reset/Makefile | 1 - drivers/reset/reset-microchip-sparx5.c | 40 +- drivers/reset/reset-uniphier-glue.c | 4 - drivers/reset/reset-uniphier.c | 27 - drivers/rpmsg/mtk_rpmsg.c | 2 +- drivers/rpmsg/qcom_glink_native.c | 92 +- drivers/rpmsg/rpmsg_core.c | 45 +- drivers/rpmsg/rpmsg_internal.h | 2 - drivers/rpmsg/virtio_rpmsg_bus.c | 17 +- drivers/rtc/Kconfig | 53 +- drivers/rtc/Makefile | 4 +- drivers/rtc/dev.c | 65 - drivers/rtc/interface.c | 15 +- drivers/rtc/rtc-ab8500.c | 23 +- drivers/rtc/rtc-da9063.c | 16 +- drivers/rtc/rtc-ftrtc010.c | 8 +- drivers/rtc/rtc-m41t80.c | 2 +- drivers/rtc/rtc-mc146818-lib.c | 188 +- drivers/rtc/rtc-omap.c | 1 + drivers/rtc/rtc-pcf85063.c | 113 +- drivers/rtc/rtc-rs5c372.c | 185 +- drivers/rtc/rtc-rv3028.c | 74 - drivers/rtc/rtc-rv3032.c | 85 +- drivers/rtc/rtc-rv8803.c | 10 +- drivers/rtc/rtc-rx6110.c | 2 +- drivers/rtc/rtc-rx8025.c | 141 +- drivers/rtc/rtc-s35390a.c | 7 +- drivers/rtc/rtc-s3c.c | 104 +- drivers/rtc/rtc-s5m.c | 1 + drivers/rtc/rtc-sun6i.c | 13 +- drivers/s390/block/Kconfig | 2 +- drivers/s390/block/dasd.c | 9 +- drivers/s390/block/dasd_3990_erp.c | 6 +- drivers/s390/block/dasd_devmap.c | 79 +- drivers/s390/block/dasd_eckd.c | 294 +- drivers/s390/block/dasd_eckd.h | 13 +- drivers/s390/block/dasd_erp.c | 8 +- drivers/s390/block/dasd_genhd.c | 11 +- drivers/s390/block/dasd_int.h | 11 +- drivers/s390/block/dcssblk.c | 39 +- drivers/s390/block/scm_blk.c | 7 +- drivers/s390/char/keyboard.h | 4 +- drivers/s390/char/raw3270.c | 12 +- drivers/s390/char/sclp.c | 14 +- drivers/s390/char/sclp.h | 2 +- drivers/s390/char/sclp_early.c | 7 +- drivers/s390/char/sclp_ftp.c | 3 - drivers/s390/char/sclp_sd.c | 14 +- drivers/s390/cio/chp.c | 2 +- drivers/s390/cio/chsc_sch.c | 5 + drivers/s390/cio/css.c | 28 +- drivers/s390/cio/device.c | 22 +- drivers/s390/cio/eadm_sch.c | 5 + drivers/s390/cio/qdio.h | 7 +- drivers/s390/cio/qdio_main.c | 210 +- drivers/s390/cio/qdio_setup.c | 56 +- drivers/s390/cio/vfio_ccw_drv.c | 163 +- drivers/s390/cio/vfio_ccw_ops.c | 142 +- drivers/s390/cio/vfio_ccw_private.h | 5 - drivers/s390/crypto/ap_bus.c | 81 +- drivers/s390/crypto/ap_queue.c | 7 +- drivers/s390/crypto/vfio_ap_drv.c | 91 +- drivers/s390/crypto/vfio_ap_ops.c | 7 +- drivers/s390/crypto/vfio_ap_private.h | 43 +- drivers/s390/crypto/zcrypt_api.c | 52 +- drivers/s390/crypto/zcrypt_card.c | 8 +- drivers/s390/crypto/zcrypt_error.h | 22 +- drivers/s390/crypto/zcrypt_msgtype50.c | 18 +- drivers/s390/crypto/zcrypt_msgtype6.c | 40 +- drivers/s390/crypto/zcrypt_queue.c | 17 +- drivers/s390/net/ctcm_dbug.h | 1 - drivers/s390/net/ctcm_fsms.c | 62 +- drivers/s390/net/ctcm_main.c | 38 +- drivers/s390/net/ctcm_mpc.c | 8 +- drivers/s390/net/fsm.c | 2 +- drivers/s390/net/ism_drv.c | 2 +- drivers/s390/net/lcs.c | 134 +- drivers/s390/net/netiucv.c | 104 +- drivers/s390/net/qeth_core.h | 8 +- drivers/s390/net/qeth_core_main.c | 182 +- drivers/s390/net/qeth_ethtool.c | 4 +- drivers/s390/net/qeth_l2_main.c | 85 +- drivers/s390/net/qeth_l3_main.c | 28 +- drivers/s390/scsi/zfcp_ext.h | 4 +- drivers/s390/scsi/zfcp_fsf.c | 2 +- drivers/s390/scsi/zfcp_qdio.c | 19 +- drivers/s390/scsi/zfcp_sysfs.c | 52 +- drivers/scsi/3w-9xxx.c | 18 +- drivers/scsi/3w-sas.c | 22 +- drivers/scsi/3w-xxxx.c | 26 +- drivers/scsi/53c700.c | 21 +- drivers/scsi/BusLogic.c | 13 +- drivers/scsi/NCR5380.c | 12 +- drivers/scsi/a100u2w.c | 7 +- drivers/scsi/aacraid/aachba.c | 55 +- drivers/scsi/aacraid/linit.c | 38 +- drivers/scsi/advansys.c | 10 +- drivers/scsi/aha152x.c | 29 +- drivers/scsi/aha1542.c | 16 +- drivers/scsi/aha1740.c | 4 +- drivers/scsi/aic7xxx/aic79xx_osm.c | 12 +- drivers/scsi/aic7xxx/aic79xx_osm.h | 2 +- drivers/scsi/aic7xxx/aic7xxx_osm.c | 6 +- drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 +- drivers/scsi/aic94xx/aic94xx_sds.c | 6 +- drivers/scsi/arcmsr/arcmsr.h | 2 +- drivers/scsi/arcmsr/arcmsr_attr.c | 33 +- drivers/scsi/arcmsr/arcmsr_hba.c | 22 +- drivers/scsi/arm/acornscsi.c | 20 +- drivers/scsi/arm/arxescsi.c | 1 - drivers/scsi/arm/cumana_2.c | 1 - drivers/scsi/arm/eesox.c | 1 - drivers/scsi/arm/fas216.c | 26 +- drivers/scsi/arm/fas216.h | 10 - drivers/scsi/arm/powertec.c | 2 +- drivers/scsi/atp870u.c | 18 +- drivers/scsi/be2iscsi/be_main.c | 21 +- drivers/scsi/bfa/bfad.c | 6 + drivers/scsi/bfa/bfad_attr.c | 68 +- drivers/scsi/bfa/bfad_im.c | 16 +- drivers/scsi/bfa/bfad_im.h | 4 +- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 8 +- drivers/scsi/bnx2fc/bnx2fc_io.c | 8 +- drivers/scsi/bnx2i/bnx2i.h | 2 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/bnx2i/bnx2i_sysfs.c | 15 +- drivers/scsi/ch.c | 8 +- drivers/scsi/csiostor/csio_scsi.c | 32 +- drivers/scsi/cxlflash/main.c | 46 +- drivers/scsi/dc395x.c | 14 +- drivers/scsi/dpt_i2o.c | 13 +- drivers/scsi/elx/efct/efct_driver.c | 15 +- drivers/scsi/elx/efct/efct_hw.c | 10 +- drivers/scsi/elx/efct/efct_io.c | 2 +- drivers/scsi/elx/efct/efct_lio.c | 4 +- drivers/scsi/elx/efct/efct_scsi.c | 3 +- drivers/scsi/elx/libefc/efc.h | 2 +- drivers/scsi/elx/libefc/efc_cmds.c | 11 +- drivers/scsi/elx/libefc/efc_els.c | 4 +- drivers/scsi/elx/libefc/efc_fabric.c | 2 +- drivers/scsi/elx/libefc/efclib.h | 1 - drivers/scsi/elx/libefc_sli/sli4.c | 23 +- drivers/scsi/esas2r/esas2r_main.c | 8 +- drivers/scsi/esp_scsi.c | 12 +- drivers/scsi/fcoe/fcoe.c | 2 +- drivers/scsi/fdomain.c | 2 +- drivers/scsi/fnic/fnic.h | 2 +- drivers/scsi/fnic/fnic_attrs.c | 17 +- drivers/scsi/fnic/fnic_main.c | 2 +- drivers/scsi/fnic/fnic_scsi.c | 118 +- drivers/scsi/hisi_sas/hisi_sas.h | 10 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 525 +- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 23 +- drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 35 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 +- drivers/scsi/hosts.c | 6 +- drivers/scsi/hpsa.c | 58 +- drivers/scsi/hptiop.c | 20 +- drivers/scsi/ibmvscsi/ibmvfc.c | 30 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 31 +- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 44 +- drivers/scsi/imm.c | 6 +- drivers/scsi/initio.c | 12 +- drivers/scsi/ipr.c | 48 +- drivers/scsi/ips.c | 31 +- drivers/scsi/isci/init.c | 8 +- drivers/scsi/isci/task.h | 4 + drivers/scsi/libfc/fc_fcp.c | 6 +- drivers/scsi/libiscsi.c | 7 +- drivers/scsi/libsas/sas_discover.c | 1 + drivers/scsi/libsas/sas_event.c | 77 +- drivers/scsi/libsas/sas_expander.c | 3 - drivers/scsi/libsas/sas_init.c | 57 +- drivers/scsi/libsas/sas_internal.h | 2 - drivers/scsi/libsas/sas_scsi_host.c | 34 +- drivers/scsi/lpfc/lpfc.h | 85 +- drivers/scsi/lpfc/lpfc_attr.c | 314 +- drivers/scsi/lpfc/lpfc_crtn.h | 5 +- drivers/scsi/lpfc/lpfc_debugfs.c | 27 +- drivers/scsi/lpfc/lpfc_els.c | 53 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 24 +- drivers/scsi/lpfc/lpfc_hw.h | 29 +- drivers/scsi/lpfc/lpfc_hw4.h | 4 - drivers/scsi/lpfc/lpfc_init.c | 144 +- drivers/scsi/lpfc/lpfc_nvme.c | 65 +- drivers/scsi/lpfc/lpfc_nvmet.c | 44 +- drivers/scsi/lpfc/lpfc_scsi.c | 122 +- drivers/scsi/lpfc/lpfc_sli.c | 108 +- drivers/scsi/lpfc/lpfc_sli4.h | 2 - drivers/scsi/lpfc/lpfc_vport.c | 83 +- drivers/scsi/mac53c94.c | 6 +- drivers/scsi/megaraid.c | 108 +- drivers/scsi/megaraid/megaraid_mbox.c | 29 +- drivers/scsi/megaraid/megaraid_sas_base.c | 67 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 51 +- drivers/scsi/mesh.c | 18 +- drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h | 603 +-- drivers/scsi/mpi3mr/mpi/mpi30_image.h | 59 +- drivers/scsi/mpi3mr/mpi/mpi30_init.h | 15 +- drivers/scsi/mpi3mr/mpi/mpi30_ioc.h | 128 +- drivers/scsi/mpi3mr/mpi/mpi30_sas.h | 14 - drivers/scsi/mpi3mr/mpi/mpi30_transport.h | 31 +- drivers/scsi/mpi3mr/mpi3mr.h | 123 +- drivers/scsi/mpi3mr/mpi3mr_debug.h | 133 +- drivers/scsi/mpi3mr/mpi3mr_fw.c | 1560 +++--- drivers/scsi/mpi3mr/mpi3mr_os.c | 797 +--- drivers/scsi/mpt3sas/mpt3sas_base.c | 21 +- drivers/scsi/mpt3sas/mpt3sas_base.h | 8 +- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 171 +- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 26 +- drivers/scsi/mvsas/mv_init.c | 12 +- drivers/scsi/mvsas/mv_sas.c | 5 - drivers/scsi/mvumi.c | 4 +- drivers/scsi/myrb.c | 62 +- drivers/scsi/myrs.c | 60 +- drivers/scsi/ncr53c8xx.c | 16 +- drivers/scsi/nsp32.c | 7 +- drivers/scsi/pcmcia/nsp_cs.c | 10 +- drivers/scsi/pcmcia/sym53c500_cs.c | 14 +- drivers/scsi/pm8001/Makefile | 7 +- drivers/scsi/pm8001/pm8001_ctl.c | 94 +- drivers/scsi/pm8001/pm8001_hwi.c | 39 +- drivers/scsi/pm8001/pm8001_init.c | 7 +- drivers/scsi/pm8001/pm8001_sas.c | 38 +- drivers/scsi/pm8001/pm8001_sas.h | 7 +- drivers/scsi/pm8001/pm80xx_hwi.c | 94 +- drivers/scsi/pmcraid.c | 32 +- drivers/scsi/ppa.c | 6 +- drivers/scsi/ps3rom.c | 8 +- drivers/scsi/qedf/drv_fcoe_fw_funcs.c | 8 +- drivers/scsi/qedf/drv_fcoe_fw_funcs.h | 2 +- drivers/scsi/qedf/qedf_attr.c | 15 +- drivers/scsi/qedf/qedf_els.c | 2 +- drivers/scsi/qedf/qedf_io.c | 31 +- drivers/scsi/qedf/qedf_main.c | 12 +- drivers/scsi/qedi/qedi_debugfs.c | 4 +- drivers/scsi/qedi/qedi_fw.c | 77 +- drivers/scsi/qedi/qedi_fw_api.c | 22 +- drivers/scsi/qedi/qedi_fw_iscsi.h | 2 +- drivers/scsi/qedi/qedi_gbl.h | 2 +- drivers/scsi/qedi/qedi_iscsi.c | 4 +- drivers/scsi/qedi/qedi_iscsi.h | 4 +- drivers/scsi/qedi/qedi_sysfs.c | 15 +- drivers/scsi/qla1280.c | 8 +- drivers/scsi/qla2xxx/qla_attr.c | 140 +- drivers/scsi/qla2xxx/qla_bsg.c | 48 - drivers/scsi/qla2xxx/qla_bsg.h | 7 - drivers/scsi/qla2xxx/qla_def.h | 8 +- drivers/scsi/qla2xxx/qla_edif.c | 71 +- drivers/scsi/qla2xxx/qla_edif.h | 10 +- drivers/scsi/qla2xxx/qla_gbl.h | 8 +- drivers/scsi/qla2xxx/qla_gs.c | 3 +- drivers/scsi/qla2xxx/qla_init.c | 62 +- drivers/scsi/qla2xxx/qla_iocb.c | 3 +- drivers/scsi/qla2xxx/qla_isr.c | 4 - drivers/scsi/qla2xxx/qla_mbx.c | 35 +- drivers/scsi/qla2xxx/qla_nvme.c | 26 +- drivers/scsi/qla2xxx/qla_os.c | 103 +- drivers/scsi/qla2xxx/qla_target.c | 2 +- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 73 +- drivers/scsi/qla4xxx/ql4_attr.c | 41 +- drivers/scsi/qla4xxx/ql4_def.h | 4 +- drivers/scsi/qla4xxx/ql4_glbl.h | 3 +- drivers/scsi/qla4xxx/ql4_os.c | 10 +- drivers/scsi/qlogicfas408.c | 7 +- drivers/scsi/qlogicpti.c | 7 +- drivers/scsi/scsi.c | 9 + drivers/scsi/scsi_bsg.c | 8 +- drivers/scsi/scsi_debug.c | 18 +- drivers/scsi/scsi_error.c | 135 +- drivers/scsi/scsi_ioctl.c | 51 +- drivers/scsi/scsi_lib.c | 188 +- drivers/scsi/scsi_logging.c | 4 +- drivers/scsi/scsi_pm.c | 112 +- drivers/scsi/scsi_priv.h | 8 +- drivers/scsi/scsi_scan.c | 77 +- drivers/scsi/scsi_sysfs.c | 42 +- drivers/scsi/scsi_transport_sas.c | 1 - drivers/scsi/sd.c | 182 +- drivers/scsi/sd.h | 1 - drivers/scsi/sd_dif.c | 2 +- drivers/scsi/sd_zbc.c | 14 +- drivers/scsi/sg.c | 52 +- drivers/scsi/smartpqi/smartpqi.h | 61 +- drivers/scsi/smartpqi/smartpqi_init.c | 549 +-- .../scsi/smartpqi/smartpqi_sas_transport.c | 6 +- drivers/scsi/smartpqi/smartpqi_sis.c | 9 +- drivers/scsi/smartpqi/smartpqi_sis.h | 3 +- drivers/scsi/snic/snic.h | 2 +- drivers/scsi/snic/snic_attrs.c | 19 +- drivers/scsi/snic/snic_disc.c | 2 +- drivers/scsi/snic/snic_main.c | 2 +- drivers/scsi/snic/snic_scsi.c | 33 +- drivers/scsi/sr.c | 30 +- drivers/scsi/st.c | 11 +- drivers/scsi/stex.c | 10 +- drivers/scsi/storvsc_drv.c | 58 +- drivers/scsi/sym53c8xx_2/sym_glue.c | 6 +- drivers/scsi/ufs/Kconfig | 32 +- drivers/scsi/ufs/Makefile | 1 - drivers/scsi/ufs/ufs-debugfs.c | 98 +- drivers/scsi/ufs/ufs-exynos.c | 364 +- drivers/scsi/ufs/ufs-exynos.h | 27 +- drivers/scsi/ufs/ufs-hisi.c | 14 +- drivers/scsi/ufs/ufs-mediatek.c | 112 +- drivers/scsi/ufs/ufs-mediatek.h | 27 - drivers/scsi/ufs/ufs-qcom.c | 21 +- drivers/scsi/ufs/ufs.h | 7 - drivers/scsi/ufs/ufshcd-crypto.c | 32 +- drivers/scsi/ufs/ufshcd-crypto.h | 9 +- drivers/scsi/ufs/ufshcd.c | 524 +- drivers/scsi/ufs/ufshcd.h | 66 +- drivers/scsi/ufs/ufshci.h | 15 +- drivers/scsi/ufs/ufshpb.c | 11 +- drivers/scsi/virtio_scsi.c | 12 +- drivers/scsi/vmw_pvscsi.c | 9 +- drivers/scsi/wd33c93.c | 18 +- drivers/scsi/wd719x.c | 4 +- drivers/scsi/xen-scsifront.c | 7 +- drivers/soc/Kconfig | 1 - drivers/soc/Makefile | 1 - drivers/soc/amlogic/meson-canvas.c | 4 +- drivers/soc/amlogic/meson-clk-measure.c | 4 +- drivers/soc/amlogic/meson-gx-socinfo.c | 1 - drivers/soc/aspeed/Kconfig | 10 - drivers/soc/aspeed/Makefile | 9 +- drivers/soc/bcm/bcm63xx/bcm-pmb.c | 4 +- drivers/soc/bcm/bcm63xx/bcm63xx-power.c | 4 +- drivers/soc/bcm/brcmstb/biuctrl.c | 2 - drivers/soc/bcm/brcmstb/pm/pm-mips.c | 5 +- drivers/soc/canaan/Kconfig | 1 + drivers/soc/fsl/Kconfig | 1 - drivers/soc/fsl/dpio/dpio-cmd.h | 3 - drivers/soc/fsl/dpio/dpio-driver.c | 9 +- drivers/soc/fsl/dpio/dpio-service.c | 119 +- drivers/soc/fsl/dpio/dpio.c | 1 - drivers/soc/fsl/dpio/dpio.h | 2 - drivers/soc/fsl/dpio/qbman-portal.c | 66 +- drivers/soc/fsl/dpio/qbman-portal.h | 13 - drivers/soc/fsl/guts.c | 18 +- drivers/soc/fsl/qbman/bman_portal.c | 2 +- drivers/soc/fsl/qbman/qman_portal.c | 2 +- drivers/soc/fsl/qe/qe_io.c | 2 + drivers/soc/fsl/rcpm.c | 7 +- drivers/soc/imx/Kconfig | 1 - drivers/soc/imx/Makefile | 1 - drivers/soc/imx/gpcv2.c | 157 +- drivers/soc/mediatek/mtk-mmsys.c | 79 - drivers/soc/mediatek/mtk-mmsys.h | 2 - drivers/soc/mediatek/mtk-mutex.c | 35 - drivers/soc/qcom/Kconfig | 21 +- drivers/soc/qcom/Makefile | 2 - drivers/soc/qcom/apr.c | 287 +- drivers/soc/qcom/cpr.c | 4 +- drivers/soc/qcom/llcc-qcom.c | 44 - drivers/soc/qcom/ocmem.c | 4 +- drivers/soc/qcom/pdr_interface.c | 12 +- drivers/soc/qcom/qcom-geni-se.c | 4 +- drivers/soc/qcom/qcom_aoss.c | 167 +- drivers/soc/qcom/qcom_gsbi.c | 4 +- drivers/soc/qcom/qmi_interface.c | 2 +- drivers/soc/qcom/rpmh-rsc.c | 6 +- drivers/soc/qcom/rpmhpd.c | 330 +- drivers/soc/qcom/rpmpd.c | 66 +- drivers/soc/qcom/smd-rpm.c | 2 - drivers/soc/qcom/smem.c | 59 +- drivers/soc/qcom/smp2p.c | 154 +- drivers/soc/qcom/socinfo.c | 17 - drivers/soc/renesas/Kconfig | 22 +- drivers/soc/renesas/Makefile | 2 - drivers/soc/renesas/r8a779a0-sysc.c | 380 +- drivers/soc/renesas/rcar-rst.c | 50 +- drivers/soc/renesas/renesas-soc.c | 136 +- drivers/soc/samsung/Kconfig | 18 +- drivers/soc/samsung/Makefile | 5 +- drivers/soc/samsung/exynos-chipid.c | 97 +- drivers/soc/samsung/exynos-pmu.c | 2 - drivers/soc/samsung/exynos5422-asv.c | 1 - drivers/soc/samsung/pm_domains.c | 1 + drivers/soc/sunxi/sunxi_sram.c | 4 +- drivers/soc/tegra/Makefile | 1 - drivers/soc/tegra/common.c | 29 +- drivers/soc/tegra/fuse/fuse-tegra.c | 51 +- drivers/soc/tegra/fuse/fuse-tegra20.c | 33 +- drivers/soc/tegra/fuse/fuse.h | 1 - drivers/soc/tegra/pmc.c | 67 +- drivers/soc/tegra/regulators-tegra20.c | 99 - drivers/soc/tegra/regulators-tegra30.c | 122 - drivers/soc/ti/k3-ringacc.c | 10 +- drivers/soc/ti/k3-socinfo.c | 3 +- drivers/soc/ti/knav_dma.c | 20 +- drivers/soc/ti/ti_sci_inta_msi.c | 94 +- drivers/soc/ti/wkup_m3_ipc.c | 7 +- drivers/soc/xilinx/Kconfig | 10 - drivers/soc/xilinx/Makefile | 1 - drivers/soc/xilinx/zynqmp_pm_domains.c | 91 +- drivers/soc/xilinx/zynqmp_power.c | 55 +- drivers/soundwire/cadence_master.c | 36 +- drivers/soundwire/cadence_master.h | 14 +- drivers/soundwire/intel.c | 261 +- drivers/soundwire/intel_init.c | 2 +- drivers/soundwire/qcom.c | 41 +- drivers/soundwire/stream.c | 4 +- drivers/spi/Kconfig | 37 +- drivers/spi/Makefile | 2 - drivers/spi/spi-amd.c | 113 +- drivers/spi/spi-ar934x.c | 18 +- drivers/spi/spi-at91-usart.c | 27 +- drivers/spi/spi-atmel.c | 38 +- drivers/spi/spi-bcm-qspi.c | 221 +- drivers/spi/spi-cadence-quadspi.c | 238 +- drivers/spi/spi-dln2.c | 4 +- drivers/spi/spi-dw-bt1.c | 9 +- drivers/spi/spi-dw-core.c | 179 +- drivers/spi/spi-dw-dma.c | 55 +- drivers/spi/spi-dw-mmio.c | 22 +- drivers/spi/spi-dw-pci.c | 60 +- drivers/spi/spi-dw.h | 172 +- drivers/spi/spi-fsi.c | 121 +- drivers/spi/spi-fsl-lpspi.c | 8 +- drivers/spi/spi-geni-qcom.c | 284 +- drivers/spi/spi-orion.c | 1 - drivers/spi/spi-pic32.c | 2 + drivers/spi/spi-pxa2xx.c | 61 +- drivers/spi/spi-pxa2xx.h | 7 + drivers/spi/spi-rockchip.c | 13 +- drivers/spi/spi-rpc-if.c | 4 +- drivers/spi/spi-rspi.c | 28 +- drivers/spi/spi-sh-msiof.c | 1 + drivers/spi/spi-stm32.c | 7 +- drivers/spi/spi-tegra20-slink.c | 13 +- drivers/spi/spi-tegra210-quad.c | 15 +- drivers/spi/spi-tle62x0.c | 2 +- drivers/spi/spi-xlp.c | 8 + drivers/spi/spi.c | 416 +- drivers/spi/spidev.c | 9 +- drivers/spmi/Kconfig | 11 - drivers/spmi/Makefile | 1 - drivers/spmi/spmi-pmic-arb.c | 193 +- drivers/ssb/pcihost_wrapper.c | 6 +- drivers/tee/optee/Makefile | 6 +- drivers/tee/optee/call.c | 447 +- drivers/tee/optee/core.c | 740 ++- drivers/tee/optee/optee_msg.h | 36 +- drivers/tee/optee/optee_private.h | 186 +- drivers/tee/optee/optee_rpc_cmd.h | 31 +- drivers/tee/optee/optee_smc.h | 75 +- drivers/tee/optee/rpc.c | 310 +- drivers/tee/optee/shm_pool.c | 6 +- drivers/thermal/Kconfig | 9 - drivers/thermal/Makefile | 1 - drivers/thermal/cpufreq_cooling.c | 6 +- drivers/thermal/gov_user_space.c | 9 - .../intel/int340x_thermal/acpi_thermal_rel.c | 5 +- .../intel/int340x_thermal/acpi_thermal_rel.h | 48 +- .../intel/int340x_thermal/int3400_thermal.c | 10 +- .../intel/int340x_thermal/int3403_thermal.c | 1 - .../processor_thermal_device.h | 1 - .../processor_thermal_device_pci.c | 1 - drivers/thermal/intel/intel_powerclamp.c | 10 +- drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 41 +- drivers/thermal/rcar_gen3_thermal.c | 113 +- drivers/thermal/rockchip_thermal.c | 2 +- drivers/thermal/thermal_core.c | 6 +- drivers/thermal/thermal_mmio.c | 2 +- drivers/thermal/thermal_netlink.c | 16 +- drivers/thermal/thermal_netlink.h | 8 +- drivers/thermal/thermal_sysfs.c | 3 - drivers/thermal/uniphier_thermal.c | 4 - drivers/thunderbolt/acpi.c | 2 +- drivers/thunderbolt/icm.c | 7 +- drivers/thunderbolt/lc.c | 24 - drivers/thunderbolt/path.c | 38 +- drivers/thunderbolt/retimer.c | 28 +- drivers/thunderbolt/switch.c | 493 +- drivers/thunderbolt/tb.c | 91 +- drivers/thunderbolt/tb.h | 106 +- drivers/thunderbolt/tb_msgs.h | 47 +- drivers/thunderbolt/tb_regs.h | 111 +- drivers/thunderbolt/tmu.c | 345 +- drivers/thunderbolt/tunnel.c | 27 +- drivers/thunderbolt/tunnel.h | 9 +- drivers/thunderbolt/usb4.c | 52 +- drivers/thunderbolt/xdomain.c | 18 +- drivers/uio/uio.c | 8 +- drivers/uio/uio_dmem_genirq.c | 6 +- drivers/uio/uio_hv_generic.c | 18 +- drivers/usb/atm/usbatm.c | 6 +- drivers/usb/cdns3/cdns3-plat.c | 14 +- drivers/usb/cdns3/cdnsp-gadget.c | 2 +- drivers/usb/cdns3/host.c | 1 - drivers/usb/chipidea/ci_hdrc_tegra.c | 53 +- drivers/usb/chipidea/core.c | 1 - drivers/usb/chipidea/otg.c | 5 +- drivers/usb/chipidea/udc.c | 8 - drivers/usb/class/cdc-acm.c | 5 + drivers/usb/class/cdc-wdm.c | 2 +- drivers/usb/common/debug.c | 1 - drivers/usb/core/config.c | 4 +- drivers/usb/core/driver.c | 3 +- drivers/usb/core/generic.c | 2 +- drivers/usb/core/hcd.c | 8 +- drivers/usb/core/hub.c | 30 +- drivers/usb/core/port.c | 35 - drivers/usb/core/usb.c | 46 + drivers/usb/dwc2/core.h | 25 +- drivers/usb/dwc2/debugfs.c | 4 +- drivers/usb/dwc2/drd.c | 51 +- drivers/usb/dwc2/gadget.c | 5 +- drivers/usb/dwc2/hcd.c | 12 +- drivers/usb/dwc2/params.c | 75 +- drivers/usb/dwc2/platform.c | 63 +- drivers/usb/dwc3/Kconfig | 7 +- drivers/usb/dwc3/core.c | 29 - drivers/usb/dwc3/core.h | 33 +- drivers/usb/dwc3/dwc3-pci.c | 4 - drivers/usb/dwc3/dwc3-qcom.c | 8 +- drivers/usb/dwc3/gadget.c | 65 +- drivers/usb/dwc3/host.c | 45 +- drivers/usb/early/xhci-dbc.c | 10 +- drivers/usb/gadget/composite.c | 39 +- drivers/usb/gadget/configfs.c | 65 +- drivers/usb/gadget/epautoconf.c | 2 +- drivers/usb/gadget/function/f_fs.c | 2 +- drivers/usb/gadget/function/f_mass_storage.c | 99 +- drivers/usb/gadget/function/f_midi.c | 48 +- drivers/usb/gadget/function/f_phonet.c | 5 +- drivers/usb/gadget/function/f_tcm.c | 31 +- drivers/usb/gadget/function/f_uac1.c | 1 - drivers/usb/gadget/function/f_uac2.c | 24 +- drivers/usb/gadget/function/f_uvc.c | 8 +- drivers/usb/gadget/function/u_audio.c | 94 +- drivers/usb/gadget/function/u_audio.h | 10 +- drivers/usb/gadget/function/u_ether.c | 4 +- drivers/usb/gadget/function/u_uac2.h | 1 + drivers/usb/gadget/function/uvc.h | 4 +- drivers/usb/gadget/function/uvc_queue.c | 2 +- drivers/usb/gadget/function/uvc_v4l2.c | 3 +- drivers/usb/gadget/function/uvc_video.c | 71 +- drivers/usb/gadget/function/uvc_video.h | 2 + drivers/usb/gadget/legacy/inode.c | 15 +- drivers/usb/gadget/udc/amd5536udc.h | 1 + drivers/usb/gadget/udc/aspeed-vhub/dev.c | 19 +- drivers/usb/gadget/udc/aspeed-vhub/ep0.c | 7 - drivers/usb/gadget/udc/aspeed-vhub/hub.c | 47 +- drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 1 - drivers/usb/gadget/udc/at91_udc.c | 69 +- drivers/usb/gadget/udc/at91_udc.h | 8 +- drivers/usb/gadget/udc/bcm63xx_udc.c | 8 +- drivers/usb/gadget/udc/bdc/bdc_core.c | 1 - drivers/usb/gadget/udc/core.c | 10 +- drivers/usb/gadget/udc/goku_udc.c | 6 +- drivers/usb/gadget/udc/mv_udc_core.c | 4 +- drivers/usb/gadget/udc/pxa25x_udc.c | 4 +- drivers/usb/gadget/udc/snps_udc_plat.c | 5 + drivers/usb/gadget/udc/udc-xilinx.c | 86 +- drivers/usb/host/Kconfig | 17 +- drivers/usb/host/Makefile | 1 - drivers/usb/host/dwc_common_port/dwc_os.h | 1 + drivers/usb/host/ehci-atmel.c | 8 - drivers/usb/host/ehci-hub.c | 11 +- drivers/usb/host/ehci-mem.c | 3 +- drivers/usb/host/ehci-mv.c | 2 + drivers/usb/host/fotg210-hcd.c | 16 +- drivers/usb/host/ohci-hcd.c | 3 +- drivers/usb/host/ohci-hub.c | 3 - drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 10 +- drivers/usb/host/ohci-spear.c | 2 +- drivers/usb/host/ohci-tmio.c | 5 + drivers/usb/host/u132-hcd.c | 1 + drivers/usb/host/uhci-platform.c | 6 +- drivers/usb/host/xhci-mtk.c | 18 +- drivers/usb/host/xhci-pci.c | 2 +- drivers/usb/host/xhci.c | 6 +- drivers/usb/image/microtek.c | 5 +- drivers/usb/isp1760/isp1760-if.c | 16 +- drivers/usb/misc/ehset.c | 58 - drivers/usb/misc/usb251xb.c | 4 +- drivers/usb/mtu3/mtu3_plat.c | 2 +- drivers/usb/musb/am35x.c | 2 - drivers/usb/musb/da8xx.c | 20 +- drivers/usb/musb/jz4740.c | 1 - drivers/usb/musb/mediatek.c | 3 - drivers/usb/musb/musb_dsps.c | 15 +- drivers/usb/musb/omap2430.c | 23 +- drivers/usb/musb/sunxi.c | 8 - drivers/usb/musb/ux500.c | 18 +- drivers/usb/phy/phy-mv-usb.c | 5 +- drivers/usb/phy/phy-tahvo.c | 4 + drivers/usb/phy/phy-tegra-usb.c | 198 +- drivers/usb/renesas_usbhs/common.c | 14 +- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/mod.c | 14 +- drivers/usb/serial/ch341.c | 87 +- drivers/usb/serial/cp210x.c | 109 +- drivers/usb/serial/f81232.c | 96 +- drivers/usb/serial/ftdi_sio.c | 53 +- drivers/usb/serial/keyspan_pda.c | 65 +- drivers/usb/serial/kl5kusb105.c | 117 +- drivers/usb/serial/usb-serial.c | 59 +- drivers/usb/storage/scsiglue.c | 13 +- drivers/usb/storage/sierra_ms.c | 2 + drivers/usb/storage/uas.c | 13 +- drivers/usb/storage/usb.c | 4 +- drivers/usb/typec/Makefile | 3 +- drivers/usb/typec/altmodes/Kconfig | 1 - drivers/usb/typec/altmodes/displayport.c | 58 +- drivers/usb/typec/class.c | 2 + drivers/usb/typec/class.h | 10 +- drivers/usb/typec/hd3ss3220.c | 8 +- drivers/usb/typec/port-mapper.c | 301 +- drivers/usb/typec/tipd/core.c | 220 +- drivers/usb/typec/tipd/tps6598x.h | 12 - drivers/usb/typec/tipd/trace.h | 23 - drivers/usb/typec/ucsi/ucsi.c | 359 +- drivers/usb/typec/ucsi/ucsi.h | 3 +- drivers/usb/typec/ucsi/ucsi_acpi.c | 2 +- drivers/usb/usb-skeleton.c | 2 +- drivers/usb/usbip/usbip_event.c | 1 + drivers/vdpa/Kconfig | 8 - drivers/vdpa/Makefile | 1 - drivers/vdpa/ifcvf/ifcvf_main.c | 19 +- drivers/vdpa/mlx5/core/mlx5_vdpa.h | 10 +- drivers/vdpa/mlx5/core/mr.c | 8 +- drivers/vdpa/mlx5/core/resources.c | 13 +- drivers/vdpa/mlx5/net/mlx5_vnet.c | 353 +- drivers/vdpa/vdpa.c | 388 +- drivers/vdpa/vdpa_sim/vdpa_sim.c | 21 +- drivers/vdpa/vdpa_sim/vdpa_sim_blk.c | 3 +- drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 40 +- drivers/vdpa/vdpa_user/iova_domain.c | 8 + drivers/vdpa/vdpa_user/vduse_dev.c | 22 +- drivers/vdpa/virtio_pci/vp_vdpa.c | 28 +- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 62 +- drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c | 4 +- drivers/vfio/mdev/mdev_driver.c | 45 +- drivers/vfio/mdev/vfio_mdev.c | 2 +- drivers/vfio/pci/vfio_pci_core.c | 13 +- drivers/vfio/pci/vfio_pci_igd.c | 252 +- drivers/vfio/platform/vfio_platform_common.c | 13 +- drivers/vfio/vfio.c | 694 +-- drivers/vfio/vfio_iommu_spapr_tce.c | 6 +- drivers/vfio/vfio_iommu_type1.c | 262 +- drivers/vhost/test.c | 1 - drivers/vhost/vdpa.c | 17 +- drivers/vhost/vsock.c | 6 +- drivers/video/backlight/backlight.c | 22 +- drivers/video/backlight/ili9320.c | 3 +- drivers/video/backlight/ili9320.h | 2 +- drivers/video/backlight/lp855x_bl.c | 134 +- drivers/video/backlight/qcom-wled.c | 8 +- drivers/video/backlight/vgg2432a4.c | 4 +- drivers/video/console/vgacon.c | 21 + drivers/video/fbdev/core/fbcon.c | 8 +- drivers/video/fbdev/core/fbcon.h | 2 +- drivers/video/fbdev/core/fbmem.c | 7 +- drivers/video/fbdev/core/fbsysfs.c | 14 +- drivers/video/fbdev/omap/omapfb_main.c | 1 - .../fbdev/omap2/omapfb/dss/display-sysfs.c | 14 +- .../fbdev/omap2/omapfb/dss/manager-sysfs.c | 18 +- .../fbdev/omap2/omapfb/dss/overlay-sysfs.c | 20 +- .../video/fbdev/omap2/omapfb/omapfb-sysfs.c | 12 +- drivers/video/fbdev/simplefb.c | 21 +- drivers/video/fbdev/xen-fbfront.c | 1 - drivers/virt/acrn/hsm.c | 49 - drivers/virt/acrn/hypercall.h | 52 - drivers/virt/acrn/ioreq.c | 3 +- drivers/virt/nitro_enclaves/Kconfig | 17 +- drivers/virt/nitro_enclaves/ne_misc_dev.c | 191 +- drivers/virt/nitro_enclaves/ne_pci_dev.c | 3 +- drivers/virt/nitro_enclaves/ne_pci_dev.h | 8 +- drivers/virtio/Kconfig | 13 +- drivers/virtio/Makefile | 1 - drivers/virtio/virtio.c | 6 - drivers/virtio/virtio_balloon.c | 2 +- drivers/virtio/virtio_dma_buf.c | 1 - drivers/virtio/virtio_mem.c | 414 +- drivers/virtio/virtio_pci_common.c | 58 +- drivers/virtio/virtio_pci_common.h | 16 +- drivers/virtio/virtio_pci_legacy.c | 108 +- drivers/virtio/virtio_pci_modern.c | 6 +- drivers/virtio/virtio_pci_modern_dev.c | 2 +- drivers/virtio/virtio_ring.c | 16 +- drivers/virtio/virtio_vdpa.c | 26 +- drivers/w1/slaves/w1_therm.c | 7 +- drivers/xen/Kconfig | 34 +- drivers/xen/Makefile | 2 +- drivers/xen/balloon.c | 27 +- drivers/xen/gntalloc.c | 25 +- drivers/xen/gntdev-dmabuf.c | 3 - drivers/xen/grant-table.c | 71 +- drivers/xen/mem-reservation.c | 27 +- drivers/xen/pci.c | 76 - drivers/xen/pvcalls-back.c | 1 + drivers/xen/pvcalls-front.c | 9 +- drivers/xen/swiotlb-xen.c | 4 +- drivers/xen/unpopulated-alloc.c | 87 +- drivers/xen/xen-acpi-processor.c | 6 +- drivers/xen/xen-pciback/Makefile | 7 - drivers/xen/xen-pciback/conf_space_header.c | 8 +- drivers/xen/xen-pciback/pci_stub.c | 3 +- drivers/xen/xen-pciback/pciback.h | 5 - drivers/xen/xen-pciback/xenbus.c | 8 +- drivers/xen/xenbus/xenbus_client.c | 24 +- drivers/xen/xenbus/xenbus_probe_frontend.c | 16 +- fs/9p/Kconfig | 1 - fs/9p/acl.c | 11 +- fs/9p/acl.h | 27 +- fs/9p/cache.c | 336 +- fs/9p/cache.h | 120 +- fs/9p/v9fs.c | 39 +- fs/9p/v9fs.h | 30 +- fs/9p/v9fs_vfs.h | 11 +- fs/9p/vfs_addr.c | 350 +- fs/9p/vfs_dentry.c | 4 +- fs/9p/vfs_dir.c | 19 +- fs/9p/vfs_file.c | 41 +- fs/9p/vfs_inode.c | 55 +- fs/9p/vfs_inode_dotl.c | 14 +- fs/9p/vfs_super.c | 17 +- fs/9p/xattr.c | 10 +- fs/9p/xattr.h | 29 +- fs/Kconfig | 12 +- fs/Makefile | 4 +- fs/adfs/inode.c | 4 +- fs/affs/super.c | 2 +- fs/afs/Makefile | 3 + fs/afs/cell.c | 12 + fs/afs/dir.c | 229 +- fs/afs/dir_edit.c | 154 +- fs/afs/file.c | 120 +- fs/afs/inode.c | 105 +- fs/afs/internal.h | 86 +- fs/afs/main.c | 14 + fs/afs/super.c | 1 - fs/afs/volume.c | 29 +- fs/afs/write.c | 442 +- fs/afs/yfsclient.c | 32 +- fs/aio.c | 40 +- fs/anon_inodes.c | 29 - fs/binfmt_elf.c | 43 +- fs/binfmt_elf_fdpic.c | 2 +- fs/btrfs/Kconfig | 3 +- fs/btrfs/Makefile | 2 +- fs/btrfs/backref.c | 56 +- fs/btrfs/block-group.c | 302 +- fs/btrfs/block-group.h | 8 +- fs/btrfs/block-rsv.c | 84 +- fs/btrfs/block-rsv.h | 5 +- fs/btrfs/btrfs_inode.h | 32 +- fs/btrfs/check-integrity.c | 205 +- fs/btrfs/compression.c | 691 ++- fs/btrfs/compression.h | 4 +- fs/btrfs/ctree.c | 699 ++- fs/btrfs/ctree.h | 253 +- fs/btrfs/delalloc-space.c | 2 +- fs/btrfs/delayed-inode.c | 44 +- fs/btrfs/delayed-ref.c | 42 +- fs/btrfs/delayed-ref.h | 51 +- fs/btrfs/dev-replace.c | 28 +- fs/btrfs/dir-item.c | 12 +- fs/btrfs/disk-io.c | 431 +- fs/btrfs/disk-io.h | 16 +- fs/btrfs/extent-tree.c | 414 +- fs/btrfs/extent_io.c | 403 +- fs/btrfs/extent_io.h | 10 +- fs/btrfs/extent_map.c | 6 +- fs/btrfs/extent_map.h | 8 - fs/btrfs/file-item.c | 54 +- fs/btrfs/file.c | 274 +- fs/btrfs/free-space-cache.c | 346 +- fs/btrfs/free-space-cache.h | 10 +- fs/btrfs/free-space-tree.c | 54 +- fs/btrfs/inode-item.c | 344 +- fs/btrfs/inode.c | 1093 +++-- fs/btrfs/ioctl.c | 1427 +++--- fs/btrfs/locking.h | 7 +- fs/btrfs/lzo.c | 295 +- fs/btrfs/print-tree.c | 8 +- fs/btrfs/props.c | 7 +- fs/btrfs/qgroup.c | 17 +- fs/btrfs/raid56.c | 175 +- fs/btrfs/raid56.h | 22 +- fs/btrfs/ref-verify.c | 12 +- fs/btrfs/reflink.c | 4 +- fs/btrfs/relocation.c | 97 +- fs/btrfs/root-tree.c | 27 +- fs/btrfs/scrub.c | 367 +- fs/btrfs/send.c | 455 +- fs/btrfs/send.h | 7 - fs/btrfs/space-info.c | 119 +- fs/btrfs/space-info.h | 2 +- fs/btrfs/subpage.c | 292 +- fs/btrfs/subpage.h | 56 +- fs/btrfs/super.c | 5 +- fs/btrfs/sysfs.c | 104 +- fs/btrfs/tests/btrfs-tests.c | 1 - fs/btrfs/tests/extent-buffer-tests.c | 19 +- fs/btrfs/tests/extent-io-tests.c | 64 +- fs/btrfs/tests/free-space-tests.c | 186 +- fs/btrfs/tests/free-space-tree-tests.c | 5 +- fs/btrfs/tests/inode-tests.c | 4 +- fs/btrfs/tests/qgroup-tests.c | 5 +- fs/btrfs/transaction.c | 238 +- fs/btrfs/transaction.h | 4 +- fs/btrfs/tree-checker.c | 60 +- fs/btrfs/tree-defrag.c | 8 + fs/btrfs/tree-log.c | 1369 +++--- fs/btrfs/tree-log.h | 18 +- fs/btrfs/uuid-tree.c | 10 +- fs/btrfs/verity.c | 2 +- fs/btrfs/volumes.c | 667 ++- fs/btrfs/volumes.h | 122 +- fs/btrfs/xattr.c | 10 +- fs/btrfs/zoned.c | 539 +-- fs/btrfs/zoned.h | 52 +- fs/btrfs/zstd.c | 68 +- fs/buffer.c | 27 +- fs/cachefiles/Kconfig | 7 - fs/cachefiles/Makefile | 6 +- fs/cachefiles/daemon.c | 187 +- fs/cachefiles/interface.c | 791 +-- fs/cachefiles/internal.h | 276 +- fs/cachefiles/io.c | 399 +- fs/cachefiles/key.c | 195 +- fs/cachefiles/main.c | 22 +- fs/cachefiles/namei.c | 1341 +++--- fs/cachefiles/security.c | 2 +- fs/cachefiles/xattr.c | 449 +- fs/ceph/addr.c | 216 +- fs/ceph/cache.c | 267 +- fs/ceph/cache.h | 99 +- fs/ceph/caps.c | 157 +- fs/ceph/debugfs.c | 155 +- fs/ceph/export.c | 12 +- fs/ceph/file.c | 142 +- fs/ceph/inode.c | 76 +- fs/ceph/locks.c | 9 +- fs/ceph/mds_client.c | 139 +- fs/ceph/metric.c | 130 +- fs/ceph/metric.h | 88 +- fs/ceph/quota.c | 17 - fs/ceph/super.c | 185 +- fs/ceph/super.h | 49 +- fs/ceph/xattr.c | 3 +- fs/cifs/Makefile | 2 +- fs/cifs/cifs_debug.c | 11 +- fs/cifs/cifs_dfs_ref.c | 61 +- fs/cifs/cifs_fs_sb.h | 5 + fs/cifs/cifs_spnego.c | 4 +- fs/cifs/cifs_spnego.h | 3 +- fs/cifs/cifs_swn.c | 21 +- fs/cifs/cifsencrypt.c | 6 +- fs/cifs/cifsfs.c | 25 +- fs/cifs/cifsfs.h | 3 +- fs/cifs/cifsglob.h | 127 +- fs/cifs/cifsproto.h | 50 +- fs/cifs/cifssmb.c | 94 +- fs/cifs/connect.c | 1820 +++---- fs/cifs/dfs_cache.c | 53 +- fs/cifs/dir.c | 5 - fs/cifs/file.c | 291 +- fs/cifs/fs_context.c | 50 +- fs/cifs/fs_context.h | 2 - fs/cifs/fscache.c | 447 +- fs/cifs/fscache.h | 195 +- fs/cifs/inode.c | 29 +- fs/cifs/misc.c | 110 +- fs/cifs/netmisc.c | 5 +- fs/cifs/ntlmssp.h | 36 +- fs/cifs/sess.c | 533 +-- fs/cifs/smb1ops.c | 22 +- fs/cifs/smb2glob.h | 2 + fs/cifs/smb2inode.c | 22 +- fs/cifs/smb2maperror.c | 16 +- fs/cifs/smb2misc.c | 52 +- fs/cifs/smb2ops.c | 117 +- fs/cifs/smb2pdu.c | 496 +- fs/cifs/smb2pdu.h | 919 +++- fs/cifs/smb2proto.h | 8 +- fs/cifs/smb2transport.c | 103 +- fs/cifs/trace.h | 71 - fs/cifs/transport.c | 86 +- fs/coda/cnode.c | 13 +- fs/coda/coda_linux.c | 39 +- fs/coda/coda_linux.h | 6 +- fs/coda/dir.c | 20 +- fs/coda/file.c | 12 +- fs/coda/psdev.c | 14 +- fs/coda/upcall.c | 3 +- fs/coredump.c | 166 +- fs/cramfs/inode.c | 2 +- fs/crypto/bio.c | 32 +- fs/crypto/fname.c | 3 +- fs/crypto/fscrypt_private.h | 11 +- fs/crypto/keysetup.c | 5 +- fs/d_path.c | 8 +- fs/dax.c | 155 +- fs/dcache.c | 37 +- fs/direct-io.c | 16 +- fs/dlm/ast.c | 16 +- fs/dlm/debug_fs.c | 96 +- fs/dlm/dir.c | 3 +- fs/dlm/dlm_internal.h | 12 +- fs/dlm/lock.c | 100 +- fs/dlm/lock.h | 4 - fs/dlm/lockspace.c | 41 +- fs/dlm/lowcomms.c | 165 +- fs/dlm/lowcomms.h | 6 +- fs/dlm/main.c | 3 - fs/dlm/member.c | 3 +- fs/dlm/memory.c | 68 +- fs/dlm/memory.h | 6 - fs/dlm/midcomms.c | 85 +- fs/dlm/midcomms.h | 3 - fs/dlm/rcom.c | 2 +- fs/dlm/recoverd.c | 3 +- fs/dlm/requestqueue.c | 17 +- fs/ecryptfs/main.c | 2 +- fs/erofs/Kconfig | 40 +- fs/erofs/Makefile | 3 +- fs/erofs/compress.h | 32 +- fs/erofs/data.c | 214 +- fs/erofs/decompressor.c | 250 +- fs/erofs/erofs_fs.h | 89 +- fs/erofs/inode.c | 70 +- fs/erofs/internal.h | 158 +- fs/erofs/pcpubuf.c | 6 +- fs/erofs/super.c | 315 +- fs/erofs/utils.c | 19 +- fs/erofs/xattr.c | 139 +- fs/erofs/xattr.h | 1 + fs/erofs/zdata.c | 450 +- fs/erofs/zdata.h | 26 +- fs/erofs/zmap.c | 231 +- fs/eventpoll.c | 10 +- fs/exec.c | 66 +- fs/exfat/balloc.c | 2 +- fs/exfat/dir.c | 42 +- fs/exfat/exfat_fs.h | 6 +- fs/exfat/fatent.c | 4 +- fs/exfat/inode.c | 2 +- fs/exfat/misc.c | 3 +- fs/exfat/namei.c | 42 +- fs/exfat/nls.c | 2 +- fs/exfat/super.c | 1 - fs/ext2/ext2.h | 1 - fs/ext2/inode.c | 15 +- fs/ext2/super.c | 16 +- fs/ext4/acl.c | 10 +- fs/ext4/dir.c | 1 + fs/ext4/ext4.h | 38 +- fs/ext4/extents.c | 41 +- fs/ext4/fast_commit.c | 26 +- fs/ext4/file.c | 11 +- fs/ext4/hash.c | 2 +- fs/ext4/inline.c | 18 +- fs/ext4/inode.c | 358 +- fs/ext4/ioctl.c | 319 +- fs/ext4/mballoc.c | 23 +- fs/ext4/move_extent.c | 1 + fs/ext4/namei.c | 14 +- fs/ext4/page-io.c | 17 +- fs/ext4/readpage.c | 6 + fs/ext4/resize.c | 19 +- fs/ext4/super.c | 2149 ++++----- fs/ext4/sysfs.c | 44 +- fs/f2fs/Kconfig | 1 - fs/f2fs/checkpoint.c | 7 +- fs/f2fs/compress.c | 110 +- fs/f2fs/data.c | 450 +- fs/f2fs/dir.c | 10 +- fs/f2fs/f2fs.h | 87 +- fs/f2fs/file.c | 511 +- fs/f2fs/gc.c | 28 +- fs/f2fs/hash.c | 2 +- fs/f2fs/inline.c | 6 +- fs/f2fs/inode.c | 19 +- fs/f2fs/iostat.c | 40 +- fs/f2fs/namei.c | 34 +- fs/f2fs/node.c | 27 +- fs/f2fs/node.h | 5 + fs/f2fs/recovery.c | 26 +- fs/f2fs/segment.c | 100 +- fs/f2fs/segment.h | 1 - fs/f2fs/super.c | 91 +- fs/f2fs/sysfs.c | 57 +- fs/f2fs/verity.c | 2 +- fs/f2fs/xattr.c | 31 +- fs/fat/file.c | 5 +- fs/fat/inode.c | 11 +- fs/file_table.c | 53 +- fs/fs-writeback.c | 43 +- fs/fs_parser.c | 31 +- fs/fscache/Kconfig | 3 - fs/fscache/Makefile | 6 +- fs/fscache/cache.c | 638 ++- fs/fscache/cookie.c | 1474 +++--- fs/fscache/internal.h | 315 +- fs/fscache/io.c | 384 +- fs/fscache/main.c | 147 +- fs/fscache/proc.c | 47 +- fs/fscache/stats.c | 287 +- fs/fuse/Kconfig | 2 +- fs/fuse/dax.c | 41 +- fs/fuse/dev.c | 10 +- fs/fuse/dir.c | 209 +- fs/fuse/file.c | 99 +- fs/fuse/fuse_i.h | 47 +- fs/fuse/inode.c | 131 +- fs/fuse/ioctl.c | 4 +- fs/fuse/readdir.c | 6 +- fs/fuse/virtio_fs.c | 42 +- fs/fuse/xattr.c | 10 +- fs/gfs2/bmap.c | 60 +- fs/gfs2/file.c | 272 +- fs/gfs2/glock.c | 444 +- fs/gfs2/glock.h | 34 +- fs/gfs2/glops.c | 29 +- fs/gfs2/incore.h | 10 +- fs/gfs2/inode.c | 113 +- fs/gfs2/rgrp.c | 70 +- fs/gfs2/rgrp.h | 2 +- fs/gfs2/super.c | 8 +- fs/gfs2/sys.c | 3 +- fs/gfs2/trace_gfs2.h | 9 +- fs/gfs2/util.c | 2 - fs/hfs/inode.c | 6 +- fs/hfs/mdb.c | 2 +- fs/hfsplus/hfsplus_raw.h | 12 +- fs/hfsplus/inode.c | 12 +- fs/hfsplus/wrapper.c | 2 +- fs/hfsplus/xattr.c | 4 +- fs/hostfs/hostfs_kern.c | 3 - fs/hpfs/hpfs.h | 8 +- fs/hugetlbfs/inode.c | 23 +- fs/inode.c | 136 +- fs/internal.h | 14 +- fs/io-wq.c | 102 +- fs/io-wq.h | 83 +- fs/io_uring.c | 2981 ++++++------ fs/ioctl.c | 2 +- fs/iomap/Makefile | 4 +- fs/iomap/buffered-io.c | 618 ++- fs/iomap/direct-io.c | 89 +- fs/jbd2/commit.c | 19 +- fs/jbd2/journal.c | 8 +- fs/jbd2/transaction.c | 53 +- fs/jffs2/background.c | 2 +- fs/jfs/jfs_metapage.c | 1 - fs/jfs/resize.c | 5 +- fs/jfs/super.c | 5 +- fs/kernfs/dir.c | 118 +- fs/kernfs/file.c | 6 +- fs/kernfs/inode.c | 22 +- fs/kernfs/mount.c | 15 +- fs/kernfs/symlink.c | 8 +- fs/ksmbd/Kconfig | 1 + fs/ksmbd/asn1.c | 142 +- fs/ksmbd/auth.c | 65 +- fs/ksmbd/auth.h | 10 +- fs/ksmbd/connection.c | 20 +- fs/ksmbd/connection.h | 8 +- fs/ksmbd/ksmbd_work.c | 1 + fs/ksmbd/ksmbd_work.h | 4 +- fs/ksmbd/mgmt/user_config.c | 10 - fs/ksmbd/mgmt/user_config.h | 1 - fs/ksmbd/mgmt/user_session.h | 1 + fs/ksmbd/oplock.c | 48 +- fs/ksmbd/oplock.h | 2 + fs/ksmbd/server.c | 1 + fs/ksmbd/smb2misc.c | 10 +- fs/ksmbd/smb2ops.c | 9 +- fs/ksmbd/smb2pdu.c | 743 ++- fs/ksmbd/smb2pdu.h | 696 ++- fs/ksmbd/smb_common.c | 13 +- fs/ksmbd/smb_common.h | 55 +- fs/ksmbd/smbacl.c | 19 +- fs/ksmbd/smbacl.h | 5 +- fs/ksmbd/transport_rdma.c | 264 +- fs/ksmbd/transport_rdma.h | 4 +- fs/ksmbd/vfs.c | 8 +- fs/ksmbd/vfs.h | 43 +- fs/ksmbd/vfs_cache.h | 10 + fs/libfs.c | 39 +- fs/lockd/clntproc.c | 3 + fs/lockd/svc.c | 218 +- fs/lockd/svc4proc.c | 2 + fs/lockd/svclock.c | 6 +- fs/lockd/svcproc.c | 2 + fs/lockd/xdr.c | 152 +- fs/lockd/xdr4.c | 153 +- fs/locks.c | 195 +- fs/mpage.c | 7 + fs/namei.c | 65 +- fs/namespace.c | 107 +- fs/netfs/read_helper.c | 180 +- fs/nfs/Makefile | 2 +- fs/nfs/blocklayout/dev.c | 4 +- fs/nfs/callback.c | 36 +- fs/nfs/callback_proc.c | 3 - fs/nfs/callback_xdr.c | 4 +- fs/nfs/client.c | 43 +- fs/nfs/delegation.c | 10 +- fs/nfs/dir.c | 233 +- fs/nfs/direct.c | 4 +- fs/nfs/export.c | 50 +- fs/nfs/file.c | 22 +- fs/nfs/filelayout/filelayout.c | 2 + fs/nfs/filelayout/filelayout.h | 2 +- fs/nfs/filelayout/filelayoutdev.c | 4 +- fs/nfs/flexfilelayout/flexfilelayout.c | 2 + fs/nfs/fs_context.c | 1 - fs/nfs/fscache.c | 488 +- fs/nfs/fscache.h | 182 +- fs/nfs/getroot.c | 21 +- fs/nfs/inode.c | 129 +- fs/nfs/internal.h | 13 +- fs/nfs/namespace.c | 3 +- fs/nfs/nfs3proc.c | 15 +- fs/nfs/nfs42proc.c | 22 +- fs/nfs/nfs4_fs.h | 6 +- fs/nfs/nfs4client.c | 65 +- fs/nfs/nfs4file.c | 14 +- fs/nfs/nfs4proc.c | 383 +- fs/nfs/nfs4session.c | 12 +- fs/nfs/nfs4session.h | 1 - fs/nfs/nfs4state.c | 11 +- fs/nfs/nfs4trace.h | 920 ++-- fs/nfs/nfs4xdr.c | 121 +- fs/nfs/nfstrace.h | 467 +- fs/nfs/pagelist.c | 13 +- fs/nfs/pnfs.h | 4 + fs/nfs/proc.c | 14 +- fs/nfs/read.c | 36 +- fs/nfs/super.c | 35 +- fs/nfs/sysfs.c | 3 +- fs/nfs/write.c | 55 +- fs/nfsd/Kconfig | 1 + fs/nfsd/blocklayout.c | 158 +- fs/nfsd/export.c | 2 +- fs/nfsd/filecache.c | 82 +- fs/nfsd/filecache.h | 1 + fs/nfsd/flexfilelayout.c | 2 +- fs/nfsd/lockd.c | 2 +- fs/nfsd/netns.h | 27 +- fs/nfsd/nfs2acl.c | 44 +- fs/nfsd/nfs3acl.c | 48 +- fs/nfsd/nfs3proc.c | 6 + fs/nfsd/nfs3xdr.c | 434 +- fs/nfsd/nfs4callback.c | 2 +- fs/nfsd/nfs4layouts.c | 5 +- fs/nfsd/nfs4proc.c | 32 +- fs/nfsd/nfs4state.c | 63 +- fs/nfsd/nfs4xdr.c | 75 +- fs/nfsd/nfscache.c | 19 +- fs/nfsd/nfsctl.c | 33 +- fs/nfsd/nfsd.h | 8 +- fs/nfsd/nfsfh.c | 233 +- fs/nfsd/nfsfh.h | 95 +- fs/nfsd/nfsproc.c | 3 - fs/nfsd/nfssvc.c | 250 +- fs/nfsd/nfsxdr.c | 178 +- fs/nfsd/state.h | 5 - fs/nfsd/stats.c | 2 +- fs/nfsd/stats.h | 4 +- fs/nfsd/trace.h | 107 +- fs/nfsd/vfs.c | 184 +- fs/nfsd/vfs.h | 7 +- fs/nfsd/xdr.h | 35 +- fs/nfsd/xdr3.h | 61 +- fs/nfsd/xdr4.h | 7 +- fs/nilfs2/alloc.c | 2 +- fs/nilfs2/alloc.h | 2 +- fs/nilfs2/bmap.c | 2 +- fs/nilfs2/bmap.h | 2 +- fs/nilfs2/btnode.c | 2 +- fs/nilfs2/btnode.h | 2 +- fs/nilfs2/btree.c | 2 +- fs/nilfs2/btree.h | 2 +- fs/nilfs2/cpfile.c | 2 +- fs/nilfs2/cpfile.h | 2 +- fs/nilfs2/dat.c | 2 +- fs/nilfs2/dat.h | 2 +- fs/nilfs2/dir.c | 2 +- fs/nilfs2/direct.c | 2 +- fs/nilfs2/direct.h | 2 +- fs/nilfs2/file.c | 2 +- fs/nilfs2/gcinode.c | 2 +- fs/nilfs2/ifile.c | 2 +- fs/nilfs2/ifile.h | 2 +- fs/nilfs2/inode.c | 2 +- fs/nilfs2/ioctl.c | 4 +- fs/nilfs2/mdt.c | 2 +- fs/nilfs2/mdt.h | 2 +- fs/nilfs2/namei.c | 2 +- fs/nilfs2/nilfs.h | 2 +- fs/nilfs2/page.c | 6 +- fs/nilfs2/page.h | 2 +- fs/nilfs2/recovery.c | 2 +- fs/nilfs2/segbuf.c | 2 +- fs/nilfs2/segbuf.h | 2 +- fs/nilfs2/segment.c | 2 +- fs/nilfs2/segment.h | 2 +- fs/nilfs2/sufile.c | 2 +- fs/nilfs2/sufile.h | 2 +- fs/nilfs2/super.c | 4 +- fs/nilfs2/sysfs.c | 91 +- fs/nilfs2/sysfs.h | 2 +- fs/nilfs2/the_nilfs.c | 4 +- fs/nilfs2/the_nilfs.h | 2 +- fs/notify/dnotify/dnotify.c | 23 +- fs/notify/fanotify/fanotify.c | 326 +- fs/notify/fanotify/fanotify.h | 196 +- fs/notify/fanotify/fanotify_user.c | 228 +- fs/notify/fsnotify.c | 63 +- fs/notify/group.c | 4 +- fs/notify/inotify/inotify_fsnotify.c | 5 +- fs/notify/inotify/inotify_user.c | 17 +- fs/notify/mark.c | 31 +- fs/notify/notification.c | 14 +- fs/ntfs/Kconfig | 1 - fs/ntfs/attrib.c | 2 +- fs/ntfs/file.c | 3 +- fs/ntfs/super.c | 8 +- fs/ntfs3/file.c | 3 +- fs/ntfs3/inode.c | 2 +- fs/ntfs3/ntfs_fs.h | 1 + fs/ntfs3/super.c | 2 +- fs/ocfs2/alloc.c | 23 +- fs/ocfs2/aops.c | 26 +- fs/ocfs2/cluster/heartbeat.c | 2 +- fs/ocfs2/cluster/masklog.c | 11 +- fs/ocfs2/dir.c | 2 +- fs/ocfs2/dlm/dlmdomain.c | 4 +- fs/ocfs2/dlm/dlmmaster.c | 18 +- fs/ocfs2/dlm/dlmrecovery.c | 3 +- fs/ocfs2/dlm/dlmthread.c | 2 +- fs/ocfs2/filecheck.c | 3 +- fs/ocfs2/inode.c | 4 +- fs/ocfs2/journal.c | 37 +- fs/ocfs2/journal.h | 3 +- fs/ocfs2/stackglue.c | 36 +- fs/ocfs2/super.c | 42 +- fs/open.c | 10 +- fs/orangefs/inode.c | 2 +- fs/orangefs/orangefs-sysfs.c | 21 +- fs/orangefs/super.c | 5 +- fs/overlayfs/file.c | 4 +- fs/overlayfs/super.c | 2 +- fs/pipe.c | 64 +- fs/posix_acl.c | 20 +- fs/proc/array.c | 22 +- fs/proc/base.c | 25 +- fs/proc/generic.c | 6 + fs/proc/inode.c | 1 - fs/proc/internal.h | 5 + fs/proc/proc_net.c | 27 +- fs/proc/proc_sysctl.c | 72 +- fs/proc/task_mmu.c | 44 +- fs/proc/vmcore.c | 103 +- fs/proc_namespace.c | 2 +- fs/pstore/blk.c | 8 +- fs/pstore/ftrace.c | 56 +- fs/pstore/platform.c | 2 +- fs/quota/quota.c | 1 - fs/ramfs/inode.c | 12 +- fs/read_write.c | 4 + fs/reiserfs/journal.c | 7 +- fs/reiserfs/super.c | 14 +- fs/remap_range.c | 114 +- fs/select.c | 1 - fs/seq_file.c | 16 + fs/signalfd.c | 5 +- fs/smbfs_common/smbfsctl.h | 2 - fs/squashfs/super.c | 38 +- fs/squashfs/zstd_wrapper.c | 16 +- fs/super.c | 6 +- fs/sync.c | 72 +- fs/sysfs/dir.c | 3 +- fs/sysfs/file.c | 140 +- fs/sysfs/group.c | 15 +- fs/sysfs/sysfs.h | 8 +- fs/sysv/super.c | 6 +- fs/ubifs/Makefile | 2 +- fs/ubifs/crypto.c | 1 + fs/ubifs/dir.c | 4 +- fs/ubifs/gc.c | 19 +- fs/ubifs/io.c | 21 - fs/ubifs/super.c | 22 +- fs/ubifs/ubifs.h | 35 - fs/udf/lowlevel.c | 5 +- fs/udf/super.c | 9 +- fs/unicode/Kconfig | 7 +- fs/unicode/Makefile | 17 +- fs/unicode/mkutf8data.c | 24 +- fs/unicode/utf8-core.c | 105 +- fs/unicode/utf8-norm.c | 268 +- fs/unicode/utf8-selftest.c | 94 +- fs/unicode/utf8n.h | 81 +- fs/userfaultfd.c | 8 +- fs/xfs/kmem.c | 3 +- fs/xfs/kmem.h | 4 + fs/xfs/libxfs/xfs_ag.c | 4 +- fs/xfs/libxfs/xfs_ag.h | 44 +- fs/xfs/libxfs/xfs_ag_resv.c | 3 +- fs/xfs/libxfs/xfs_alloc.c | 120 +- fs/xfs/libxfs/xfs_alloc.h | 38 +- fs/xfs/libxfs/xfs_alloc_btree.c | 63 +- fs/xfs/libxfs/xfs_alloc_btree.h | 5 - fs/xfs/libxfs/xfs_attr.c | 17 +- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 105 +- fs/xfs/libxfs/xfs_bmap.h | 35 +- fs/xfs/libxfs/xfs_bmap_btree.c | 62 +- fs/xfs/libxfs/xfs_bmap_btree.h | 5 - fs/xfs/libxfs/xfs_btree.c | 337 +- fs/xfs/libxfs/xfs_btree.h | 99 +- fs/xfs/libxfs/xfs_btree_staging.c | 8 +- fs/xfs/libxfs/xfs_da_btree.c | 11 +- fs/xfs/libxfs/xfs_da_btree.h | 3 +- fs/xfs/libxfs/xfs_defer.c | 241 +- fs/xfs/libxfs/xfs_defer.h | 41 +- fs/xfs/libxfs/xfs_dquot_buf.c | 4 +- fs/xfs/libxfs/xfs_format.h | 12 +- fs/xfs/libxfs/xfs_fs.h | 39 +- fs/xfs/libxfs/xfs_ialloc.c | 5 +- fs/xfs/libxfs/xfs_ialloc_btree.c | 90 +- fs/xfs/libxfs/xfs_ialloc_btree.h | 5 - fs/xfs/libxfs/xfs_inode_buf.c | 6 +- fs/xfs/libxfs/xfs_inode_fork.c | 24 +- fs/xfs/libxfs/xfs_inode_fork.h | 2 +- fs/xfs/libxfs/xfs_refcount.c | 46 +- fs/xfs/libxfs/xfs_refcount.h | 7 +- fs/xfs/libxfs/xfs_refcount_btree.c | 65 +- fs/xfs/libxfs/xfs_refcount_btree.h | 5 - fs/xfs/libxfs/xfs_rmap.c | 21 +- fs/xfs/libxfs/xfs_rmap.h | 7 +- fs/xfs/libxfs/xfs_rmap_btree.c | 116 +- fs/xfs/libxfs/xfs_rmap_btree.h | 5 - fs/xfs/libxfs/xfs_sb.c | 4 +- fs/xfs/libxfs/xfs_trans_resv.c | 18 +- fs/xfs/libxfs/xfs_trans_space.h | 9 +- fs/xfs/scrub/agheader.c | 66 +- fs/xfs/scrub/agheader_repair.c | 20 +- fs/xfs/scrub/bitmap.c | 22 +- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/btree.c | 123 +- fs/xfs/scrub/btree.h | 17 +- fs/xfs/scrub/dabtree.c | 62 +- fs/xfs/scrub/dir.c | 15 +- fs/xfs/scrub/inode.c | 14 - fs/xfs/scrub/quota.c | 4 +- fs/xfs/scrub/repair.c | 3 - fs/xfs/scrub/repair.h | 3 - fs/xfs/scrub/scrub.c | 68 +- fs/xfs/scrub/scrub.h | 1 + fs/xfs/scrub/trace.c | 11 +- fs/xfs/scrub/trace.h | 10 +- fs/xfs/xfs_aops.c | 57 +- fs/xfs/xfs_attr_inactive.c | 2 +- fs/xfs/xfs_bmap_item.c | 18 +- fs/xfs/xfs_bmap_item.h | 6 +- fs/xfs/xfs_bmap_util.c | 23 +- fs/xfs/xfs_bmap_util.h | 2 +- fs/xfs/xfs_buf.c | 24 +- fs/xfs/xfs_buf.h | 5 +- fs/xfs/xfs_buf_item.c | 8 +- fs/xfs/xfs_buf_item.h | 2 +- fs/xfs/xfs_buf_item_recover.c | 4 +- fs/xfs/xfs_dir2_readdir.c | 53 +- fs/xfs/xfs_dquot.c | 107 +- fs/xfs/xfs_error.c | 3 +- fs/xfs/xfs_extfree_item.c | 33 +- fs/xfs/xfs_extfree_item.h | 6 +- fs/xfs/xfs_file.c | 100 +- fs/xfs/xfs_icache.c | 58 +- fs/xfs/xfs_icreate_item.c | 6 +- fs/xfs/xfs_icreate_item.h | 2 +- fs/xfs/xfs_inode.c | 21 +- fs/xfs/xfs_inode.h | 15 +- fs/xfs/xfs_inode_item.c | 6 +- fs/xfs/xfs_inode_item.h | 2 +- fs/xfs/xfs_ioctl.c | 112 +- fs/xfs/xfs_ioctl.h | 11 +- fs/xfs/xfs_ioctl32.c | 27 + fs/xfs/xfs_ioctl32.h | 22 + fs/xfs/xfs_iomap.c | 84 +- fs/xfs/xfs_iomap.h | 12 +- fs/xfs/xfs_iops.c | 47 +- fs/xfs/xfs_linux.h | 1 - fs/xfs/xfs_log.c | 6 +- fs/xfs/xfs_log_cil.c | 52 +- fs/xfs/xfs_log_priv.h | 2 +- fs/xfs/xfs_log_recover.c | 38 +- fs/xfs/xfs_mount.c | 24 +- fs/xfs/xfs_mount.h | 5 +- fs/xfs/xfs_mru_cache.c | 2 +- fs/xfs/xfs_pnfs.c | 46 +- fs/xfs/xfs_qm.c | 2 +- fs/xfs/xfs_qm_syscalls.c | 11 +- fs/xfs/xfs_refcount_item.c | 18 +- fs/xfs/xfs_refcount_item.h | 6 +- fs/xfs/xfs_reflink.c | 10 +- fs/xfs/xfs_rmap_item.c | 18 +- fs/xfs/xfs_rmap_item.h | 6 +- fs/xfs/xfs_super.c | 349 +- fs/xfs/xfs_symlink.c | 31 +- fs/xfs/xfs_sysfs.c | 40 +- fs/xfs/xfs_trace.h | 2 +- fs/xfs/xfs_trans.c | 27 +- fs/xfs/xfs_trans.h | 8 +- fs/xfs/xfs_trans_dquot.c | 4 +- fs/zonefs/super.c | 6 +- include/linux/acpi.h | 61 +- include/linux/aio.h | 4 + include/linux/amba/bus.h | 24 + include/linux/anon_inodes.h | 4 - include/linux/arch_topology.h | 9 +- include/linux/arm-smccc.h | 5 + include/linux/arm_ffa.h | 2 - include/linux/ata.h | 1 - include/linux/atalk.h | 2 +- include/linux/atomic/atomic-instrumented.h | 135 +- include/linux/audit.h | 37 - include/linux/auxiliary_bus.h | 174 - include/linux/avf/virtchnl.h | 416 +- include/linux/backing-dev-defs.h | 3 - include/linux/backing-dev.h | 26 +- include/linux/bio.h | 205 +- include/linux/bitfield.h | 19 +- include/linux/bitmap.h | 36 +- include/linux/bitops.h | 34 + include/linux/blk-mq.h | 653 +-- include/linux/blk_types.h | 55 +- include/linux/blkdev.h | 936 +++- include/linux/bootconfig.h | 31 +- include/linux/bootmem_info.h | 2 +- include/linux/bottom_half.h | 1 - include/linux/bpf-cgroup.h | 77 +- include/linux/bpf-netns.h | 8 +- include/linux/bpf.h | 224 +- include/linux/bpf_local_storage.h | 6 - include/linux/bpf_types.h | 1 - include/linux/bpf_verifier.h | 33 +- include/linux/bpfptr.h | 1 - include/linux/brcmphy.h | 11 - include/linux/btf.h | 134 +- include/linux/btf_ids.h | 20 +- include/linux/bvec.h | 2 +- include/linux/byteorder/generic.h | 4 +- include/linux/cacheinfo.h | 1 + include/linux/can/bittiming.h | 94 +- include/linux/can/dev.h | 58 +- include/linux/can/skb.h | 5 +- include/linux/cc_platform.h | 11 - include/linux/cdrom.h | 1 - include/linux/ceph/ceph_fs.h | 2 - include/linux/ceph/libceph.h | 5 +- include/linux/ceph/messenger.h | 7 +- include/linux/ceph/osd_client.h | 19 +- include/linux/cgroup-defs.h | 4 +- include/linux/cleancache.h | 5 +- include/linux/clk-provider.h | 23 - include/linux/clk/sunxi-ng.h | 15 + include/linux/clk/tegra.h | 24 +- include/linux/cma.h | 1 - include/linux/compiler-gcc.h | 18 +- include/linux/compiler_attributes.h | 29 +- include/linux/compiler_types.h | 38 +- include/linux/console.h | 6 + include/linux/context_tracking.h | 2 +- include/linux/coredump.h | 10 +- include/linux/counter.h | 728 ++- include/linux/cpufreq.h | 170 +- include/linux/cpuhotplug.h | 3 +- include/linux/cpumask.h | 46 +- include/linux/cpuset.h | 17 - include/linux/crash_dump.h | 30 +- include/linux/cuda.h | 2 +- include/linux/damon.h | 281 +- include/linux/dax.h | 95 +- include/linux/dcache.h | 10 + include/linux/debug_locks.h | 2 + include/linux/decompress/mm.h | 12 +- include/linux/delay.h | 2 +- include/linux/delayacct.h | 107 +- include/linux/device-mapper.h | 8 +- include/linux/device.h | 31 +- include/linux/device/bus.h | 1 - include/linux/device/driver.h | 1 - include/linux/dma-buf.h | 15 +- include/linux/dma-fence.h | 33 +- include/linux/dma-mapping.h | 8 - include/linux/dma-resv.h | 251 +- include/linux/dmaengine.h | 24 +- include/linux/dmar.h | 8 - include/linux/dnotify.h | 3 +- include/linux/dsa/8021q.h | 14 +- include/linux/dsa/loop.h | 1 - include/linux/dsa/ocelot.h | 16 +- include/linux/dsa/sja1105.h | 65 +- include/linux/dtpm.h | 28 +- include/linux/edac.h | 6 - include/linux/efi.h | 53 +- include/linux/elevator.h | 172 +- include/linux/elfcore-compat.h | 5 - include/linux/elfcore.h | 5 - include/linux/energy_model.h | 68 +- include/linux/entry-kvm.h | 2 +- include/linux/etherdevice.h | 37 +- include/linux/ethtool.h | 49 +- include/linux/exportfs.h | 2 + include/linux/fanotify.h | 16 +- include/linux/filter.h | 28 +- include/linux/firewire.h | 11 +- include/linux/firmware.h | 30 +- include/linux/firmware/xlnx-zynqmp.h | 59 +- include/linux/flex_proportions.h | 9 +- include/linux/fortify-string.h | 76 +- include/linux/fpga/fpga-bridge.h | 30 +- include/linux/fpga/fpga-mgr.h | 62 +- include/linux/fpga/fpga-region.h | 36 +- include/linux/frontswap.h | 35 +- include/linux/fs.h | 189 +- include/linux/fs_parser.h | 2 +- include/linux/fscache-cache.h | 650 ++- include/linux/fscache.h | 1140 +++-- include/linux/fscrypt.h | 3 + include/linux/fsi-occ.h | 2 - include/linux/fsl/mc.h | 18 +- include/linux/fsnotify.h | 70 +- include/linux/fsnotify_backend.h | 170 +- include/linux/ftrace.h | 38 +- include/linux/fwnode.h | 1 - include/linux/generic-radix-tree.h | 3 +- include/linux/genhd.h | 129 +- include/linux/gfp.h | 42 +- include/linux/gpio/consumer.h | 2 + include/linux/gpio/driver.h | 21 +- include/linux/gpio/machine.h | 2 - include/linux/hash.h | 5 +- include/linux/hid.h | 97 +- include/linux/highmem-internal.h | 11 - include/linux/highmem.h | 112 +- include/linux/host1x.h | 76 +- include/linux/huge_mm.h | 29 +- include/linux/hugetlb.h | 46 +- include/linux/hugetlb_cgroup.h | 19 - include/linux/hwmon.h | 4 +- include/linux/hyperv.h | 32 +- include/linux/i2c.h | 35 +- include/linux/ieee80211.h | 80 +- include/linux/if_eql.h | 1 - include/linux/if_vlan.h | 9 +- include/linux/iio/buffer-dma.h | 5 + include/linux/iio/buffer.h | 11 - include/linux/iio/buffer_impl.h | 11 - include/linux/iio/common/st_sensors.h | 13 + include/linux/iio/driver.h | 14 - include/linux/iio/iio-opaque.h | 4 - include/linux/iio/iio.h | 5 +- include/linux/iio/imu/adis.h | 2 - include/linux/iio/triggered_buffer.h | 11 +- include/linux/iio/types.h | 1 - include/linux/inetdevice.h | 4 - include/linux/inotify.h | 3 + include/linux/input/cy8ctmg110_pdata.h | 2 +- include/linux/intel-iommu.h | 13 +- include/linux/intel-ish-client-if.h | 4 +- include/linux/intel-svm.h | 6 + include/linux/intel_rapl.h | 6 - include/linux/interrupt.h | 53 +- include/linux/io-mapping.h | 6 + include/linux/io.h | 5 - include/linux/iocontext.h | 49 +- include/linux/iomap.h | 26 +- include/linux/iommu.h | 3 +- include/linux/iova.h | 68 +- include/linux/ipmi.h | 3 - include/linux/ipmi_smi.h | 59 - include/linux/ipv6.h | 1 - include/linux/irq.h | 6 +- include/linux/irq_work.h | 8 - include/linux/irqchip.h | 20 +- include/linux/irqchip/arm-gic-v3.h | 4 +- include/linux/irqdesc.h | 9 +- include/linux/irqdomain.h | 6 +- include/linux/irqflags.h | 23 +- include/linux/jbd2.h | 11 +- include/linux/kallsyms.h | 13 +- include/linux/kasan.h | 26 +- include/linux/kcsan-checks.h | 86 +- include/linux/kcsan.h | 11 +- include/linux/kernel.h | 65 +- include/linux/kernfs.h | 34 +- include/linux/kfence.h | 2 - include/linux/kobject.h | 35 +- include/linux/kprobes.h | 117 +- include/linux/ksm.h | 4 +- include/linux/kthread.h | 30 +- include/linux/kvm_dirty_ring.h | 14 +- include/linux/kvm_host.h | 487 +- include/linux/kvm_types.h | 14 +- include/linux/leds.h | 2 +- include/linux/libata.h | 163 +- include/linux/list.h | 40 +- include/linux/llist.h | 4 +- include/linux/lockd/lockd.h | 9 +- include/linux/lockd/xdr.h | 27 +- include/linux/lockd/xdr4.h | 27 +- include/linux/lockdep.h | 17 + include/linux/lockdep_types.h | 2 +- include/linux/lsm_hook_defs.h | 19 +- include/linux/lsm_hooks.h | 34 +- include/linux/mc146818rtc.h | 6 +- include/linux/mdev.h | 20 + include/linux/mdio.h | 38 - include/linux/mei_cl_bus.h | 3 - include/linux/mem_encrypt.h | 4 + include/linux/memblock.h | 52 +- include/linux/memcontrol.h | 341 +- include/linux/memory.h | 26 +- include/linux/memory_hotplug.h | 3 + include/linux/mempolicy.h | 6 +- include/linux/memremap.h | 29 +- include/linux/mfd/da9063/core.h | 1 - include/linux/mfd/idt8a340_reg.h | 31 +- include/linux/mfd/max77686-private.h | 26 +- include/linux/mfd/ntxec.h | 2 +- include/linux/mfd/rohm-generic.h | 11 +- include/linux/mfd/stm32-lptimer.h | 5 - include/linux/mfd/stm32-timers.h | 4 - include/linux/mfd/ti_am335x_tscadc.h | 118 +- include/linux/mfd/tps65912.h | 2 +- include/linux/mfd/tps68470.h | 11 - include/linux/mhi.h | 21 +- include/linux/micrel_phy.h | 1 - include/linux/migrate.h | 30 +- include/linux/migrate_mode.h | 13 - include/linux/misc_cgroup.h | 6 +- include/linux/mlx4/device.h | 2 +- include/linux/mlx4/driver.h | 22 + include/linux/mlx5/device.h | 64 +- include/linux/mlx5/driver.h | 65 +- include/linux/mlx5/eq.h | 5 +- include/linux/mlx5/eswitch.h | 9 - include/linux/mlx5/fs.h | 16 - include/linux/mlx5/mlx5_ifc.h | 482 +- include/linux/mm.h | 430 +- include/linux/mm_inline.h | 247 +- include/linux/mm_types.h | 289 +- include/linux/mmc/host.h | 8 +- include/linux/mmc/sdhci-pci-data.h | 4 +- include/linux/mmc/sdio_ids.h | 1 - include/linux/mmdebug.h | 20 - include/linux/mmzone.h | 42 +- include/linux/mod_devicetable.h | 14 - include/linux/module.h | 9 +- include/linux/mount.h | 3 + include/linux/mroute_base.h | 2 - include/linux/msi.h | 301 +- include/linux/mtd/mtd.h | 5 +- include/linux/mtd/spi-nor.h | 2 + include/linux/mux/consumer.h | 23 +- include/linux/mux/driver.h | 4 - include/linux/nd.h | 4 +- include/linux/net/intel/iidc.h | 7 +- include/linux/netdevice.h | 546 ++- include/linux/netfilter.h | 10 +- include/linux/netfilter/nf_conntrack_common.h | 10 +- include/linux/netfilter_arp/arp_tables.h | 5 +- include/linux/netfilter_bridge/ebtables.h | 5 +- include/linux/netfilter_ingress.h | 14 +- include/linux/netfilter_ipv4/ip_tables.h | 6 +- include/linux/netfilter_ipv6/ip6_tables.h | 5 +- include/linux/netfs.h | 111 +- include/linux/netlink.h | 4 + include/linux/netpoll.h | 1 - include/linux/nfs.h | 8 + include/linux/nfs4.h | 4 - include/linux/nfs_fs.h | 84 +- include/linux/nfs_fs_sb.h | 11 +- include/linux/nfs_xdr.h | 20 +- include/linux/node.h | 4 +- include/linux/numa.h | 4 - include/linux/nvme-fc-driver.h | 7 - include/linux/nvme-rdma.h | 2 - include/linux/nvme-tcp.h | 1 - include/linux/nvme.h | 30 +- include/linux/nvmem-provider.h | 5 - include/linux/objtool.h | 12 - include/linux/of.h | 425 +- include/linux/of_fdt.h | 10 +- include/linux/of_net.h | 6 - include/linux/once.h | 2 +- include/linux/page-flags.h | 337 +- include/linux/page_idle.h | 100 +- include/linux/page_owner.h | 20 +- include/linux/page_ref.h | 158 +- include/linux/pagemap.h | 815 ++-- include/linux/pagevec.h | 68 +- include/linux/part_stat.h | 1 - include/linux/pci-acpi.h | 8 - include/linux/pci.h | 43 +- include/linux/pci_ids.h | 69 +- include/linux/percpu-refcount.h | 35 +- include/linux/percpu.h | 20 +- include/linux/perf_event.h | 84 +- include/linux/pgtable.h | 8 - include/linux/phy.h | 48 +- include/linux/phylink.h | 110 +- include/linux/pid.h | 1 - include/linux/pid_namespace.h | 5 - include/linux/pinctrl/pinconf-generic.h | 3 - include/linux/pipe_fs_i.h | 4 + include/linux/pktcdvd.h | 12 +- include/linux/platform_data/ad5755.h | 3 +- include/linux/platform_data/brcmfmac.h | 2 +- include/linux/platform_data/clk-fch.h | 2 +- include/linux/platform_data/cros_ec_proto.h | 7 +- include/linux/platform_data/mlxreg.h | 82 - include/linux/platform_data/mtd-nand-omap2.h | 10 +- include/linux/platform_data/ntc_thermistor.h | 22 +- include/linux/platform_data/pata_ixp4xx_cf.h | 4 +- include/linux/platform_data/spi-clps711x.h | 6 +- include/linux/platform_data/ti-sysc.h | 2 - include/linux/platform_data/ux500_wdt.h | 3 +- include/linux/platform_data/x86/asus-wmi.h | 2 - include/linux/plist.h | 5 +- include/linux/pm.h | 101 +- include/linux/pm_opp.h | 20 +- include/linux/pm_runtime.h | 24 - include/linux/pm_wakeirq.h | 9 +- include/linux/pmu.h | 2 +- include/linux/poll.h | 2 + include/linux/power_supply.h | 249 +- include/linux/preempt.h | 26 +- include/linux/printk.h | 4 + include/linux/proc_fs.h | 25 +- include/linux/profile.h | 45 + include/linux/property.h | 19 +- include/linux/psi.h | 1 - include/linux/psi_types.h | 1 - include/linux/psp-sev.h | 21 - include/linux/ptp_classify.h | 1 - include/linux/ptrace.h | 22 +- include/linux/pwm.h | 15 - include/linux/qed/common_hsi.h | 141 +- include/linux/qed/eth_common.h | 1 - include/linux/qed/fcoe_common.h | 362 +- include/linux/qed/iscsi_common.h | 360 +- include/linux/qed/nvmetcp_common.h | 18 +- include/linux/qed/qed_chain.h | 97 +- include/linux/qed/qed_eth_if.h | 23 +- include/linux/qed/qed_if.h | 279 +- include/linux/qed/qed_iscsi_if.h | 2 +- include/linux/qed/qed_ll2_if.h | 42 +- include/linux/qed/qed_nvmetcp_if.h | 17 - include/linux/qed/qed_rdma_if.h | 3 +- include/linux/qed/rdma_common.h | 1 - include/linux/quota.h | 2 +- include/linux/radix-tree.h | 4 +- include/linux/raid/pq.h | 2 +- include/linux/random.h | 2 +- include/linux/ratelimit_types.h | 2 +- include/linux/rcu_segcblist.h | 51 +- include/linux/rcupdate.h | 59 +- include/linux/rcupdate_trace.h | 5 +- include/linux/rcutiny.h | 2 +- include/linux/regmap.h | 7 - include/linux/regulator/driver.h | 81 +- include/linux/regulator/lp872x.h | 17 +- include/linux/regulator/tps62360.h | 6 + include/linux/remoteproc.h | 12 + include/linux/reset.h | 20 - include/linux/rfkill.h | 7 - include/linux/rio_ids.h | 13 + include/linux/rmap.h | 10 +- include/linux/rpmsg.h | 10 - include/linux/rtc.h | 3 - include/linux/rtmutex.h | 9 - include/linux/rwlock.h | 21 +- include/linux/rwlock_api_smp.h | 14 +- include/linux/rwlock_rt.h | 10 - include/linux/rwsem.h | 1 + include/linux/sbitmap.h | 46 +- include/linux/scatterlist.h | 29 +- include/linux/sched.h | 99 +- include/linux/sched/cputime.h | 5 +- include/linux/sched/idle.h | 4 - include/linux/sched/mm.h | 55 - include/linux/sched/signal.h | 38 +- include/linux/sched/sysctl.h | 14 +- include/linux/sched/task.h | 1 - include/linux/sched/topology.h | 15 +- include/linux/sdb.h | 1 + include/linux/security.h | 44 +- include/linux/seq_file.h | 19 +- include/linux/seq_file_net.h | 3 +- include/linux/seqno-fence.h | 30 +- include/linux/serial_8250.h | 2 + include/linux/serial_s3c.h | 9 + include/linux/shmem_fs.h | 3 +- include/linux/shrinker.h | 1 - include/linux/signal.h | 7 +- include/linux/siphash.h | 2 - include/linux/skbuff.h | 132 +- include/linux/skmsg.h | 6 - include/linux/slab.h | 145 +- include/linux/slab_def.h | 16 +- include/linux/slub_def.h | 38 +- include/linux/smp.h | 1 + include/linux/soc/marvell/octeontx2/asm.h | 15 - include/linux/soc/mediatek/mtk-mmsys.h | 3 - include/linux/soc/qcom/apr.h | 70 +- include/linux/soc/qcom/llcc-qcom.h | 3 - include/linux/soc/qcom/smd-rpm.h | 2 - include/linux/soc/renesas/rcar-rst.h | 2 - include/linux/soc/samsung/exynos-chipid.h | 6 +- include/linux/soc/ti/ti_sci_inta_msi.h | 2 + include/linux/socket.h | 2 - include/linux/soundwire/sdw_intel.h | 4 +- include/linux/spi/ads7846.h | 15 + include/linux/spi/max7301.h | 2 +- include/linux/spi/pxa2xx_spi.h | 5 + include/linux/spi/spi.h | 57 +- include/linux/spinlock.h | 16 +- include/linux/spinlock_api_smp.h | 9 + include/linux/spinlock_api_up.h | 1 - include/linux/spinlock_types_up.h | 2 +- include/linux/spinlock_up.h | 1 + include/linux/srcu.h | 3 +- include/linux/stackdepot.h | 34 +- include/linux/stackleak.h | 5 + include/linux/stacktrace.h | 34 +- include/linux/stddef.h | 65 +- include/linux/stmmac.h | 1 - include/linux/string.h | 44 +- include/linux/string_helpers.h | 5 - include/linux/sunrpc/clnt.h | 1 - include/linux/sunrpc/sched.h | 16 +- include/linux/sunrpc/svc.h | 90 +- include/linux/surface_aggregator/device.h | 9 - include/linux/suspend.h | 1 - include/linux/swap.h | 24 +- include/linux/swapfile.h | 3 + include/linux/swiotlb.h | 9 +- include/linux/switchtec.h | 3 +- include/linux/syscalls.h | 10 +- include/linux/sysctl.h | 67 +- include/linux/tcp.h | 2 - include/linux/tee_drv.h | 7 +- include/linux/thread_info.h | 16 +- include/linux/topology.h | 38 - include/linux/torture.h | 17 +- include/linux/tpm.h | 10 - include/linux/trace_events.h | 26 +- include/linux/trace_recursion.h | 27 +- include/linux/tracehook.h | 7 +- include/linux/tty.h | 293 +- include/linux/tty_driver.h | 712 ++- include/linux/tty_flip.h | 21 +- include/linux/tty_ldisc.h | 314 +- include/linux/tty_port.h | 131 +- include/linux/u64_stats_sync.h | 52 +- include/linux/uio.h | 31 +- include/linux/unaligned/packed_struct.h | 2 +- include/linux/unicode.h | 49 +- include/linux/usb.h | 9 + include/linux/usb/ch9.h | 3 +- include/linux/usb/tegra_usb_phy.h | 5 - include/linux/usb/typec.h | 12 + include/linux/vdpa.h | 90 +- include/linux/vermagic.h | 2 +- include/linux/vfio.h | 53 +- include/linux/virtio.h | 1 - include/linux/virtio_config.h | 6 - include/linux/vm_event_item.h | 3 - include/linux/vmalloc.h | 24 +- include/linux/vmstat.h | 113 +- include/linux/wait.h | 3 +- include/linux/wmi.h | 1 - include/linux/workqueue.h | 3 +- include/linux/writeback.h | 24 +- include/linux/ww_mutex.h | 15 +- include/linux/wwan.h | 18 +- include/linux/xarray.h | 18 - include/linux/xz.h | 106 - include/linux/zstd.h | 1296 +++-- include/net/9p/9p.h | 14 +- include/net/9p/client.h | 24 +- include/net/9p/transport.h | 28 +- include/net/act_api.h | 37 +- include/net/af_unix.h | 3 +- include/net/arp.h | 8 +- include/net/ax25.h | 28 +- include/net/bareudp.h | 13 +- include/net/bluetooth/bluetooth.h | 99 - include/net/bluetooth/hci.h | 190 +- include/net/bluetooth/hci_core.h | 144 +- include/net/bluetooth/mgmt.h | 9 +- include/net/bond_options.h | 1 - include/net/bonding.h | 3 +- include/net/busy_poll.h | 14 - include/net/cfg80211.h | 147 +- include/net/checksum.h | 4 - include/net/codel.h | 7 +- include/net/codel_impl.h | 20 +- include/net/codel_qdisc.h | 2 - include/net/datalink.h | 2 +- include/net/devlink.h | 174 +- include/net/dn.h | 2 +- include/net/dsa.h | 323 +- include/net/dst.h | 1 - include/net/failover.h | 1 - include/net/fib_rules.h | 21 + include/net/flow_dissector.h | 1 - include/net/flow_offload.h | 20 +- include/net/gen_stats.h | 59 +- include/net/gro.h | 421 +- include/net/if_inet6.h | 1 - include/net/inet_connection_sock.h | 2 +- include/net/inet_ecn.h | 17 - include/net/inet_sock.h | 12 - include/net/ioam6.h | 3 +- include/net/ip.h | 17 +- include/net/ip6_checksum.h | 20 +- include/net/ip6_fib.h | 1 - include/net/ip6_route.h | 18 +- include/net/ip6_tunnel.h | 1 - include/net/ip_fib.h | 2 - include/net/ip_tunnels.h | 3 - include/net/ip_vs.h | 11 - include/net/ipv6.h | 5 +- include/net/iucv/af_iucv.h | 10 +- include/net/llc.h | 2 +- include/net/llc_conn.h | 1 - include/net/llc_if.h | 3 +- include/net/mac80211.h | 68 +- include/net/mctp.h | 82 +- include/net/mctpdevice.h | 21 - include/net/mptcp.h | 4 - include/net/ndisc.h | 22 +- include/net/neighbour.h | 73 +- include/net/net_namespace.h | 34 - include/net/netfilter/nf_conntrack.h | 11 +- include/net/netfilter/nf_conntrack_extend.h | 4 - include/net/netfilter/nf_tables.h | 50 +- include/net/netfilter/nf_tables_core.h | 6 - include/net/netfilter/nf_tables_ipv4.h | 7 +- include/net/netfilter/nf_tables_ipv6.h | 6 +- include/net/netfilter/xt_rateest.h | 2 +- include/net/netns/bpf.h | 9 +- include/net/netns/core.h | 1 + include/net/netns/ipv4.h | 3 - include/net/page_pool.h | 11 +- include/net/pkt_cls.h | 54 +- include/net/rose.h | 8 +- include/net/route.h | 1 - include/net/sch_generic.h | 84 +- include/net/sctp/sctp.h | 4 +- include/net/sctp/structs.h | 35 +- include/net/sock.h | 241 +- include/net/switchdev.h | 48 +- include/net/tc_act/tc_gate.h | 5 + include/net/tc_act/tc_mirred.h | 1 - include/net/tcp.h | 65 +- include/net/tls.h | 5 +- include/net/udp.h | 24 + include/net/vxlan.h | 1 - include/net/xdp.h | 11 +- include/net/xdp_priv.h | 1 + include/net/xdp_sock.h | 1 - include/net/xdp_sock_drv.h | 22 - include/net/xfrm.h | 4 +- include/net/xsk_buff_pool.h | 48 +- include/soc/arc/timers.h | 4 +- include/soc/fsl/dpaa2-io.h | 9 - include/soc/mscc/ocelot.h | 93 +- include/soc/mscc/ocelot_ana.h | 10 - include/soc/mscc/ocelot_vcap.h | 13 - include/soc/tegra/common.h | 15 - include/soc/tegra/fuse.h | 31 +- include/soc/tegra/irq.h | 9 +- include/soc/tegra/pm.h | 2 +- include/target/target_core_base.h | 3 +- include/target/target_core_fabric.h | 1 - include/uapi/linux/acrn.h | 70 - include/uapi/linux/audit.h | 9 +- include/uapi/linux/bcache.h | 110 +- include/uapi/linux/bpf.h | 241 +- include/uapi/linux/btf.h | 56 +- include/uapi/linux/btrfs.h | 11 +- include/uapi/linux/btrfs_tree.h | 4 +- include/uapi/linux/can/netlink.h | 44 +- include/uapi/linux/cdrom.h | 19 - include/uapi/linux/devlink.h | 2 - include/uapi/linux/dlm_device.h | 4 +- include/uapi/linux/ethtool.h | 30 - include/uapi/linux/ethtool_netlink.h | 18 - include/uapi/linux/fanotify.h | 20 - include/uapi/linux/fuse.h | 60 +- include/uapi/linux/futex.h | 25 - include/uapi/linux/idxd.h | 1 - include/uapi/linux/if_ether.h | 3 +- include/uapi/linux/if_link.h | 2 - include/uapi/linux/input-event-codes.h | 4 +- include/uapi/linux/io_uring.h | 5 - include/uapi/linux/ioam6_iptunnel.h | 29 - include/uapi/linux/ip.h | 1 - include/uapi/linux/ipmi.h | 16 +- include/uapi/linux/ipv6.h | 1 - include/uapi/linux/kvm.h | 48 +- include/uapi/linux/magic.h | 6 - include/uapi/linux/mctp.h | 11 - include/uapi/linux/mdio.h | 9 - include/uapi/linux/module.h | 1 - include/uapi/linux/mptcp.h | 35 - include/uapi/linux/neighbour.h | 35 +- include/uapi/linux/net_tstamp.h | 17 +- include/uapi/linux/netfilter.h | 1 - include/uapi/linux/netfilter/nf_tables.h | 6 +- include/uapi/linux/netfilter/xt_CONNMARK.h | 45 +- include/uapi/linux/netfilter/xt_DSCP.h | 27 +- include/uapi/linux/netfilter/xt_RATEEST.h | 38 +- include/uapi/linux/netfilter_ipv4/ipt_ECN.h | 40 +- include/uapi/linux/nfsd/nfsfh.h | 29 +- include/uapi/linux/nitro_enclaves.h | 10 +- include/uapi/linux/nl80211-vnd-intel.h | 29 - include/uapi/linux/nl80211.h | 178 +- include/uapi/linux/pci_regs.h | 142 +- include/uapi/linux/perf_event.h | 39 +- include/uapi/linux/pfkeyv2.h | 2 - include/uapi/linux/pkt_cls.h | 9 +- include/uapi/linux/pkt_sched.h | 2 - include/uapi/linux/prctl.h | 8 +- include/uapi/linux/resource.h | 13 +- include/uapi/linux/rtc.h | 31 +- include/uapi/linux/rtnetlink.h | 2 - include/uapi/linux/smc.h | 46 +- include/uapi/linux/soundcard.h | 2 +- include/uapi/linux/stddef.h | 37 - include/uapi/linux/sysctl.h | 1 - include/uapi/linux/taskstats.h | 6 +- include/uapi/linux/tls.h | 30 - include/uapi/linux/tty.h | 1 - include/uapi/linux/uuid.h | 10 +- include/uapi/linux/v4l2-controls.h | 293 +- include/uapi/linux/vdpa.h | 13 - include/uapi/linux/videodev2.h | 37 +- include/uapi/linux/virtio_gpio.h | 27 +- include/uapi/linux/virtio_gpu.h | 18 +- include/uapi/linux/virtio_i2c.h | 6 - include/uapi/linux/virtio_iommu.h | 8 +- include/uapi/linux/virtio_mem.h | 9 +- include/uapi/linux/vm_sockets.h | 13 +- include/uapi/linux/xfrm.h | 6 + 5887 files changed, 134132 insertions(+), 209190 deletions(-) diff --git a/drivers/accessibility/speakup/speakup_acntpc.c b/drivers/accessibility/speakup/speakup_acntpc.c index 023172ca22..c1ec087dca 100644 --- a/drivers/accessibility/speakup/speakup_acntpc.c +++ b/drivers/accessibility/speakup/speakup_acntpc.c @@ -247,7 +247,7 @@ static void synth_flush(struct spk_synth *synth) static int synth_probe(struct spk_synth *synth) { unsigned int port_val = 0; - int i; + int i = 0; pr_info("Probing for %s.\n", synth->long_name); if (port_forced) { diff --git a/drivers/accessibility/speakup/speakup_dtlk.c b/drivers/accessibility/speakup/speakup_dtlk.c index a9dd5c45d2..92838d3ae9 100644 --- a/drivers/accessibility/speakup/speakup_dtlk.c +++ b/drivers/accessibility/speakup/speakup_dtlk.c @@ -316,7 +316,7 @@ static struct synth_settings *synth_interrogate(struct spk_synth *synth) static int synth_probe(struct spk_synth *synth) { unsigned int port_val = 0; - int i; + int i = 0; struct synth_settings *sp; pr_info("Probing for DoubleTalk.\n"); diff --git a/drivers/accessibility/speakup/speakup_keypc.c b/drivers/accessibility/speakup/speakup_keypc.c index 1618be87bf..311f4aa0be 100644 --- a/drivers/accessibility/speakup/speakup_keypc.c +++ b/drivers/accessibility/speakup/speakup_keypc.c @@ -254,7 +254,7 @@ static void synth_flush(struct spk_synth *synth) static int synth_probe(struct spk_synth *synth) { unsigned int port_val = 0; - int i; + int i = 0; pr_info("Probing for %s.\n", synth->long_name); if (port_forced) { diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 08cf8a1775..0d1f397cd8 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -88,7 +88,7 @@ static int spk_ttyio_receive_buf2(struct tty_struct *tty, } if (!ldisc_data->buf_free) - /* ttyio_in will tty_flip_buffer_push */ + /* ttyio_in will tty_schedule_flip */ return 0; /* Make sure the consumer has read buf before we have seen @@ -312,7 +312,7 @@ static unsigned char ttyio_in(struct spk_synth *in_synth, int timeout) mb(); ldisc_data->buf_free = true; /* Let TTY push more characters */ - tty_flip_buffer_push(tty->port); + tty_schedule_flip(tty->port); return rv; } diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 273741dedf..1da360c51d 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -11,7 +11,6 @@ menuconfig ACPI depends on ARCH_SUPPORTS_ACPI select PNP select NLS - select CRC32 default y if X86 help Advanced Configuration and Power Interface (ACPI) support for @@ -60,9 +59,6 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT config ACPI_CCA_REQUIRED bool -config ACPI_TABLE_LIB - bool - config ACPI_DEBUGGER bool "AML debugger interface" select ACPI_DEBUG @@ -75,7 +71,7 @@ config ACPI_DEBUGGER if ACPI_DEBUGGER config ACPI_DEBUGGER_USER - tristate "Userspace debugger accessibility" + tristate "Userspace debugger accessiblity" depends on DEBUG_FS help Export /sys/kernel/debug/acpi/acpidbg for userspace utilities @@ -521,28 +517,6 @@ config ACPI_CONFIGFS userspace. The configurable ACPI groups will be visible under /config/acpi, assuming configfs is mounted under /config. -config ACPI_PFRUT - tristate "ACPI Platform Firmware Runtime Update and Telemetry" - depends on 64BIT - help - This mechanism allows certain pieces of the platform firmware - to be updated on the fly while the system is running (runtime) - without the need to restart it, which is key in the cases when - the system needs to be available 100% of the time and it cannot - afford the downtime related to restarting it, or when the work - carried out by the system is particularly important, so it cannot - be interrupted, and it is not practical to wait until it is complete. - - The existing firmware code can be modified (driver update) or - extended by adding new code to the firmware (code injection). - - Besides, the telemetry driver allows user space to fetch telemetry - data from the firmware with the help of the Platform Firmware Runtime - Telemetry interface. - - To compile the drivers as modules, choose M here: - the modules will be called pfr_update and pfr_telemetry. - if ARM64 source "drivers/acpi/arm64/Kconfig" @@ -550,23 +524,6 @@ config ACPI_PPTT bool endif -config ACPI_PCC - bool "ACPI PCC Address Space" - depends on PCC - default y - help - The PCC Address Space also referred as PCC Operation Region pertains - to the region of PCC subspace that succeeds the PCC signature. - - The PCC Operation Region works in conjunction with the PCC Table - (Platform Communications Channel Table). PCC subspaces that are - marked for use as PCC Operation Regions must not be used as PCC - subspaces for the standard ACPI features such as CPPC, RASF, PDTT and - MPST. These standard features must always use the PCC Table instead. - - Enable this feature if you want to set up and install the PCC Address - Space handler to handle PCC OpRegion in the firmware. - source "drivers/acpi/pmic/Kconfig" config ACPI_VIOT diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index bb757148e7..3018714e87 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -9,7 +9,7 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # ACPI Boot-Time Table Parsing # ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y) -tables.o: $(src)/../../include/$(CONFIG_ACPI_CUSTOM_DSDT_FILE) ; +tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ; endif @@ -67,7 +67,6 @@ acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o acpi-$(CONFIG_ACPI_PRMT) += prmt.o -acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o # Address translation acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o @@ -103,7 +102,6 @@ obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o obj-$(CONFIG_ACPI_SPCR_TABLE) += spcr.o obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o obj-$(CONFIG_ACPI_PPTT) += pptt.o -obj-$(CONFIG_ACPI_PFRUT) += pfr_update.o pfr_telemetry.o # processor has its own "processor." module_param namespace processor-y := processor_driver.o diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index db487ff9dd..81aff651a0 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -48,12 +48,19 @@ static const struct acpi_device_id ac_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ac_device_ids); +/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */ +static const struct acpi_ac_bl acpi_ac_blacklist[] = { + { "INT33F4", -1 }, /* X-Powers AXP288 PMIC */ + { "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */ +}; + #ifdef CONFIG_PM_SLEEP static int acpi_ac_resume(struct device *dev); #endif static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); static int ac_sleep_before_get_state_ms; +static int ac_check_pmic = 1; static int ac_only; static struct acpi_driver acpi_ac_driver = { @@ -193,6 +200,12 @@ static int __init thinkpad_e530_quirk(const struct dmi_system_id *d) return 0; } +static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) +{ + ac_check_pmic = 0; + return 0; +} + static int __init ac_only_quirk(const struct dmi_system_id *d) { ac_only = 1; @@ -201,6 +214,13 @@ static int __init ac_only_quirk(const struct dmi_system_id *d) /* Please keep this list alphabetically sorted */ static const struct dmi_system_id ac_dmi_table[] __initconst = { + { + /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ + .callback = ac_do_not_check_pmic_quirk, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), + }, + }, { /* Kodlix GK45 returning incorrect state */ .callback = ac_only_quirk, @@ -208,6 +228,15 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "GK45"), }, }, + { + /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ + .callback = ac_do_not_check_pmic_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), + }, + }, { /* Lenovo Thinkpad e530, see comment in acpi_ac_notify() */ .callback = thinkpad_e530_quirk, @@ -312,16 +341,24 @@ static int acpi_ac_remove(struct acpi_device *device) static int __init acpi_ac_init(void) { + unsigned int i; int result; if (acpi_disabled) return -ENODEV; - if (acpi_quirk_skip_acpi_ac_and_battery()) - return -ENODEV; - dmi_check_system(ac_dmi_table); + if (ac_check_pmic) { + for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++) + if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1", + acpi_ac_blacklist[i].hrv)) { + pr_info("found native %s PMIC, not loading\n", + acpi_ac_blacklist[i].hid); + return -ENODEV; + } + } + result = acpi_bus_register_driver(&acpi_ac_driver); if (result < 0) return -ENODEV; diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index e7934ba79b..6e02448d15 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -87,23 +87,14 @@ static int fch_misc_setup(struct apd_private_data *pdata) if (ret < 0) return -ENOENT; - if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) { - clk_data->name = devm_kzalloc(&adev->dev, obj->string.length, - GFP_KERNEL); - - strcpy(clk_data->name, obj->string.pointer); - } else { - /* Set default name to mclk if entry missing in firmware */ - clk_data->name = "mclk"; - } + if (!acpi_dev_get_property(adev, "is-rv", ACPI_TYPE_INTEGER, &obj)) + clk_data->is_rv = obj->integer.value; list_for_each_entry(rentry, &resource_list, node) { clk_data->base = devm_ioremap(&adev->dev, rentry->res->start, resource_size(rentry->res)); break; } - if (!clk_data->base) - return -ENOMEM; acpi_dev_free_resource_list(&resource_list); diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index bcae0f0357..30b1f511c2 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -712,13 +712,14 @@ static void __lpss_reg_write(u32 val, struct lpss_private_data *pdata, static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val) { - struct acpi_device *adev = ACPI_COMPANION(dev); + struct acpi_device *adev; struct lpss_private_data *pdata; unsigned long flags; int ret; - if (WARN_ON(!adev)) - return -ENODEV; + ret = acpi_bus_get_device(ACPI_HANDLE(dev), &adev); + if (WARN_ON(ret)) + return ret; spin_lock_irqsave(&dev->power.lock, flags); if (pm_runtime_suspended(dev)) { @@ -731,7 +732,6 @@ static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val) goto out; } *val = __lpss_reg_read(pdata, reg); - ret = 0; out: spin_unlock_irqrestore(&dev->power.lock, flags); @@ -750,7 +750,7 @@ static ssize_t lpss_ltr_show(struct device *dev, struct device_attribute *attr, if (ret) return ret; - return sysfs_emit(buf, "%08x\n", ltr_value); + return snprintf(buf, PAGE_SIZE, "%08x\n", ltr_value); } static ssize_t lpss_ltr_mode_show(struct device *dev, @@ -1266,8 +1266,7 @@ static int acpi_lpss_platform_notify(struct notifier_block *nb, if (!id || !id->driver_data) return 0; - adev = ACPI_COMPANION(&pdev->dev); - if (!adev) + if (acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev)) return 0; pdata = acpi_driver_data(adev); diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index ffdcfcd4a1..8f2dc176bb 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -156,6 +156,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { {"BRI0A49"}, /* Boca Complete Ofc Communicator 14.4 Data-FAX */ {"BRI1400"}, /* Boca Research 33,600 ACF Modem */ {"BRI3400"}, /* Boca 33.6 Kbps Internal FD34FSVD */ + {"BRI0A49"}, /* Boca 33.6 Kbps Internal FD34FSVD */ + {"BDP3336"}, /* Best Data Products Inc. Smart One 336F PnP Modem */ {"CPI4050"}, /* Computer Peripherals Inc. EuroViVa CommCenter-33.6 SP PnP */ {"CTL3001"}, /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */ {"CTL3011"}, /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 990ff5b0ae..42ede05972 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -1733,12 +1733,13 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, { struct acpi_device *device = context; struct acpi_device *sibling; + int result; if (handle == device->handle) return AE_CTRL_TERMINATE; - sibling = acpi_fetch_acpi_dev(handle); - if (!sibling) + result = acpi_bus_get_device(handle, &sibling); + if (result) return AE_OK; if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME)) diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index b29ba43694..82a7596434 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -223,11 +223,6 @@ acpi_ev_pci_bar_region_setup(acpi_handle handle, u32 function, void *handler_context, void **region_context); -acpi_status -acpi_ev_data_table_region_setup(acpi_handle handle, - u32 function, - void *handler_context, void **region_context); - acpi_status acpi_ev_default_region_setup(acpi_handle handle, u32 function, diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 0aa0d847cb..9db5ae0f79 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -138,7 +138,6 @@ struct acpi_object_region { union acpi_operand_object *next; acpi_physical_address address; u32 length; - void *pointer; /* Only for data table regions */ }; struct acpi_object_method { diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 533802fe73..e2d0046799 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -35,8 +35,7 @@ acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, acpi_status acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, - acpi_physical_address address, - u8 flags, struct acpi_table_header *table); + acpi_physical_address address, u8 flags); void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc); @@ -87,7 +86,6 @@ acpi_tb_release_table(struct acpi_table_header *table, acpi_status acpi_tb_install_standard_table(acpi_physical_address address, u8 flags, - struct acpi_table_header *table, u8 reload, u8 override, u32 *table_index); void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc); @@ -97,9 +95,7 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node); acpi_status acpi_tb_install_and_load_table(acpi_physical_address address, - u8 flags, - struct acpi_table_header *table, - u8 override, u32 *table_index); + u8 flags, u8 override, u32 *table_index); acpi_status acpi_tb_unload_table(u32 table_index); diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 44c4482698..639635291a 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -531,7 +531,6 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); obj_desc->region.length = table->length; - obj_desc->region.pointer = table; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index 8f43d38dc4..c0cd7147a5 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c @@ -386,7 +386,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node, case ACPI_ADR_SPACE_DATA_TABLE: handler = acpi_ex_data_table_space_handler; - setup = acpi_ev_data_table_region_setup; + setup = NULL; break; default: diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index b9d77d327d..4ef43c8ef5 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -162,16 +162,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, return_ACPI_STATUS(AE_NOT_EXIST); } - if (region_obj->region.space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { - struct acpi_pcc_info *ctx = - handler_desc->address_space.context; - - ctx->internal_buffer = - field_obj->field.internal_pcc_buffer; - ctx->length = (u16)region_obj->region.length; - ctx->subspace_id = (u8)region_obj->region.address; - } - /* * We must exit the interpreter because the region setup will * potentially execute control methods (for example, the _REG method diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index d28dee929e..984c172453 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -406,58 +406,6 @@ acpi_ev_cmos_region_setup(acpi_handle handle, return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_data_table_region_setup - * - * PARAMETERS: handle - Region we are interested in - * function - Start or stop - * handler_context - Address space handler context - * region_context - Region specific context - * - * RETURN: Status - * - * DESCRIPTION: Setup a data_table_region - * - * MUTEX: Assumes namespace is not locked - * - ******************************************************************************/ - -acpi_status -acpi_ev_data_table_region_setup(acpi_handle handle, - u32 function, - void *handler_context, void **region_context) -{ - union acpi_operand_object *region_desc = - (union acpi_operand_object *)handle; - struct acpi_data_table_space_context *local_region_context; - - ACPI_FUNCTION_TRACE(ev_data_table_region_setup); - - if (function == ACPI_REGION_DEACTIVATE) { - if (*region_context) { - ACPI_FREE(*region_context); - *region_context = NULL; - } - return_ACPI_STATUS(AE_OK); - } - - /* Create a new context */ - - local_region_context = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_data_table_space_context)); - if (!(local_region_context)) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Save the data table pointer for use in the handler */ - - local_region_context->pointer = region_desc->region.pointer; - - *region_context = local_region_context; - return_ACPI_STATUS(AE_OK); -} - /******************************************************************************* * * FUNCTION: acpi_ev_default_region_setup diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 6c2685a6a4..0cd9b3738e 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -411,7 +411,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, acpi_ex_exit_interpreter(); status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, - table, TRUE, &table_index); + TRUE, &table_index); acpi_ex_enter_interpreter(); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index deb3674ae7..80b52ad557 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -279,7 +279,6 @@ acpi_ex_create_region(u8 * aml_start, obj_desc->region.space_id = space_id; obj_desc->region.address = 0; obj_desc->region.length = 0; - obj_desc->region.pointer = NULL; obj_desc->region.node = node; obj_desc->region.handler = NULL; obj_desc->common.flags &= diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 48c19908fa..82b713a9a1 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -509,15 +509,8 @@ acpi_ex_data_table_space_handler(u32 function, u64 *value, void *handler_context, void *region_context) { - struct acpi_data_table_space_context *mapping; - char *pointer; - ACPI_FUNCTION_TRACE(ex_data_table_space_handler); - mapping = (struct acpi_data_table_space_context *) region_context; - pointer = ACPI_CAST_PTR(char, mapping->pointer) + - (address - ACPI_PTR_TO_PHYSADDR(mapping->pointer)); - /* * Perform the memory read or write. The bit_width was already * validated. @@ -525,14 +518,14 @@ acpi_ex_data_table_space_handler(u32 function, switch (function) { case ACPI_READ: - memcpy(ACPI_CAST_PTR(char, value), pointer, - ACPI_DIV_8(bit_width)); + memcpy(ACPI_CAST_PTR(char, value), + ACPI_PHYSADDR_TO_PTR(address), ACPI_DIV_8(bit_width)); break; case ACPI_WRITE: - memcpy(pointer, ACPI_CAST_PTR(char, value), - ACPI_DIV_8(bit_width)); + memcpy(ACPI_PHYSADDR_TO_PTR(address), + ACPI_CAST_PTR(char, value), ACPI_DIV_8(bit_width)); break; default: diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index 20360a9db4..ebbca109ed 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c @@ -89,27 +89,14 @@ acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, { /* - * Initialize the table descriptor. Set the pointer to NULL for external - * tables, since the table is not fully mapped at this time. + * Initialize the table descriptor. Set the pointer to NULL, since the + * table is not fully mapped at this time. */ memset(table_desc, 0, sizeof(struct acpi_table_desc)); table_desc->address = address; table_desc->length = table->length; table_desc->flags = flags; ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); - - switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { - case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: - case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: - - table_desc->pointer = table; - break; - - case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: - default: - - break; - } } /******************************************************************************* @@ -145,7 +132,9 @@ acpi_tb_acquire_table(struct acpi_table_desc *table_desc, case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: - table = table_desc->pointer; + table = ACPI_CAST_PTR(struct acpi_table_header, + ACPI_PHYSADDR_TO_PTR(table_desc-> + address)); break; default: @@ -207,8 +196,6 @@ acpi_tb_release_table(struct acpi_table_header *table, * PARAMETERS: table_desc - Table descriptor to be acquired * address - Address of the table * flags - Allocation flags of the table - * table - Pointer to the table (required for virtual - * origins, optional for physical) * * RETURN: Status * @@ -221,52 +208,49 @@ acpi_tb_release_table(struct acpi_table_header *table, acpi_status acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, - acpi_physical_address address, - u8 flags, struct acpi_table_header *table) + acpi_physical_address address, u8 flags) { - u8 mapped_table = FALSE; + struct acpi_table_header *table_header; switch (flags & ACPI_TABLE_ORIGIN_MASK) { case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: /* Get the length of the full table from the header */ - if (!table) { - table = - acpi_os_map_memory(address, - sizeof(struct - acpi_table_header)); - if (!table) { - return (AE_NO_MEMORY); - } - - mapped_table = TRUE; + table_header = + acpi_os_map_memory(address, + sizeof(struct acpi_table_header)); + if (!table_header) { + return (AE_NO_MEMORY); } - break; + acpi_tb_init_table_descriptor(table_desc, address, flags, + table_header); + acpi_os_unmap_memory(table_header, + sizeof(struct acpi_table_header)); + return (AE_OK); case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: - if (!table) { - return (AE_BAD_PARAMETER); + table_header = ACPI_CAST_PTR(struct acpi_table_header, + ACPI_PHYSADDR_TO_PTR(address)); + if (!table_header) { + return (AE_NO_MEMORY); } - break; + acpi_tb_init_table_descriptor(table_desc, address, flags, + table_header); + return (AE_OK); default: - /* Table is not valid yet */ - - return (AE_NO_MEMORY); + break; } - acpi_tb_init_table_descriptor(table_desc, address, flags, table); - if (mapped_table) { - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); - } + /* Table is not valid yet */ - return (AE_OK); + return (AE_NO_MEMORY); } /******************************************************************************* @@ -351,19 +335,7 @@ void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) acpi_tb_release_table(table_desc->pointer, table_desc->length, table_desc->flags); - - switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { - case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: - - table_desc->pointer = NULL; - break; - - case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: - case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: - default: - - break; - } + table_desc->pointer = NULL; return_VOID; } @@ -987,9 +959,6 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) * * PARAMETERS: address - Physical address of the table * flags - Allocation flags of the table - * table - Pointer to the table (required for - * virtual origins, optional for - * physical) * override - Whether override should be performed * table_index - Where table index is returned * @@ -1001,9 +970,7 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) acpi_status acpi_tb_install_and_load_table(acpi_physical_address address, - u8 flags, - struct acpi_table_header *table, - u8 override, u32 *table_index) + u8 flags, u8 override, u32 *table_index) { acpi_status status; u32 i; @@ -1012,7 +979,7 @@ acpi_tb_install_and_load_table(acpi_physical_address address, /* Install the table and load it into the namespace */ - status = acpi_tb_install_standard_table(address, flags, table, TRUE, + status = acpi_tb_install_standard_table(address, flags, TRUE, override, &i); if (ACPI_FAILURE(status)) { goto exit; diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 047bd094ba..5174abfa8a 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -313,7 +313,7 @@ void acpi_tb_parse_fadt(void) acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT. Xdsdt, ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, &acpi_gbl_dsdt_index); + FALSE, TRUE, &acpi_gbl_dsdt_index); /* If Hardware Reduced flag is set, there is no FACS */ @@ -322,14 +322,14 @@ void acpi_tb_parse_fadt(void) acpi_tb_install_standard_table((acpi_physical_address) acpi_gbl_FADT.facs, ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, + FALSE, TRUE, &acpi_gbl_facs_index); } if (acpi_gbl_FADT.Xfacs) { acpi_tb_install_standard_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, + FALSE, TRUE, &acpi_gbl_xfacs_index); } } diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 5649f493a1..8d1e5b5724 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -79,8 +79,6 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, * PARAMETERS: address - Address of the table (might be a virtual * address depending on the table_flags) * flags - Flags for the table - * table - Pointer to the table (required for virtual - * origins, optional for physical) * reload - Whether reload should be performed * override - Whether override should be performed * table_index - Where the table index is returned @@ -98,7 +96,6 @@ acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, acpi_status acpi_tb_install_standard_table(acpi_physical_address address, u8 flags, - struct acpi_table_header *table, u8 reload, u8 override, u32 *table_index) { u32 i; @@ -109,8 +106,7 @@ acpi_tb_install_standard_table(acpi_physical_address address, /* Acquire a temporary table descriptor for validation */ - status = - acpi_tb_acquire_temp_table(&new_table_desc, address, flags, table); + status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Could not acquire table length at %8.8X%8.8X", @@ -213,8 +209,7 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) if (ACPI_SUCCESS(status) && table) { acpi_tb_acquire_temp_table(&new_table_desc, ACPI_PTR_TO_PHYSADDR(table), - ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, - table); + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); ACPI_ERROR_ONLY(override_type = "Logical"); goto finish_override; } @@ -225,8 +220,7 @@ void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) &address, &length); if (ACPI_SUCCESS(status) && address && length) { acpi_tb_acquire_temp_table(&new_table_desc, address, - ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL); + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); ACPI_ERROR_ONLY(override_type = "Physical"); goto finish_override; } @@ -295,8 +289,7 @@ void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { - ACPI_FREE(table_desc->pointer); - table_desc->pointer = NULL; + ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address)); } table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index 4dac16bd63..254823d494 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c @@ -101,8 +101,7 @@ acpi_tb_print_table_header(acpi_physical_address address, ACPI_INFO(("%-4.4s 0x%8.8X%8.8X %06X", header->signature, ACPI_FORMAT_UINT64(address), header->length)); - } else if (ACPI_VALIDATE_RSDP_SIG(ACPI_CAST_PTR(struct acpi_table_rsdp, - header)->signature)) { + } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { /* RSDP has no common fields */ diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 5e8d50a4b6..4b9b329a5a 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -328,7 +328,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address) status = acpi_tb_install_standard_table(address, ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, TRUE, + FALSE, TRUE, &table_index); if (ACPI_SUCCESS(status) && diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 87356d9ad6..38623049b9 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -227,7 +227,9 @@ acpi_status acpi_tb_load_namespace(void) * * FUNCTION: acpi_install_table * - * PARAMETERS: table - Pointer to the ACPI table to be installed. + * PARAMETERS: address - Address of the ACPI table to be installed. + * physical - Whether the address is a physical table + * address or not * * RETURN: Status * @@ -238,54 +240,28 @@ acpi_status acpi_tb_load_namespace(void) ******************************************************************************/ acpi_status ACPI_INIT_FUNCTION -acpi_install_table(struct acpi_table_header *table) +acpi_install_table(acpi_physical_address address, u8 physical) { acpi_status status; + u8 flags; u32 table_index; ACPI_FUNCTION_TRACE(acpi_install_table); - status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), - ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, - table, FALSE, FALSE, - &table_index); + if (physical) { + flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; + } else { + flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; + } + + status = acpi_tb_install_standard_table(address, flags, + FALSE, FALSE, &table_index); return_ACPI_STATUS(status); } ACPI_EXPORT_SYMBOL_INIT(acpi_install_table) -/******************************************************************************* - * - * FUNCTION: acpi_install_physical_table - * - * PARAMETERS: address - Address of the ACPI table to be installed. - * - * RETURN: Status - * - * DESCRIPTION: Dynamically install an ACPI table. - * Note: This function should only be invoked after - * acpi_initialize_tables() and before acpi_load_tables(). - * - ******************************************************************************/ -acpi_status ACPI_INIT_FUNCTION -acpi_install_physical_table(acpi_physical_address address) -{ - acpi_status status; - u32 table_index; - - ACPI_FUNCTION_TRACE(acpi_install_physical_table); - - status = acpi_tb_install_standard_table(address, - ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, - NULL, FALSE, FALSE, - &table_index); - - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL_INIT(acpi_install_physical_table) - /******************************************************************************* * * FUNCTION: acpi_load_table @@ -322,7 +298,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table, u32 *table_idx) ACPI_INFO(("Host-directed Dynamic ACPI Table Load:")); status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table), ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, - table, FALSE, &table_index); + FALSE, &table_index); if (table_idx) { *table_idx = table_index; } diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 8afa1ccaf1..7b8e8bf1e8 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -73,7 +73,6 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { {"Windows 2018", NULL, 0, ACPI_OSI_WIN_10_RS4}, /* Windows 10 version 1803 - Added 11/2018 */ {"Windows 2018.2", NULL, 0, ACPI_OSI_WIN_10_RS5}, /* Windows 10 version 1809 - Added 11/2018 */ {"Windows 2019", NULL, 0, ACPI_OSI_WIN_10_19H1}, /* Windows 10 version 1903 - Added 08/2019 */ - {"Windows 2020", NULL, 0, ACPI_OSI_WIN_10_20H1}, /* Windows 10 version 2004 - Added 08/2021 */ /* Feature Group Strings */ diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 95cc2a9f3e..2882450c44 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -28,10 +28,9 @@ #undef pr_fmt #define pr_fmt(fmt) "EINJ: " fmt -#define SLEEP_UNIT_MIN 1000 /* 1ms */ -#define SLEEP_UNIT_MAX 5000 /* 5ms */ -/* Firmware should respond within 1 seconds */ -#define FIRMWARE_TIMEOUT (1 * USEC_PER_SEC) +#define SPIN_UNIT 100 /* 100ns */ +/* Firmware should respond within 1 milliseconds */ +#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) #define ACPI5_VENDOR_BIT BIT(31) #define MEM_ERROR_MASK (ACPI_EINJ_MEMORY_CORRECTABLE | \ ACPI_EINJ_MEMORY_UNCORRECTABLE | \ @@ -172,13 +171,13 @@ static int einj_get_available_error_type(u32 *type) static int einj_timedout(u64 *t) { - if ((s64)*t < SLEEP_UNIT_MIN) { + if ((s64)*t < SPIN_UNIT) { pr_warn(FW_WARN "Firmware does not respond in time\n"); return 1; } - *t -= SLEEP_UNIT_MIN; - usleep_range(SLEEP_UNIT_MIN, SLEEP_UNIT_MAX); - + *t -= SPIN_UNIT; + ndelay(SPIN_UNIT); + touch_nmi_watchdog(); return 0; } @@ -545,8 +544,7 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE) != REGION_INTERSECTS) && (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY) - != REGION_INTERSECTS) && - !arch_is_platform_page(base_addr))) + != REGION_INTERSECTS))) return -EINVAL; inject: diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 0c5c9acc62..0c8330ed1f 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -449,7 +449,7 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags) return false; pfn = PHYS_PFN(physical_addr); - if (!pfn_valid(pfn) && !arch_is_platform_page(physical_addr)) { + if (!pfn_valid(pfn)) { pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid address in generic error data: %#llx\n", physical_addr); diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 0edc1ed476..277f00b288 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -86,9 +86,7 @@ static int hest_esrc_len(struct acpi_hest_header *hest_hdr) return len; }; -typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); - -static int apei_hest_parse(apei_hest_func_t func, void *data) +int apei_hest_parse(apei_hest_func_t func, void *data) { struct acpi_hest_header *hest_hdr; int i, rc, len; @@ -123,6 +121,7 @@ static int apei_hest_parse(apei_hest_func_t func, void *data) return 0; } +EXPORT_SYMBOL_GPL(apei_hest_parse); /* * Check if firmware advertises firmware first mode. We need FF bit to be set diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index ea31ae0145..ead0114f27 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -52,6 +52,7 @@ static bool battery_driver_registered; static int battery_bix_broken_package; static int battery_notification_delay_ms; static int battery_ac_is_broken; +static int battery_check_pmic = 1; static int battery_quirk_notcharging; static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); @@ -64,6 +65,11 @@ static const struct acpi_device_id battery_device_ids[] = { MODULE_DEVICE_TABLE(acpi, battery_device_ids); +/* Lists of PMIC ACPI HIDs with an (often better) native battery driver */ +static const char * const acpi_battery_blacklist[] = { + "INT33F4", /* X-Powers AXP288 PMIC */ +}; + enum { ACPI_BATTERY_ALARM_PRESENT, ACPI_BATTERY_XINFO_PRESENT, @@ -1101,6 +1107,13 @@ battery_ac_is_broken_quirk(const struct dmi_system_id *d) return 0; } +static int __init +battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) +{ + battery_check_pmic = 0; + return 0; +} + static int __init battery_quirk_not_charging(const struct dmi_system_id *d) { battery_quirk_notcharging = 1; @@ -1135,6 +1148,22 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"), }, }, + { + /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ + .callback = battery_do_not_check_pmic_quirk, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), + }, + }, + { + /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ + .callback = battery_do_not_check_pmic_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), + }, + }, { /* * On Lenovo ThinkPads the BIOS specification defines @@ -1272,13 +1301,20 @@ static struct acpi_driver acpi_battery_driver = { static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) { + unsigned int i; int result; - if (acpi_quirk_skip_acpi_ac_and_battery()) - return; - dmi_check_system(bat_dmi_table); + if (battery_check_pmic) { + for (i = 0; i < ARRAY_SIZE(acpi_battery_blacklist); i++) + if (acpi_dev_present(acpi_battery_blacklist[i], "1", -1)) { + pr_info("found native %s PMIC, not loading\n", + acpi_battery_blacklist[i]); + return; + } + } + result = acpi_bus_register_driver(&acpi_battery_driver); battery_driver_registered = (result == 0); } diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 07f604832f..dd535b4b9a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1043,7 +1043,6 @@ struct bus_type acpi_bus_type = { .remove = acpi_device_remove, .uevent = acpi_device_uevent, }; -EXPORT_SYMBOL_GPL(acpi_bus_type); /* -------------------------------------------------------------------------- Initialization/Cleanup @@ -1321,7 +1320,6 @@ static int __init acpi_init(void) pr_debug("%s: kset create error\n", __func__); init_prmt(); - acpi_init_pcc(); result = acpi_bus_init(); if (result) { kobject_put(acpi_kobj); diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 866560cbb0..6fe28a2d38 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -43,7 +43,7 @@ #include struct cppc_pcc_data { - struct pcc_mbox_chan *pcc_channel; + struct mbox_chan *pcc_channel; void __iomem *pcc_comm_addr; bool pcc_channel_acquired; unsigned int deadline_us; @@ -118,8 +118,6 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); */ #define NUM_RETRIES 500ULL -#define OVER_16BTS_MASK ~0xFFFFULL - #define define_one_cppc_ro(_name) \ static struct kobj_attribute _name = \ __ATTR(_name, 0444, show_##_name, NULL) @@ -181,11 +179,10 @@ static struct attribute *cppc_attrs[] = { &lowest_freq.attr, NULL }; -ATTRIBUTE_GROUPS(cppc); static struct kobj_type cppc_ktype = { .sysfs_ops = &kobj_sysfs_ops, - .default_groups = cppc_groups, + .default_attrs = cppc_attrs, }; static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) @@ -298,7 +295,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) pcc_ss_data->platform_owns_pcc = true; /* Ring doorbell */ - ret = mbox_send_message(pcc_ss_data->pcc_channel->mchan, &cmd); + ret = mbox_send_message(pcc_ss_data->pcc_channel, &cmd); if (ret < 0) { pr_err("Err sending PCC mbox message. ss: %d cmd:%d, ret:%d\n", pcc_ss_id, cmd, ret); @@ -311,10 +308,10 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) if (pcc_ss_data->pcc_mrtt) pcc_ss_data->last_cmd_cmpl_time = ktime_get(); - if (pcc_ss_data->pcc_channel->mchan->mbox->txdone_irq) - mbox_chan_txdone(pcc_ss_data->pcc_channel->mchan, ret); + if (pcc_ss_data->pcc_channel->mbox->txdone_irq) + mbox_chan_txdone(pcc_ss_data->pcc_channel, ret); else - mbox_client_txdone(pcc_ss_data->pcc_channel->mchan, ret); + mbox_client_txdone(pcc_ss_data->pcc_channel, ret); end: if (cmd == CMD_WRITE) { @@ -496,33 +493,46 @@ EXPORT_SYMBOL_GPL(acpi_get_psd_map); static int register_pcc_channel(int pcc_ss_idx) { - struct pcc_mbox_chan *pcc_chan; + struct acpi_pcct_hw_reduced *cppc_ss; u64 usecs_lat; if (pcc_ss_idx >= 0) { - pcc_chan = pcc_mbox_request_channel(&cppc_mbox_cl, pcc_ss_idx); + pcc_data[pcc_ss_idx]->pcc_channel = + pcc_mbox_request_channel(&cppc_mbox_cl, pcc_ss_idx); - if (IS_ERR(pcc_chan)) { + if (IS_ERR(pcc_data[pcc_ss_idx]->pcc_channel)) { pr_err("Failed to find PCC channel for subspace %d\n", pcc_ss_idx); return -ENODEV; } - pcc_data[pcc_ss_idx]->pcc_channel = pcc_chan; + /* + * The PCC mailbox controller driver should + * have parsed the PCCT (global table of all + * PCC channels) and stored pointers to the + * subspace communication region in con_priv. + */ + cppc_ss = (pcc_data[pcc_ss_idx]->pcc_channel)->con_priv; + + if (!cppc_ss) { + pr_err("No PCC subspace found for %d CPPC\n", + pcc_ss_idx); + return -ENODEV; + } + /* * cppc_ss->latency is just a Nominal value. In reality * the remote processor could be much slower to reply. * So add an arbitrary amount of wait on top of Nominal. */ - usecs_lat = NUM_RETRIES * pcc_chan->latency; + usecs_lat = NUM_RETRIES * cppc_ss->latency; pcc_data[pcc_ss_idx]->deadline_us = usecs_lat; - pcc_data[pcc_ss_idx]->pcc_mrtt = pcc_chan->min_turnaround_time; - pcc_data[pcc_ss_idx]->pcc_mpar = pcc_chan->max_access_rate; - pcc_data[pcc_ss_idx]->pcc_nominal = pcc_chan->latency; + pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; + pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; + pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; pcc_data[pcc_ss_idx]->pcc_comm_addr = - acpi_os_ioremap(pcc_chan->shmem_base_addr, - pcc_chan->shmem_size); + acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); if (!pcc_data[pcc_ss_idx]->pcc_comm_addr) { pr_err("Failed to ioremap PCC comm region mem for %d\n", pcc_ss_idx); @@ -607,30 +617,47 @@ static bool is_cppc_supported(int revision, int num_ent) /* * An example CPC table looks like the following. * - * Name (_CPC, Package() { - * 17, // NumEntries - * 1, // Revision - * ResourceTemplate() {Register(PCC, 32, 0, 0x120, 2)}, // Highest Performance - * ResourceTemplate() {Register(PCC, 32, 0, 0x124, 2)}, // Nominal Performance - * ResourceTemplate() {Register(PCC, 32, 0, 0x128, 2)}, // Lowest Nonlinear Performance - * ResourceTemplate() {Register(PCC, 32, 0, 0x12C, 2)}, // Lowest Performance - * ResourceTemplate() {Register(PCC, 32, 0, 0x130, 2)}, // Guaranteed Performance Register - * ResourceTemplate() {Register(PCC, 32, 0, 0x110, 2)}, // Desired Performance Register - * ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, - * ... - * ... - * ... - * } + * Name(_CPC, Package() + * { + * 17, + * NumEntries + * 1, + * // Revision + * ResourceTemplate(){Register(PCC, 32, 0, 0x120, 2)}, + * // Highest Performance + * ResourceTemplate(){Register(PCC, 32, 0, 0x124, 2)}, + * // Nominal Performance + * ResourceTemplate(){Register(PCC, 32, 0, 0x128, 2)}, + * // Lowest Nonlinear Performance + * ResourceTemplate(){Register(PCC, 32, 0, 0x12C, 2)}, + * // Lowest Performance + * ResourceTemplate(){Register(PCC, 32, 0, 0x130, 2)}, + * // Guaranteed Performance Register + * ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)}, + * // Desired Performance Register + * ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)}, + * .. + * .. + * .. + * + * } * Each Register() encodes how to access that specific register. * e.g. a sample PCC entry has the following encoding: * - * Register ( - * PCC, // AddressSpaceKeyword - * 8, // RegisterBitWidth - * 8, // RegisterBitOffset - * 0x30, // RegisterAddress - * 9, // AccessSize (subspace ID) - * ) + * Register ( + * PCC, + * AddressSpaceKeyword + * 8, + * //RegisterBitWidth + * 8, + * //RegisterBitOffset + * 0x30, + * //RegisterAddress + * 9 + * //AccessSize (subspace ID) + * 0 + * ) + * } */ #ifndef init_freq_invariance_cppc @@ -732,26 +759,9 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) goto out_free; cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr; } - } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - if (gas_t->access_width < 1 || gas_t->access_width > 3) { - /* - * 1 = 8-bit, 2 = 16-bit, and 3 = 32-bit. - * SystemIO doesn't implement 64-bit - * registers. - */ - pr_debug("Invalid access width %d for SystemIO register\n", - gas_t->access_width); - goto out_free; - } - if (gas_t->address & OVER_16BTS_MASK) { - /* SystemIO registers use 16-bit integer addresses */ - pr_debug("Invalid IO port %llu for SystemIO register\n", - gas_t->address); - goto out_free; - } } else { if (gas_t->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_supported()) { - /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */ + /* Support only PCC ,SYS MEM and FFH type regs */ pr_debug("Unsupported register type: %d\n", gas_t->space_id); goto out_free; } @@ -915,33 +925,18 @@ int __weak cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) { + int ret_val = 0; void __iomem *vaddr = NULL; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; if (reg_res->type == ACPI_TYPE_INTEGER) { *val = reg_res->cpc_entry.int_value; - return 0; + return ret_val; } *val = 0; - - if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = 8 << (reg->access_width - 1); - u32 val_u32; - acpi_status status; - - status = acpi_os_read_port((acpi_io_address)reg->address, - &val_u32, width); - if (ACPI_FAILURE(status)) { - pr_debug("Error: Failed to read SystemIO port %llx\n", - reg->address); - return -EFAULT; - } - - *val = val_u32; - return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; @@ -967,10 +962,10 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) default: pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", reg->bit_width, pcc_ss_id); - return -EFAULT; + ret_val = -EFAULT; } - return 0; + return ret_val; } static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) @@ -980,20 +975,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; - if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = 8 << (reg->access_width - 1); - acpi_status status; - - status = acpi_os_write_port((acpi_io_address)reg->address, - (u32)val, width); - if (ACPI_FAILURE(status)) { - pr_debug("Error: Failed to write SystemIO port %llx\n", - reg->address); - return -EFAULT; - } - - return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; @@ -1260,51 +1242,6 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) } EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); -/** - * cppc_set_enable - Set to enable CPPC on the processor by writing the - * Continuous Performance Control package EnableRegister field. - * @cpu: CPU for which to enable CPPC register. - * @enable: 0 - disable, 1 - enable CPPC feature on the processor. - * - * Return: 0 for success, -ERRNO or -EIO otherwise. - */ -int cppc_set_enable(int cpu, bool enable) -{ - int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); - struct cpc_register_resource *enable_reg; - struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); - struct cppc_pcc_data *pcc_ss_data = NULL; - int ret = -EINVAL; - - if (!cpc_desc) { - pr_debug("No CPC descriptor for CPU:%d\n", cpu); - return -EINVAL; - } - - enable_reg = &cpc_desc->cpc_regs[ENABLE]; - - if (CPC_IN_PCC(enable_reg)) { - - if (pcc_ss_id < 0) - return -EIO; - - ret = cpc_write(cpu, enable_reg, enable); - if (ret) - return ret; - - pcc_ss_data = pcc_data[pcc_ss_id]; - - down_write(&pcc_ss_data->pcc_lock); - /* after writing CPC, transfer the ownership of PCC to platfrom */ - ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE); - up_write(&pcc_ss_data->pcc_lock); - return ret; - } - - return cpc_write(cpu, enable_reg, enable); -} -EXPORT_SYMBOL_GPL(cppc_set_enable); - /** * cppc_set_perf - Set a CPU's performance controls. * @cpu: CPU for which to set performance controls. diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index cc6c97e7dc..0028b6b51c 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -285,12 +285,14 @@ EXPORT_SYMBOL(acpi_device_set_power); int acpi_bus_set_power(acpi_handle handle, int state) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; + int result; - if (device) - return acpi_device_set_power(device, state); + result = acpi_bus_get_device(handle, &device); + if (result) + return result; - return -ENODEV; + return acpi_device_set_power(device, state); } EXPORT_SYMBOL(acpi_bus_set_power); @@ -408,20 +410,21 @@ EXPORT_SYMBOL_GPL(acpi_device_update_power); int acpi_bus_update_power(acpi_handle handle, int *state_p) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; + int result; - if (device) - return acpi_device_update_power(device, state_p); - - return -ENODEV; + result = acpi_bus_get_device(handle, &device); + return result ? result : acpi_device_update_power(device, state_p); } EXPORT_SYMBOL_GPL(acpi_bus_update_power); bool acpi_bus_power_manageable(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; + int result; - return device && device->flags.power_manageable; + result = acpi_bus_get_device(handle, &device); + return result ? false : device->flags.power_manageable; } EXPORT_SYMBOL(acpi_bus_power_manageable); @@ -540,9 +543,11 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) bool acpi_bus_can_wakeup(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; + int result; - return device && device->wakeup.flags.valid; + result = acpi_bus_get_device(handle, &device); + return result ? false : device->wakeup.flags.valid; } EXPORT_SYMBOL(acpi_bus_can_wakeup); @@ -1395,30 +1400,4 @@ bool acpi_storage_d3(struct device *dev) } EXPORT_SYMBOL_GPL(acpi_storage_d3); -/** - * acpi_dev_state_d0 - Tell if the device is in D0 power state - * @dev: Physical device the ACPI power state of which to check - * - * On a system without ACPI, return true. On a system with ACPI, return true if - * the current ACPI power state of the device is D0, or false otherwise. - * - * Note that the power state of a device is not well-defined after it has been - * passed to acpi_device_set_power() and before that function returns, so it is - * not valid to ask for the ACPI power state of the device in that time frame. - * - * This function is intended to be used in a driver's probe or remove - * function. See Documentation/firmware-guide/acpi/low-power-probe.rst for - * more information. - */ -bool acpi_dev_state_d0(struct device *dev) -{ - struct acpi_device *adev = ACPI_COMPANION(dev); - - if (!adev) - return true; - - return adev->power.state == ACPI_STATE_D0; -} -EXPORT_SYMBOL_GPL(acpi_dev_state_d0); - #endif /* CONFIG_PM */ diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index d5d6403ba0..61271e61c3 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -53,7 +53,6 @@ static struct attribute *acpi_data_node_default_attrs[] = { &data_node_path.attr, NULL }; -ATTRIBUTE_GROUPS(acpi_data_node_default); #define to_data_node(k) container_of(k, struct acpi_data_node, kobj) #define to_attr(a) container_of(a, struct acpi_data_node_attr, attr) @@ -80,7 +79,7 @@ static void acpi_data_node_release(struct kobject *kobj) static struct kobj_type acpi_data_node_ktype = { .sysfs_ops = &acpi_data_node_sysfs_ops, - .default_groups = acpi_data_node_default_groups, + .default_attrs = acpi_data_node_default_attrs, .release = acpi_data_node_release, }; diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index a89bdbe001..7cf9215800 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -489,9 +489,10 @@ static ssize_t docked_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; - struct acpi_device *adev = acpi_fetch_acpi_dev(dock_station->handle); + struct acpi_device *adev = NULL; - return sysfs_emit(buf, "%u\n", acpi_device_enumerated(adev)); + acpi_bus_get_device(dock_station->handle, &adev); + return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); } static DEVICE_ATTR_RO(docked); @@ -503,7 +504,7 @@ static ssize_t flags_show(struct device *dev, { struct dock_station *dock_station = dev->platform_data; - return sysfs_emit(buf, "%d\n", dock_station->flags); + return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); } static DEVICE_ATTR_RO(flags); @@ -542,7 +543,7 @@ static ssize_t uid_show(struct device *dev, if (ACPI_FAILURE(status)) return 0; - return sysfs_emit(buf, "%llx\n", lbuf); + return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf); } static DEVICE_ATTR_RO(uid); @@ -561,7 +562,7 @@ static ssize_t type_show(struct device *dev, else type = "unknown"; - return sysfs_emit(buf, "%s\n", type); + return snprintf(buf, PAGE_SIZE, "%s\n", type); } static DEVICE_ATTR_RO(type); diff --git a/drivers/acpi/dptf/dptf_pch_fivr.c b/drivers/acpi/dptf/dptf_pch_fivr.c index c0da24c9f8..f4e9c2ef2f 100644 --- a/drivers/acpi/dptf/dptf_pch_fivr.c +++ b/drivers/acpi/dptf/dptf_pch_fivr.c @@ -46,7 +46,7 @@ static int pch_fivr_read(acpi_handle handle, char *method, struct pch_fivr_resp } /* - * Presentation of attributes which are defined for INTC10xx + * Presentation of attributes which are defined for INT1045 * They are: * freq_mhz_low_clock : Set PCH FIVR switching freq for * FIVR clock 19.2MHz and 24MHz @@ -151,7 +151,6 @@ static int pch_fivr_remove(struct platform_device *pdev) static const struct acpi_device_id pch_fivr_device_ids[] = { {"INTC1045", 0}, {"INTC1049", 0}, - {"INTC10A3", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, pch_fivr_device_ids); diff --git a/drivers/acpi/dptf/dptf_power.c b/drivers/acpi/dptf/dptf_power.c index dc1f52a5b3..a24d5d7aa1 100644 --- a/drivers/acpi/dptf/dptf_power.c +++ b/drivers/acpi/dptf/dptf_power.c @@ -231,8 +231,6 @@ static const struct acpi_device_id int3407_device_ids[] = { {"INTC1050", 0}, {"INTC1060", 0}, {"INTC1061", 0}, - {"INTC10A4", 0}, - {"INTC10A5", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, int3407_device_ids); diff --git a/drivers/acpi/dptf/int340x_thermal.c b/drivers/acpi/dptf/int340x_thermal.c index 42a5563465..da5d5f0be2 100644 --- a/drivers/acpi/dptf/int340x_thermal.c +++ b/drivers/acpi/dptf/int340x_thermal.c @@ -37,12 +37,6 @@ static const struct acpi_device_id int340x_thermal_device_ids[] = { {"INTC1050"}, {"INTC1060"}, {"INTC1061"}, - {"INTC10A0"}, - {"INTC10A1"}, - {"INTC10A2"}, - {"INTC10A3"}, - {"INTC10A4"}, - {"INTC10A5"}, {""}, }; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 46710380a4..9b859ff976 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -92,6 +92,8 @@ enum ec_command { enum { EC_FLAGS_QUERY_ENABLED, /* Query is enabled */ + EC_FLAGS_QUERY_PENDING, /* Query is pending */ + EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ EC_FLAGS_EVENT_HANDLER_INSTALLED, /* Event handler installed */ EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */ @@ -131,7 +133,7 @@ static unsigned int ec_storm_threshold __read_mostly = 8; module_param(ec_storm_threshold, uint, 0644); MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); -static bool ec_freeze_events __read_mostly; +static bool ec_freeze_events __read_mostly = false; module_param(ec_freeze_events, bool, 0644); MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume"); @@ -167,15 +169,16 @@ struct acpi_ec_query { struct acpi_ec *ec; }; -static int acpi_ec_submit_query(struct acpi_ec *ec); -static bool advance_transaction(struct acpi_ec *ec, bool interrupt); +static int acpi_ec_query(struct acpi_ec *ec, u8 *data); +static void advance_transaction(struct acpi_ec *ec, bool interrupt); static void acpi_ec_event_handler(struct work_struct *work); +static void acpi_ec_event_processor(struct work_struct *work); struct acpi_ec *first_ec; EXPORT_SYMBOL(first_ec); static struct acpi_ec *boot_ec; -static bool boot_ec_is_ecdt; +static bool boot_ec_is_ecdt = false; static struct workqueue_struct *ec_wq; static struct workqueue_struct *ec_query_wq; @@ -441,51 +444,25 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) return true; } -static bool acpi_ec_submit_event(struct acpi_ec *ec) +static void acpi_ec_submit_query(struct acpi_ec *ec) { acpi_ec_mask_events(ec); if (!acpi_ec_event_enabled(ec)) - return false; - - if (ec->event_state == EC_EVENT_READY) { + return; + if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { ec_dbg_evt("Command(%s) submitted/blocked", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - - ec->event_state = EC_EVENT_IN_PROGRESS; - /* - * If events_to_process is greqter than 0 at this point, the - * while () loop in acpi_ec_event_handler() is still running - * and incrementing events_to_process will cause it to invoke - * acpi_ec_submit_query() once more, so it is not necessary to - * queue up the event work to start the same loop again. - */ - if (ec->events_to_process++ > 0) - return true; - + ec->nr_pending_queries++; ec->events_in_progress++; - return queue_work(ec_wq, &ec->work); + queue_work(ec_wq, &ec->work); } - - /* - * The event handling work has not been completed yet, so it needs to be - * flushed. - */ - return true; } -static void acpi_ec_complete_event(struct acpi_ec *ec) +static void acpi_ec_complete_query(struct acpi_ec *ec) { - if (ec->event_state == EC_EVENT_IN_PROGRESS) - ec->event_state = EC_EVENT_COMPLETE; -} - -static void acpi_ec_close_event(struct acpi_ec *ec) -{ - if (ec->event_state != EC_EVENT_READY) + if (test_and_clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) ec_dbg_evt("Command(%s) unblocked", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - - ec->event_state = EC_EVENT_READY; acpi_ec_unmask_events(ec); } @@ -512,10 +489,12 @@ static inline void __acpi_ec_disable_event(struct acpi_ec *ec) */ static void acpi_ec_clear(struct acpi_ec *ec) { - int i; + int i, status; + u8 value = 0; for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { - if (acpi_ec_submit_query(ec)) + status = acpi_ec_query(ec, &value); + if (status || !value) break; } if (unlikely(i == ACPI_EC_CLEAR_MAX)) @@ -572,8 +551,8 @@ void acpi_ec_flush_work(void) static bool acpi_ec_guard_event(struct acpi_ec *ec) { + bool guarded = true; unsigned long flags; - bool guarded; spin_lock_irqsave(&ec->lock, flags); /* @@ -582,15 +561,19 @@ static bool acpi_ec_guard_event(struct acpi_ec *ec) * evaluating _Qxx, so we need to re-check SCI_EVT after waiting an * acceptable period. * - * The guarding period is applicable if the event state is not - * EC_EVENT_READY, but otherwise if the current transaction is of the - * ACPI_EC_COMMAND_QUERY type, the guarding should have elapsed already - * and it should not be applied to let the transaction transition into - * the ACPI_EC_COMMAND_POLL state immediately. + * The guarding period begins when EC_FLAGS_QUERY_PENDING is + * flagged, which means SCI_EVT check has just been performed. + * But if the current transaction is ACPI_EC_COMMAND_QUERY, the + * guarding should have already been performed (via + * EC_FLAGS_QUERY_GUARDING) and should not be applied so that the + * ACPI_EC_COMMAND_QUERY transaction can be transitioned into + * ACPI_EC_COMMAND_POLL state immediately. */ - guarded = ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT && - ec->event_state != EC_EVENT_READY && - (!ec->curr || ec->curr->command != ACPI_EC_COMMAND_QUERY); + if (ec_event_clearing == ACPI_EC_EVT_TIMING_STATUS || + ec_event_clearing == ACPI_EC_EVT_TIMING_QUERY || + !test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags) || + (ec->curr && ec->curr->command == ACPI_EC_COMMAND_QUERY)) + guarded = false; spin_unlock_irqrestore(&ec->lock, flags); return guarded; } @@ -622,26 +605,16 @@ static int ec_transaction_completed(struct acpi_ec *ec) static inline void ec_transaction_transition(struct acpi_ec *ec, unsigned long flag) { ec->curr->flags |= flag; - - if (ec->curr->command != ACPI_EC_COMMAND_QUERY) - return; - - switch (ec_event_clearing) { - case ACPI_EC_EVT_TIMING_STATUS: - if (flag == ACPI_EC_COMMAND_POLL) - acpi_ec_close_event(ec); - - return; - - case ACPI_EC_EVT_TIMING_QUERY: - if (flag == ACPI_EC_COMMAND_COMPLETE) - acpi_ec_close_event(ec); - - return; - - case ACPI_EC_EVT_TIMING_EVENT: - if (flag == ACPI_EC_COMMAND_COMPLETE) - acpi_ec_complete_event(ec); + if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { + if (ec_event_clearing == ACPI_EC_EVT_TIMING_STATUS && + flag == ACPI_EC_COMMAND_POLL) + acpi_ec_complete_query(ec); + if (ec_event_clearing == ACPI_EC_EVT_TIMING_QUERY && + flag == ACPI_EC_COMMAND_COMPLETE) + acpi_ec_complete_query(ec); + if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT && + flag == ACPI_EC_COMMAND_COMPLETE) + set_bit(EC_FLAGS_QUERY_GUARDING, &ec->flags); } } @@ -655,11 +628,10 @@ static void acpi_ec_spurious_interrupt(struct acpi_ec *ec, struct transaction *t acpi_ec_mask_events(ec); } -static bool advance_transaction(struct acpi_ec *ec, bool interrupt) +static void advance_transaction(struct acpi_ec *ec, bool interrupt) { struct transaction *t = ec->curr; bool wakeup = false; - bool ret = false; u8 status; ec_dbg_stm("%s (%d)", interrupt ? "IRQ" : "TASK", smp_processor_id()); @@ -687,9 +659,11 @@ static bool advance_transaction(struct acpi_ec *ec, bool interrupt) */ if (!t || !(t->flags & ACPI_EC_COMMAND_POLL)) { if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT && - ec->event_state == EC_EVENT_COMPLETE) - acpi_ec_close_event(ec); - + (!ec->nr_pending_queries || + test_bit(EC_FLAGS_QUERY_GUARDING, &ec->flags))) { + clear_bit(EC_FLAGS_QUERY_GUARDING, &ec->flags); + acpi_ec_complete_query(ec); + } if (!t) goto out; } @@ -724,12 +698,10 @@ static bool advance_transaction(struct acpi_ec *ec, bool interrupt) out: if (status & ACPI_EC_FLAG_SCI) - ret = acpi_ec_submit_event(ec); + acpi_ec_submit_query(ec); if (wakeup && interrupt) wake_up(&ec->wait); - - return ret; } static void start_transaction(struct acpi_ec *ec) @@ -1133,6 +1105,33 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) } EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); +static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) +{ + struct acpi_ec_query *q; + struct transaction *t; + + q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); + if (!q) + return NULL; + + INIT_WORK(&q->work, acpi_ec_event_processor); + t = &q->transaction; + t->command = ACPI_EC_COMMAND_QUERY; + t->rdata = pval; + t->rlen = 1; + q->ec = ec; + return q; +} + +static void acpi_ec_delete_query(struct acpi_ec_query *q) +{ + if (q) { + if (q->handler) + acpi_ec_put_query_handler(q->handler); + kfree(q); + } +} + static void acpi_ec_event_processor(struct work_struct *work) { struct acpi_ec_query *q = container_of(work, struct acpi_ec_query, work); @@ -1152,33 +1151,14 @@ static void acpi_ec_event_processor(struct work_struct *work) ec->queries_in_progress--; spin_unlock_irq(&ec->lock); - acpi_ec_put_query_handler(handler); - kfree(q); + acpi_ec_delete_query(q); } -static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) +static int acpi_ec_query(struct acpi_ec *ec, u8 *data) { - struct acpi_ec_query *q; - struct transaction *t; - - q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); - if (!q) - return NULL; - - INIT_WORK(&q->work, acpi_ec_event_processor); - t = &q->transaction; - t->command = ACPI_EC_COMMAND_QUERY; - t->rdata = pval; - t->rlen = 1; - q->ec = ec; - return q; -} - -static int acpi_ec_submit_query(struct acpi_ec *ec) -{ - struct acpi_ec_query *q; u8 value = 0; int result; + struct acpi_ec_query *q; q = acpi_ec_create_query(ec, &value); if (!q) @@ -1190,14 +1170,11 @@ static int acpi_ec_submit_query(struct acpi_ec *ec) * bit to be cleared (and thus clearing the interrupt source). */ result = acpi_ec_transaction(ec, &q->transaction); + if (!value) + result = -ENODATA; if (result) goto err_exit; - if (!value) { - result = -ENODATA; - goto err_exit; - } - q->handler = acpi_ec_get_query_handler_by_value(ec, value); if (!q->handler) { result = -ENODATA; @@ -1220,58 +1197,66 @@ static int acpi_ec_submit_query(struct acpi_ec *ec) spin_unlock_irq(&ec->lock); - return 0; - err_exit: - kfree(q); - + if (result) + acpi_ec_delete_query(q); + if (data) + *data = value; return result; } +static void acpi_ec_check_event(struct acpi_ec *ec) +{ + unsigned long flags; + + if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT) { + if (ec_guard(ec)) { + spin_lock_irqsave(&ec->lock, flags); + /* + * Take care of the SCI_EVT unless no one else is + * taking care of it. + */ + if (!ec->curr) + advance_transaction(ec, false); + spin_unlock_irqrestore(&ec->lock, flags); + } + } +} + static void acpi_ec_event_handler(struct work_struct *work) { + unsigned long flags; struct acpi_ec *ec = container_of(work, struct acpi_ec, work); ec_dbg_evt("Event started"); - spin_lock_irq(&ec->lock); - - while (ec->events_to_process) { - spin_unlock_irq(&ec->lock); - - acpi_ec_submit_query(ec); - - spin_lock_irq(&ec->lock); - ec->events_to_process--; + spin_lock_irqsave(&ec->lock, flags); + while (ec->nr_pending_queries) { + spin_unlock_irqrestore(&ec->lock, flags); + (void)acpi_ec_query(ec, NULL); + spin_lock_irqsave(&ec->lock, flags); + ec->nr_pending_queries--; + /* + * Before exit, make sure that this work item can be + * scheduled again. There might be QR_EC failures, leaving + * EC_FLAGS_QUERY_PENDING uncleared and preventing this work + * item from being scheduled again. + */ + if (!ec->nr_pending_queries) { + if (ec_event_clearing == ACPI_EC_EVT_TIMING_STATUS || + ec_event_clearing == ACPI_EC_EVT_TIMING_QUERY) + acpi_ec_complete_query(ec); + } } - - /* - * Before exit, make sure that the it will be possible to queue up the - * event handling work again regardless of whether or not the query - * queued up above is processed successfully. - */ - if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT) - acpi_ec_complete_event(ec); - else - acpi_ec_close_event(ec); - - spin_unlock_irq(&ec->lock); + spin_unlock_irqrestore(&ec->lock, flags); ec_dbg_evt("Event stopped"); - if (ec_event_clearing == ACPI_EC_EVT_TIMING_EVENT && ec_guard(ec)) { - spin_lock_irq(&ec->lock); + acpi_ec_check_event(ec); - /* Take care of SCI_EVT unless someone else is doing that. */ - if (!ec->curr) - advance_transaction(ec, false); - - spin_unlock_irq(&ec->lock); - } - - spin_lock_irq(&ec->lock); + spin_lock_irqsave(&ec->lock, flags); ec->events_in_progress--; - spin_unlock_irq(&ec->lock); + spin_unlock_irqrestore(&ec->lock, flags); } static void acpi_ec_handle_interrupt(struct acpi_ec *ec) @@ -2053,7 +2038,8 @@ void acpi_ec_set_gpe_wake_mask(u8 action) bool acpi_ec_dispatch_gpe(void) { - bool work_in_progress = false; + bool work_in_progress; + u32 ret; if (!first_ec) return acpi_any_gpe_status_set(U32_MAX); @@ -2065,31 +2051,13 @@ bool acpi_ec_dispatch_gpe(void) if (acpi_any_gpe_status_set(first_ec->gpe)) return true; - /* - * Cancel the SCI wakeup and process all pending events in case there - * are any wakeup ones in there. - * - * Note that if any non-EC GPEs are active at this point, the SCI will - * retrigger after the rearming in acpi_s2idle_wake(), so no events - * should be missed by canceling the wakeup here. - */ - pm_system_cancel_wakeup(); - /* * Dispatch the EC GPE in-band, but do not report wakeup in any case * to allow the caller to process events properly after that. */ - spin_lock_irq(&first_ec->lock); - - if (acpi_ec_gpe_status_set(first_ec)) - work_in_progress = advance_transaction(first_ec, false); - - spin_unlock_irq(&first_ec->lock); - - if (!work_in_progress) - return false; - - pm_pr_dbg("ACPI EC GPE dispatched\n"); + ret = acpi_dispatch_gpe(NULL, first_ec->gpe); + if (ret == ACPI_INTERRUPT_HANDLED) + pm_pr_dbg("ACPI EC GPE dispatched\n"); /* Drain EC work. */ do { @@ -2213,13 +2181,6 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"), }, }, - { - .ident = "HP ZHAN 66 Pro", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), - }, - }, { }, }; diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index c074a0fae0..fd39c14493 100644 --- a/drivers/acpi/ec_sys.c +++ b/drivers/acpi/ec_sys.c @@ -19,7 +19,7 @@ MODULE_DESCRIPTION("ACPI EC sysfs access driver"); MODULE_LICENSE("GPL"); static bool write_support; -module_param_hw(write_support, bool, other, 0644); +module_param(write_support, bool, 0644); MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " "be needed."); diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h index dd9bb8ca22..dc9a6efa51 100644 --- a/drivers/acpi/fan.h +++ b/drivers/acpi/fan.h @@ -10,5 +10,4 @@ {"INT3404", }, /* Fan */ \ {"INTC1044", }, /* Fan for Tiger Lake generation */ \ {"INTC1048", }, /* Fan for Alder Lake generation */ \ - {"INTC10A2", }, /* Fan for Raptor Lake generation */ \ {"PNP0C0B", } /* Generic ACPI fan */ diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index ef104809f2..7a33a6d985 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include "internal.h" @@ -113,10 +111,13 @@ struct acpi_device *acpi_find_child_device(struct acpi_device *parent, return NULL; list_for_each_entry(adev, &parent->children, node) { - acpi_bus_address addr = acpi_device_adr(adev); + unsigned long long addr; + acpi_status status; int score; - if (!adev->pnp.type.bus_address || addr != address) + status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR, + NULL, &addr); + if (ACPI_FAILURE(status) || addr != address) continue; if (!ret) { @@ -286,13 +287,12 @@ EXPORT_SYMBOL_GPL(acpi_unbind_one); void acpi_device_notify(struct device *dev) { + struct acpi_bus_type *type = acpi_get_bus_type(dev); struct acpi_device *adev; int ret; ret = acpi_bind_one(dev, NULL); if (ret) { - struct acpi_bus_type *type = acpi_get_bus_type(dev); - if (!type) goto err; @@ -304,26 +304,17 @@ void acpi_device_notify(struct device *dev) ret = acpi_bind_one(dev, adev); if (ret) goto err; - - if (type->setup) { - type->setup(dev); - goto done; - } - } else { - adev = ACPI_COMPANION(dev); - - if (dev_is_pci(dev)) { - pci_acpi_setup(dev, adev); - goto done; - } else if (dev_is_platform(dev)) { - acpi_configure_pmsi_domain(dev); - } } + adev = ACPI_COMPANION(dev); - if (adev->handler && adev->handler->bind) + if (dev_is_platform(dev)) + acpi_configure_pmsi_domain(dev); + + if (type && type->setup) + type->setup(dev); + else if (adev->handler && adev->handler->bind) adev->handler->bind(dev); -done: acpi_handle_debug(ACPI_HANDLE(dev), "Bound to device %s\n", dev_name(dev)); @@ -336,12 +327,14 @@ void acpi_device_notify(struct device *dev) void acpi_device_notify_remove(struct device *dev) { struct acpi_device *adev = ACPI_COMPANION(dev); + struct acpi_bus_type *type; if (!adev) return; - if (dev_is_pci(dev)) - pci_acpi_cleanup(dev, adev); + type = acpi_get_bus_type(dev); + if (type && type->cleanup) + type->cleanup(dev); else if (adev->handler && adev->handler->unbind) adev->handler->unbind(dev); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 457e11d851..54b2be94d2 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -14,7 +14,7 @@ int early_acpi_osi_init(void); int acpi_osi_init(void); acpi_status acpi_os_initialize1(void); -void acpi_scan_init(void); +int acpi_scan_init(void); #ifdef CONFIG_PCI void acpi_pci_root_init(void); void acpi_pci_link_init(void); @@ -166,13 +166,6 @@ static inline void acpi_early_processor_osc(void) {} /* -------------------------------------------------------------------------- Embedded Controller -------------------------------------------------------------------------- */ - -enum acpi_ec_event_state { - EC_EVENT_READY = 0, /* Event work can be submitted */ - EC_EVENT_IN_PROGRESS, /* Event work is pending or being processed */ - EC_EVENT_COMPLETE, /* Event work processing has completed */ -}; - struct acpi_ec { acpi_handle handle; int gpe; @@ -189,8 +182,7 @@ struct acpi_ec { spinlock_t lock; struct work_struct work; unsigned long timestamp; - enum acpi_ec_event_state event_state; - unsigned int events_to_process; + unsigned long nr_pending_queries; unsigned int events_in_progress; unsigned int queries_in_progress; bool busy_polling; diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index e5d7f2bda1..7dd80acf92 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -678,12 +678,10 @@ static const char *spa_type_name(u16 type) int nfit_spa_type(struct acpi_nfit_system_address *spa) { - guid_t guid; int i; - import_guid(&guid, spa->range_guid); for (i = 0; i < NFIT_UUID_MAX; i++) - if (guid_equal(to_nfit_uuid(i), &guid)) + if (guid_equal(to_nfit_uuid(i), (guid_t *)&spa->range_guid)) return i; return -1; } diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c index 3b818ab186..b8795fc490 100644 --- a/drivers/acpi/numa/srat.c +++ b/drivers/acpi/numa/srat.c @@ -254,8 +254,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) } if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) goto out_err; - hotpluggable = IS_ENABLED(CONFIG_MEMORY_HOTPLUG) && - (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE); + hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE; + if (hotpluggable && !IS_ENABLED(CONFIG_MEMORY_HOTPLUG)) + goto out_err; start = ma->base_address; end = start + ma->length; @@ -297,47 +298,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) out_err: return -EINVAL; } - -static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, - void *arg, const unsigned long table_end) -{ - struct acpi_cedt_cfmws *cfmws; - int *fake_pxm = arg; - u64 start, end; - int node; - - cfmws = (struct acpi_cedt_cfmws *)header; - start = cfmws->base_hpa; - end = cfmws->base_hpa + cfmws->window_size; - - /* Skip if the SRAT already described the NUMA details for this HPA */ - node = phys_to_target_node(start); - if (node != NUMA_NO_NODE) - return 0; - - node = acpi_map_pxm_to_node(*fake_pxm); - - if (node == NUMA_NO_NODE) { - pr_err("ACPI NUMA: Too many proximity domains while processing CFMWS.\n"); - return -EINVAL; - } - - if (numa_add_memblk(node, start, end) < 0) { - /* CXL driver must handle the NUMA_NO_NODE case */ - pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n", - node, start, end); - } - - /* Set the next available fake_pxm value */ - (*fake_pxm)++; - return 0; -} -#else -static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, - void *arg, const unsigned long table_end) -{ - return 0; -} #endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */ static int __init acpi_parse_slit(struct acpi_table_header *table) @@ -482,7 +442,7 @@ acpi_table_parse_srat(enum acpi_srat_type id, int __init acpi_numa_init(void) { - int i, fake_pxm, cnt = 0; + int cnt = 0; if (acpi_disabled) return -EINVAL; @@ -518,22 +478,6 @@ int __init acpi_numa_init(void) /* SLIT: System Locality Information Table */ acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); - /* - * CXL Fixed Memory Window Structures (CFMWS) must be parsed - * after the SRAT. Create NUMA Nodes for CXL memory ranges that - * are defined in the CFMWS and not already defined in the SRAT. - * Initialize a fake_pxm as the first available PXM to emulate. - */ - - /* fake_pxm is the next unused PXM value after SRAT parsing */ - for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) { - if (node_to_pxm_map[i] > fake_pxm) - fake_pxm = node_to_pxm_map[i]; - } - fake_pxm++; - acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws, - &fake_pxm); - if (cnt < 0) return cnt; else if (!parsed_numa_memblks) diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index d54fb8e546..cb7b900d94 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -606,10 +606,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, int *polarity, char **name) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + int result; + struct acpi_device *device; struct acpi_pci_link *link; - if (!device) { + result = acpi_bus_get_device(handle, &device); + if (result) { acpi_handle_err(handle, "Invalid link device\n"); return -1; } @@ -656,10 +658,12 @@ int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, */ int acpi_pci_link_free_irq(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; struct acpi_pci_link *link; + acpi_status result; - if (!device) { + result = acpi_bus_get_device(handle, &device); + if (result) { acpi_handle_err(handle, "Invalid link device\n"); return -1; } diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index b76db99cce..d7deedf354 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -67,10 +67,11 @@ static struct acpi_scan_handler pci_root_handler = { */ int acpi_is_root_bridge(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); int ret; + struct acpi_device *device; - if (!device) + ret = acpi_bus_get_device(handle, &device); + if (ret) return 0; ret = acpi_match_device_ids(device, root_device_ids); @@ -198,26 +199,40 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, acpi_status status; u32 result, capbuf[3]; + support &= OSC_PCI_SUPPORT_MASKS; support |= root->osc_support_set; capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; capbuf[OSC_SUPPORT_DWORD] = support; - capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; + if (control) { + *control &= OSC_PCI_CONTROL_MASKS; + capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; + } else { + /* Run _OSC query only with existing controls. */ + capbuf[OSC_CONTROL_DWORD] = root->osc_control_set; + } status = acpi_pci_run_osc(root->device->handle, capbuf, &result); if (ACPI_SUCCESS(status)) { root->osc_support_set = support; - *control = result; + if (control) + *control = result; } return status; } +static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) +{ + return acpi_pci_query_osc(root, flags, NULL); +} + struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); struct acpi_pci_root *root; + struct acpi_device *device; - if (!device || acpi_match_device_ids(device, root_device_ids)) + if (acpi_bus_get_device(handle, &device) || + acpi_match_device_ids(device, root_device_ids)) return NULL; root = acpi_driver_data(device); @@ -322,7 +337,7 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); * acpi_pci_osc_control_set - Request control of PCI root _OSC features. * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). * @mask: Mask of _OSC bits to request control of, place to store control mask. - * @support: _OSC supported capability. + * @req: Mask of _OSC bits the control of is essential to the caller. * * Run _OSC query for @mask and if that is successful, compare the returned * mask of control bits with @req. If all of the @req bits are set in the @@ -333,9 +348,8 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); * _OSC bits the BIOS has granted control of, but its contents are meaningless * on failure. **/ -static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 support) +static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) { - u32 req = OSC_PCI_EXPRESS_CAPABILITY_CONTROL; struct acpi_pci_root *root; acpi_status status; u32 ctrl, capbuf[3]; @@ -343,16 +357,22 @@ static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 s if (!mask) return AE_BAD_PARAMETER; + ctrl = *mask & OSC_PCI_CONTROL_MASKS; + if ((ctrl & req) != req) + return AE_TYPE; + root = acpi_pci_find_root(handle); if (!root) return AE_NOT_EXIST; - ctrl = *mask; - *mask |= root->osc_control_set; + *mask = ctrl | root->osc_control_set; + /* No need to evaluate _OSC if the control was already granted. */ + if ((root->osc_control_set & ctrl) == ctrl) + return AE_OK; /* Need to check the available controls bits before requesting them. */ - do { - status = acpi_pci_query_osc(root, support, mask); + while (*mask) { + status = acpi_pci_query_osc(root, root->osc_support_set, mask); if (ACPI_FAILURE(status)) return status; if (ctrl == *mask) @@ -360,11 +380,7 @@ static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 s decode_osc_control(root, "platform does not support", ctrl & ~(*mask)); ctrl = *mask; - } while (*mask); - - /* No need to request _OSC if the control was already granted. */ - if ((root->osc_control_set & ctrl) == ctrl) - return AE_OK; + } if ((ctrl & req) != req) { decode_osc_control(root, "not requesting control; platform does not support", @@ -383,9 +399,25 @@ static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 s return AE_OK; } -static u32 calculate_support(void) +static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, + bool is_pcie) { - u32 support; + u32 support, control, requested; + acpi_status status; + struct acpi_device *device = root->device; + acpi_handle handle = device->handle; + + /* + * Apple always return failure on _OSC calls when _OSI("Darwin") has + * been called successfully. We know the feature set supported by the + * platform, so avoid calling _OSC at all + */ + if (x86_apple_machine) { + root->osc_control_set = ~OSC_PCI_EXPRESS_PME_CONTROL; + decode_osc_control(root, "OS assumes control of", + root->osc_control_set); + return; + } /* * All supported architectures that use ACPI have support for @@ -402,12 +434,30 @@ static u32 calculate_support(void) if (IS_ENABLED(CONFIG_PCIE_EDR)) support |= OSC_PCI_EDR_SUPPORT; - return support; -} + decode_osc_support(root, "OS supports", support); + status = acpi_pci_osc_support(root, support); + if (ACPI_FAILURE(status)) { + *no_aspm = 1; -static u32 calculate_control(void) -{ - u32 control; + /* _OSC is optional for PCI host bridges */ + if ((status == AE_NOT_FOUND) && !is_pcie) + return; + + dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", + acpi_format_exception(status)); + return; + } + + if (pcie_ports_disabled) { + dev_info(&device->dev, "PCIe port services disabled; not requesting _OSC control\n"); + return; + } + + if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { + decode_osc_support(root, "not requesting OS control; OS requires", + ACPI_PCIE_REQ_SUPPORT); + return; + } control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | OSC_PCI_EXPRESS_PME_CONTROL; @@ -433,59 +483,11 @@ static u32 calculate_control(void) if (IS_ENABLED(CONFIG_PCIE_DPC) && IS_ENABLED(CONFIG_PCIE_EDR)) control |= OSC_PCI_EXPRESS_DPC_CONTROL; - return control; -} - -static bool os_control_query_checks(struct acpi_pci_root *root, u32 support) -{ - struct acpi_device *device = root->device; - - if (pcie_ports_disabled) { - dev_info(&device->dev, "PCIe port services disabled; not requesting _OSC control\n"); - return false; - } - - if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { - decode_osc_support(root, "not requesting OS control; OS requires", - ACPI_PCIE_REQ_SUPPORT); - return false; - } - - return true; -} - -static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, - bool is_pcie) -{ - u32 support, control = 0, requested = 0; - acpi_status status; - struct acpi_device *device = root->device; - acpi_handle handle = device->handle; - - /* - * Apple always return failure on _OSC calls when _OSI("Darwin") has - * been called successfully. We know the feature set supported by the - * platform, so avoid calling _OSC at all - */ - if (x86_apple_machine) { - root->osc_control_set = ~OSC_PCI_EXPRESS_PME_CONTROL; - decode_osc_control(root, "OS assumes control of", - root->osc_control_set); - return; - } - - support = calculate_support(); - - decode_osc_support(root, "OS supports", support); - - if (os_control_query_checks(root, support)) - requested = control = calculate_control(); - - status = acpi_pci_osc_control_set(handle, &control, support); + requested = control; + status = acpi_pci_osc_control_set(handle, &control, + OSC_PCI_EXPRESS_CAPABILITY_CONTROL); if (ACPI_SUCCESS(status)) { - if (control) - decode_osc_control(root, "OS now controls", control); - + decode_osc_control(root, "OS now controls", control); if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { /* * We have ASPM control, but the FADT indicates that @@ -496,6 +498,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, *no_aspm = 1; } } else { + decode_osc_control(root, "OS requested", requested); + decode_osc_control(root, "platform willing to grant", control); + dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", + acpi_format_exception(status)); + /* * We want to disable ASPM here, but aspm_disabled * needs to remain in its state from boot so that we @@ -504,18 +511,6 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, * root scan. */ *no_aspm = 1; - - /* _OSC is optional for PCI host bridges */ - if ((status == AE_NOT_FOUND) && !is_pcie) - return; - - if (control) { - decode_osc_control(root, "OS requested", requested); - decode_osc_control(root, "platform willing to grant", control); - } - - dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", - acpi_format_exception(status)); } } diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c index f20dbda1a8..9cde299eba 100644 --- a/drivers/acpi/pmic/intel_pmic.c +++ b/drivers/acpi/pmic/intel_pmic.c @@ -25,7 +25,7 @@ struct intel_pmic_opregion { struct mutex lock; struct acpi_lpat_conversion_table *lpat_table; struct regmap *regmap; - const struct intel_pmic_opregion_data *data; + struct intel_pmic_opregion_data *data; struct intel_pmic_regs_handler_ctx ctx; }; @@ -53,7 +53,7 @@ static acpi_status intel_pmic_power_handler(u32 function, { struct intel_pmic_opregion *opregion = region_context; struct regmap *regmap = opregion->regmap; - const struct intel_pmic_opregion_data *d = opregion->data; + struct intel_pmic_opregion_data *d = opregion->data; int reg, bit, result; if (bits != 32 || !value64) @@ -95,7 +95,7 @@ static int pmic_read_temp(struct intel_pmic_opregion *opregion, return 0; } - temp = opregion->data->lpat_raw_to_temp(opregion->lpat_table, raw_temp); + temp = acpi_lpat_raw_to_temp(opregion->lpat_table, raw_temp); if (temp < 0) return temp; @@ -135,7 +135,7 @@ static int pmic_thermal_aux(struct intel_pmic_opregion *opregion, int reg, static int pmic_thermal_pen(struct intel_pmic_opregion *opregion, int reg, int bit, u32 function, u64 *value) { - const struct intel_pmic_opregion_data *d = opregion->data; + struct intel_pmic_opregion_data *d = opregion->data; struct regmap *regmap = opregion->regmap; if (!d->get_policy || !d->update_policy) @@ -171,7 +171,7 @@ static acpi_status intel_pmic_thermal_handler(u32 function, void *handler_context, void *region_context) { struct intel_pmic_opregion *opregion = region_context; - const struct intel_pmic_opregion_data *d = opregion->data; + struct intel_pmic_opregion_data *d = opregion->data; int reg, bit, result; if (bits != 32 || !value64) @@ -255,7 +255,7 @@ static acpi_status intel_pmic_regs_handler(u32 function, int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, struct regmap *regmap, - const struct intel_pmic_opregion_data *d) + struct intel_pmic_opregion_data *d) { acpi_status status = AE_OK; struct intel_pmic_opregion *opregion; @@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(intel_pmic_install_opregion_handler); int intel_soc_pmic_exec_mipi_pmic_seq_element(u16 i2c_address, u32 reg_address, u32 value, u32 mask) { - const struct intel_pmic_opregion_data *d; + struct intel_pmic_opregion_data *d; int ret; if (!intel_pmic_opregion) { diff --git a/drivers/acpi/pmic/intel_pmic.h b/drivers/acpi/pmic/intel_pmic.h index d956b03a6c..89379476a1 100644 --- a/drivers/acpi/pmic/intel_pmic.h +++ b/drivers/acpi/pmic/intel_pmic.h @@ -2,8 +2,6 @@ #ifndef __INTEL_PMIC_H #define __INTEL_PMIC_H -#include - struct pmic_table { int address; /* operation region address */ int reg; /* corresponding thermal register */ @@ -19,8 +17,6 @@ struct intel_pmic_opregion_data { int (*update_policy)(struct regmap *r, int reg, int bit, int enable); int (*exec_mipi_pmic_seq_element)(struct regmap *r, u16 i2c_address, u32 reg_address, u32 value, u32 mask); - int (*lpat_raw_to_temp)(struct acpi_lpat_conversion_table *lpat_table, - int raw); struct pmic_table *power_table; int power_table_count; struct pmic_table *thermal_table; @@ -29,8 +25,6 @@ struct intel_pmic_opregion_data { int pmic_i2c_address; }; -int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, - struct regmap *regmap, - const struct intel_pmic_opregion_data *d); +int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle, struct regmap *regmap, struct intel_pmic_opregion_data *d); #endif diff --git a/drivers/acpi/pmic/intel_pmic_bxtwc.c b/drivers/acpi/pmic/intel_pmic_bxtwc.c index e247615189..bd7621edd6 100644 --- a/drivers/acpi/pmic/intel_pmic_bxtwc.c +++ b/drivers/acpi/pmic/intel_pmic_bxtwc.c @@ -369,14 +369,13 @@ intel_bxtwc_pmic_update_policy(struct regmap *regmap, return regmap_update_bits(regmap, reg, mask, val); } -static const struct intel_pmic_opregion_data intel_bxtwc_pmic_opregion_data = { +static struct intel_pmic_opregion_data intel_bxtwc_pmic_opregion_data = { .get_power = intel_bxtwc_pmic_get_power, .update_power = intel_bxtwc_pmic_update_power, .get_raw_temp = intel_bxtwc_pmic_get_raw_temp, .update_aux = intel_bxtwc_pmic_update_aux, .get_policy = intel_bxtwc_pmic_get_policy, .update_policy = intel_bxtwc_pmic_update_policy, - .lpat_raw_to_temp = acpi_lpat_raw_to_temp, .power_table = power_table, .power_table_count = ARRAY_SIZE(power_table), .thermal_table = thermal_table, diff --git a/drivers/acpi/pmic/intel_pmic_bytcrc.c b/drivers/acpi/pmic/intel_pmic_bytcrc.c index 9ea79f2109..2a692cc4b7 100644 --- a/drivers/acpi/pmic/intel_pmic_bytcrc.c +++ b/drivers/acpi/pmic/intel_pmic_bytcrc.c @@ -271,14 +271,13 @@ static int intel_crc_pmic_update_policy(struct regmap *regmap, return 0; } -static const struct intel_pmic_opregion_data intel_crc_pmic_opregion_data = { +static struct intel_pmic_opregion_data intel_crc_pmic_opregion_data = { .get_power = intel_crc_pmic_get_power, .update_power = intel_crc_pmic_update_power, .get_raw_temp = intel_crc_pmic_get_raw_temp, .update_aux = intel_crc_pmic_update_aux, .get_policy = intel_crc_pmic_get_policy, .update_policy = intel_crc_pmic_update_policy, - .lpat_raw_to_temp = acpi_lpat_raw_to_temp, .power_table = power_table, .power_table_count= ARRAY_SIZE(power_table), .thermal_table = thermal_table, diff --git a/drivers/acpi/pmic/intel_pmic_chtcrc.c b/drivers/acpi/pmic/intel_pmic_chtcrc.c index f9301c6f09..2900dc3074 100644 --- a/drivers/acpi/pmic/intel_pmic_chtcrc.c +++ b/drivers/acpi/pmic/intel_pmic_chtcrc.c @@ -23,8 +23,7 @@ * intel_soc_pmic_exec_mipi_pmic_seq_element work on devices with a * CHT Crystal Cove PMIC. */ -static const struct intel_pmic_opregion_data intel_chtcrc_pmic_opregion_data = { - .lpat_raw_to_temp = acpi_lpat_raw_to_temp, +static struct intel_pmic_opregion_data intel_chtcrc_pmic_opregion_data = { .pmic_i2c_address = 0x6e, }; diff --git a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c index 418eec5230..fef7831d0d 100644 --- a/drivers/acpi/pmic/intel_pmic_chtdc_ti.c +++ b/drivers/acpi/pmic/intel_pmic_chtdc_ti.c @@ -94,11 +94,10 @@ static int chtdc_ti_pmic_get_raw_temp(struct regmap *regmap, int reg) return ((buf[0] & 0x03) << 8) | buf[1]; } -static const struct intel_pmic_opregion_data chtdc_ti_pmic_opregion_data = { +static struct intel_pmic_opregion_data chtdc_ti_pmic_opregion_data = { .get_power = chtdc_ti_pmic_get_power, .update_power = chtdc_ti_pmic_update_power, .get_raw_temp = chtdc_ti_pmic_get_raw_temp, - .lpat_raw_to_temp = acpi_lpat_raw_to_temp, .power_table = chtdc_ti_power_table, .power_table_count = ARRAY_SIZE(chtdc_ti_power_table), .thermal_table = chtdc_ti_thermal_table, diff --git a/drivers/acpi/pmic/intel_pmic_chtwc.c b/drivers/acpi/pmic/intel_pmic_chtwc.c index f2c42f4c79..7ffd5624b8 100644 --- a/drivers/acpi/pmic/intel_pmic_chtwc.c +++ b/drivers/acpi/pmic/intel_pmic_chtwc.c @@ -253,11 +253,10 @@ static int intel_cht_wc_exec_mipi_pmic_seq_element(struct regmap *regmap, * The thermal table and ops are empty, we do not support the Thermal opregion * (DPTF) due to lacking documentation. */ -static const struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = { +static struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = { .get_power = intel_cht_wc_pmic_get_power, .update_power = intel_cht_wc_pmic_update_power, .exec_mipi_pmic_seq_element = intel_cht_wc_exec_mipi_pmic_seq_element, - .lpat_raw_to_temp = acpi_lpat_raw_to_temp, .power_table = power_table, .power_table_count = ARRAY_SIZE(power_table), }; diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c index 61bbe4c24d..cbe08e600f 100644 --- a/drivers/acpi/pmic/intel_pmic_xpower.c +++ b/drivers/acpi/pmic/intel_pmic_xpower.c @@ -293,33 +293,11 @@ static int intel_xpower_exec_mipi_pmic_seq_element(struct regmap *regmap, return ret; } -static int intel_xpower_lpat_raw_to_temp(struct acpi_lpat_conversion_table *lpat_table, - int raw) -{ - struct acpi_lpat first = lpat_table->lpat[0]; - struct acpi_lpat last = lpat_table->lpat[lpat_table->lpat_count - 1]; - - /* - * Some LPAT tables in the ACPI Device for the AXP288 PMIC for some - * reason only describe a small temperature range, e.g. 27° - 37° - * Celcius. Resulting in errors when the tablet is idle in a cool room. - * - * To avoid these errors clamp the raw value to be inside the LPAT. - */ - if (first.raw < last.raw) - raw = clamp(raw, first.raw, last.raw); - else - raw = clamp(raw, last.raw, first.raw); - - return acpi_lpat_raw_to_temp(lpat_table, raw); -} - -static const struct intel_pmic_opregion_data intel_xpower_pmic_opregion_data = { +static struct intel_pmic_opregion_data intel_xpower_pmic_opregion_data = { .get_power = intel_xpower_pmic_get_power, .update_power = intel_xpower_pmic_update_power, .get_raw_temp = intel_xpower_pmic_get_raw_temp, .exec_mipi_pmic_seq_element = intel_xpower_exec_mipi_pmic_seq_element, - .lpat_raw_to_temp = intel_xpower_lpat_raw_to_temp, .power_table = power_table, .power_table_count = ARRAY_SIZE(power_table), .thermal_table = thermal_table, diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 8c4a73a135..c95eedd58f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -81,9 +81,9 @@ struct acpi_power_resource *to_power_resource(struct acpi_device *device) static struct acpi_power_resource *acpi_power_get_context(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device; - if (!device) + if (acpi_bus_get_device(handle, &device)) return NULL; return to_power_resource(device); @@ -716,9 +716,6 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) mutex_lock(&acpi_device_lock); - dev_dbg(&dev->dev, "Enabling wakeup power (count %d)\n", - dev->wakeup.prepare_count); - if (dev->wakeup.prepare_count++) goto out; @@ -734,13 +731,8 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) * put into arbitrary power state afterward. */ err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); - if (err) { - acpi_power_off_list(&dev->wakeup.resources); + if (err) dev->wakeup.prepare_count = 0; - goto out; - } - - dev_dbg(&dev->dev, "Wakeup power enabled\n"); out: mutex_unlock(&acpi_device_lock); @@ -763,9 +755,6 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) mutex_lock(&acpi_device_lock); - dev_dbg(&dev->dev, "Disabling wakeup power (count %d)\n", - dev->wakeup.prepare_count); - /* Do nothing if wakeup power has not been enabled for this device. */ if (dev->wakeup.prepare_count <= 0) goto out; @@ -791,11 +780,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) if (err) { dev_err(&dev->dev, "Cannot turn off wakeup power resources\n"); dev->wakeup.flags.valid = 0; - goto out; } - dev_dbg(&dev->dev, "Wakeup power disabled\n"); - out: mutex_unlock(&acpi_device_lock); return err; @@ -928,14 +914,14 @@ static void acpi_power_add_resource_to_list(struct acpi_power_resource *resource struct acpi_device *acpi_add_power_resource(acpi_handle handle) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); struct acpi_power_resource *resource; + struct acpi_device *device = NULL; union acpi_object acpi_object; struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object }; acpi_status status; - u8 state_dummy; int result; + acpi_bus_get_device(handle, &device); if (device) return device; @@ -961,10 +947,6 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle) resource->order = acpi_object.power_resource.resource_order; resource->state = ACPI_POWER_RESOURCE_STATE_UNKNOWN; - /* Get the initial state or just flip it on if that fails. */ - if (acpi_power_get_state(resource, &state_dummy)) - __acpi_power_on(resource); - pr_info("%s [%s]\n", acpi_device_name(device), acpi_device_bid(device)); device->flags.match_driver = true; diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 701f61c013..fe69dc518f 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -746,73 +746,6 @@ int find_acpi_cpu_topology_package(unsigned int cpu) ACPI_PPTT_PHYSICAL_PACKAGE); } -/** - * find_acpi_cpu_topology_cluster() - Determine a unique CPU cluster value - * @cpu: Kernel logical CPU number - * - * Determine a topology unique cluster ID for the given CPU/thread. - * This ID can then be used to group peers, which will have matching ids. - * - * The cluster, if present is the level of topology above CPUs. In a - * multi-thread CPU, it will be the level above the CPU, not the thread. - * It may not exist in single CPU systems. In simple multi-CPU systems, - * it may be equal to the package topology level. - * - * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found - * or there is no toplogy level above the CPU.. - * Otherwise returns a value which represents the package for this CPU. - */ - -int find_acpi_cpu_topology_cluster(unsigned int cpu) -{ - struct acpi_table_header *table; - acpi_status status; - struct acpi_pptt_processor *cpu_node, *cluster_node; - u32 acpi_cpu_id; - int retval; - int is_thread; - - status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); - if (ACPI_FAILURE(status)) { - acpi_pptt_warn_missing(); - return -ENOENT; - } - - acpi_cpu_id = get_acpi_id_for_cpu(cpu); - cpu_node = acpi_find_processor_node(table, acpi_cpu_id); - if (cpu_node == NULL || !cpu_node->parent) { - retval = -ENOENT; - goto put_table; - } - - is_thread = cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD; - cluster_node = fetch_pptt_node(table, cpu_node->parent); - if (cluster_node == NULL) { - retval = -ENOENT; - goto put_table; - } - if (is_thread) { - if (!cluster_node->parent) { - retval = -ENOENT; - goto put_table; - } - cluster_node = fetch_pptt_node(table, cluster_node->parent); - if (cluster_node == NULL) { - retval = -ENOENT; - goto put_table; - } - } - if (cluster_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID) - retval = cluster_node->acpi_processor_id; - else - retval = ACPI_PTR_DIFF(cluster_node, table); - -put_table: - acpi_put_table(table); - - return retval; -} - /** * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag * @cpu: Kernel logical CPU number diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 4d3a219c67..89c22bc550 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -49,6 +49,7 @@ struct prm_context_buffer { }; #pragma pack() + static LIST_HEAD(prm_module_list); struct prm_handler_info { @@ -72,6 +73,7 @@ struct prm_module_info { struct prm_handler_info handlers[]; }; + static u64 efi_pa_va_lookup(u64 pa) { efi_memory_desc_t *md; @@ -86,6 +88,7 @@ static u64 efi_pa_va_lookup(u64 pa) return 0; } + #define get_first_handler(a) ((struct acpi_prmt_handler_info *) ((char *) (a) + a->handler_info_offset)) #define get_next_handler(a) ((struct acpi_prmt_handler_info *) (sizeof(struct acpi_prmt_handler_info) + (char *) a)) @@ -96,7 +99,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) struct acpi_prmt_handler_info *handler_info; struct prm_handler_info *th; struct prm_module_info *tm; - u64 *mmio_count; + u64 mmio_count = 0; u64 cur_handler = 0; u32 module_info_size = 0; u64 mmio_range_size = 0; @@ -105,8 +108,6 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) module_info = (struct acpi_prmt_module_info *) header; module_info_size = struct_size(tm, handlers, module_info->handler_info_count); tm = kmalloc(module_info_size, GFP_KERNEL); - if (!tm) - goto parse_prmt_out1; guid_copy(&tm->guid, (guid_t *) module_info->module_guid); tm->major_rev = module_info->major_rev; @@ -119,24 +120,14 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) * Each module is associated with a list of addr * ranges that it can use during the service */ - mmio_count = (u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB); - if (!mmio_count) - goto parse_prmt_out2; - - mmio_range_size = struct_size(tm->mmio_info, addr_ranges, *mmio_count); + mmio_count = *(u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB); + mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count); tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL); - if (!tm->mmio_info) - goto parse_prmt_out3; - temp_mmio = memremap(module_info->mmio_list_pointer, mmio_range_size, MEMREMAP_WB); - if (!temp_mmio) - goto parse_prmt_out4; memmove(tm->mmio_info, temp_mmio, mmio_range_size); } else { - tm->mmio_info = kmalloc(sizeof(*tm->mmio_info), GFP_KERNEL); - if (!tm->mmio_info) - goto parse_prmt_out2; - + mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count); + tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL); tm->mmio_info->mmio_count = 0; } @@ -154,15 +145,6 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info))); return 0; - -parse_prmt_out4: - kfree(tm->mmio_info); -parse_prmt_out3: - memunmap(mmio_count); -parse_prmt_out2: - kfree(tm); -parse_prmt_out1: - return -ENOMEM; } #define GET_MODULE 0 @@ -189,6 +171,7 @@ static void *find_guid_info(const guid_t *guid, u8 mode) return NULL; } + static struct prm_module_info *find_prm_module(const guid_t *guid) { return (struct prm_module_info *)find_guid_info(guid, GET_MODULE); diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 368a9edefd..77541f939b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -98,13 +98,8 @@ static int acpi_soft_cpu_online(unsigned int cpu) struct acpi_processor *pr = per_cpu(processors, cpu); struct acpi_device *device; - if (!pr) + if (!pr || acpi_bus_get_device(pr->handle, &device)) return 0; - - device = acpi_fetch_acpi_dev(pr->handle); - if (!device) - return 0; - /* * CPU got physically hotplugged and onlined for the first time: * Initialize missing things. @@ -130,8 +125,9 @@ static int acpi_soft_cpu_online(unsigned int cpu) static int acpi_soft_cpu_dead(unsigned int cpu) { struct acpi_processor *pr = per_cpu(processors, cpu); + struct acpi_device *device; - if (!pr || !acpi_fetch_acpi_dev(pr->handle)) + if (!pr || acpi_bus_get_device(pr->handle, &device)) return 0; acpi_processor_reevaluate_tstate(pr, true); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f8e9fa82cb..f37fba9e5b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -20,7 +20,6 @@ #include #include #include -#include #include /* @@ -96,11 +95,6 @@ static const struct dmi_system_id processor_power_dmi_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, (void *)1}, - /* T40 can not handle C3 idle state */ - { set_max_cstate, "IBM ThinkPad T40", { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "23737CU")}, - (void *)2}, {}, }; @@ -406,10 +400,13 @@ static int acpi_cst_latency_cmp(const void *a, const void *b) static void acpi_cst_latency_swap(void *a, void *b, int n) { struct acpi_processor_cx *x = a, *y = b; + u32 tmp; if (!(x->valid && y->valid)) return; - swap(x->latency, y->latency); + tmp = x->latency; + x->latency = y->latency; + y->latency = tmp; } static int acpi_processor_power_verify(struct acpi_processor *pr) @@ -570,8 +567,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) { struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); - if (cx->type == ACPI_STATE_C3) - ACPI_FLUSH_CPU_CACHE(); + ACPI_FLUSH_CPU_CACHE(); while (1) { @@ -793,8 +789,7 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr) state->enter = acpi_idle_enter; state->flags = 0; - if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2 || - cx->type == ACPI_STATE_C3) { + if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) { state->enter_dead = acpi_idle_play_dead; drv->safe_state_index = count; } @@ -1105,7 +1100,7 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr) status = acpi_get_parent(handle, &pr_ahandle); while (ACPI_SUCCESS(status)) { - d = acpi_fetch_acpi_dev(pr_ahandle); + acpi_bus_get_device(pr_ahandle, &d); handle = pr_ahandle; if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID)) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index d8b2dfcd59..a3d34e3f9f 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -53,17 +53,10 @@ static int phys_package_first_cpu(int cpu) static int cpu_has_cpufreq(unsigned int cpu) { - struct cpufreq_policy *policy; - - if (!acpi_processor_cpufreq_init) + struct cpufreq_policy policy; + if (!acpi_processor_cpufreq_init || cpufreq_get_policy(&policy, cpu)) return 0; - - policy = cpufreq_cpu_get(cpu); - if (policy) { - cpufreq_cpu_put(policy); - return 1; - } - return 0; + return 1; } static int cpufreq_get_max_state(unsigned int cpu) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index d0986bda29..781e312f45 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -687,9 +687,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, if (index) return -EINVAL; - device = acpi_fetch_acpi_dev(obj->reference.handle); - if (!device) - return -EINVAL; + ret = acpi_bus_get_device(obj->reference.handle, &device); + if (ret) + return ret == -ENODEV ? -EINVAL : ret; args->fwnode = acpi_fwnode_handle(device); args->nargs = 0; @@ -719,8 +719,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { struct fwnode_handle *ref_fwnode; - device = acpi_fetch_acpi_dev(element->reference.handle); - if (!device) + ret = acpi_bus_get_device(element->reference.handle, + &device); + if (ret) return -EINVAL; nargs = 0; @@ -1083,8 +1084,7 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, * Returns parent node of an ACPI device or data firmware node or %NULL if * not available. */ -static struct fwnode_handle * -acpi_node_get_parent(const struct fwnode_handle *fwnode) +struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) { if (is_acpi_data_node(fwnode)) { /* All data nodes have parent pointer so just return that */ diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index c2d4947844..3c25ce8c95 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -791,9 +791,9 @@ static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth, { struct resource *res = context; struct acpi_device **consumer = (struct acpi_device **) ret; - struct acpi_device *adev = acpi_fetch_acpi_dev(handle); + struct acpi_device *adev; - if (!adev) + if (acpi_bus_get_device(handle, &adev)) return AE_OK; if (acpi_dev_consumes_res(adev, res)) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1331756d4c..6e9cd41c5f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "internal.h" @@ -136,12 +135,12 @@ bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent) static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, void **ret_p) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device = NULL; struct acpi_device_physical_node *pn; bool second_pass = (bool)data; acpi_status status = AE_OK; - if (!device) + if (acpi_bus_get_device(handle, &device)) return AE_OK; if (device->handler && !device->handler->hotplug.enabled) { @@ -181,10 +180,10 @@ static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data, void **ret_p) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device = NULL; struct acpi_device_physical_node *pn; - if (!device) + if (acpi_bus_get_device(handle, &device)) return AE_OK; mutex_lock(&device->physical_node_lock); @@ -600,19 +599,6 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) } EXPORT_SYMBOL(acpi_bus_get_device); -/** - * acpi_fetch_acpi_dev - Retrieve ACPI device object. - * @handle: ACPI handle associated with the requested ACPI device object. - * - * Return a pointer to the ACPI device object associated with @handle, if - * present, or NULL otherwise. - */ -struct acpi_device *acpi_fetch_acpi_dev(acpi_handle handle) -{ - return handle_to_device(handle, NULL); -} -EXPORT_SYMBOL_GPL(acpi_fetch_acpi_dev); - static void get_acpi_device(void *dev) { acpi_dev_get(dev); @@ -622,7 +608,6 @@ struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) { return handle_to_device(handle, get_acpi_device); } -EXPORT_SYMBOL_GPL(acpi_bus_get_acpi_device); static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) { @@ -668,19 +653,6 @@ static int acpi_tie_acpi_dev(struct acpi_device *adev) return 0; } -static void acpi_store_pld_crc(struct acpi_device *adev) -{ - struct acpi_pld_info *pld; - acpi_status status; - - status = acpi_get_physical_device_location(adev->handle, &pld); - if (ACPI_FAILURE(status)) - return; - - adev->pld_crc = crc32(~0, pld, sizeof(*pld)); - ACPI_FREE(pld); -} - static int __acpi_device_add(struct acpi_device *device, void (*release)(struct device *)) { @@ -739,8 +711,6 @@ static int __acpi_device_add(struct acpi_device *device, if (device->wakeup.flags.valid) list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list); - acpi_store_pld_crc(device); - mutex_unlock(&acpi_device_lock); if (device->parent) @@ -826,15 +796,9 @@ static const char * const acpi_ignore_dep_ids[] = { NULL }; -/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */ -static const char * const acpi_honor_dep_ids[] = { - "INT3472", /* Camera sensor PMIC / clk and regulator info */ - NULL -}; - static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) { - struct acpi_device *device; + struct acpi_device *device = NULL; acpi_status status; /* @@ -849,9 +813,7 @@ static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) status = acpi_get_parent(handle, &handle); if (ACPI_FAILURE(status)) return status == AE_NULL_ENTRY ? NULL : acpi_root; - - device = acpi_fetch_acpi_dev(handle); - } while (!device); + } while (acpi_bus_get_device(handle, &device)); return device; } @@ -1054,7 +1016,6 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) static void acpi_bus_get_power_flags(struct acpi_device *device) { - unsigned long long dsc = ACPI_STATE_D0; u32 i; /* Presence of _PS0|_PR0 indicates 'power manageable' */ @@ -1076,9 +1037,6 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) if (acpi_has_method(device->handle, "_DSW")) device->power.flags.dsw_present = 1; - acpi_evaluate_integer(device->handle, "_DSC", NULL, &dsc); - device->power.state_for_enumeration = dsc; - /* * Enumerate supported power management states */ @@ -1377,11 +1335,11 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, if (info->valid & ACPI_VALID_HID) { acpi_add_id(pnp, info->hardware_id.string); pnp->type.platform_id = 1; - if (info->valid & ACPI_VALID_CID) { - cid_list = &info->compatible_id_list; - for (i = 0; i < cid_list->count; i++) - acpi_add_id(pnp, cid_list->ids[i].string); - } + } + if (info->valid & ACPI_VALID_CID) { + cid_list = &info->compatible_id_list; + for (i = 0; i < cid_list->count; i++) + acpi_add_id(pnp, cid_list->ids[i].string); } if (info->valid & ACPI_VALID_ADR) { pnp->bus_address = info->address; @@ -1806,12 +1764,8 @@ static void acpi_scan_dep_init(struct acpi_device *adev) struct acpi_dep_data *dep; list_for_each_entry(dep, &acpi_dep_list, node) { - if (dep->consumer == adev->handle) { - if (dep->honor_dep) - adev->flags.honor_deps = 1; - + if (dep->consumer == adev->handle) adev->dep_unmet++; - } } } @@ -2015,7 +1969,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) for (count = 0, i = 0; i < dep_devices.count; i++) { struct acpi_device_info *info; struct acpi_dep_data *dep; - bool skip, honor_dep; + bool skip; status = acpi_get_object_info(dep_devices.handles[i], &info); if (ACPI_FAILURE(status)) { @@ -2024,7 +1978,6 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) } skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids); - honor_dep = acpi_info_matches_ids(info, acpi_honor_dep_ids); kfree(info); if (skip) @@ -2038,7 +1991,6 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) dep->supplier = dep_devices.handles[i]; dep->consumer = handle; - dep->honor_dep = honor_dep; mutex_lock(&acpi_dep_list_lock); list_add_tail(&dep->node , &acpi_dep_list); @@ -2053,10 +2005,11 @@ static bool acpi_bus_scan_second_pass; static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep, struct acpi_device **adev_p) { - struct acpi_device *device = acpi_fetch_acpi_dev(handle); + struct acpi_device *device = NULL; acpi_object_type acpi_type; int type; + acpi_bus_get_device(handle, &device); if (device) goto out; @@ -2204,8 +2157,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass) register_dock_dependent_device(device, ejd); acpi_bus_get_status(device); - /* Skip devices that are not ready for enumeration (e.g. not present) */ - if (!acpi_dev_ready_for_enumeration(device)) { + /* Skip devices that are not present. */ + if (!acpi_device_is_present(device)) { device->flags.initialized = false; acpi_device_clear_enumerated(device); device->flags.power_manageable = 0; @@ -2367,23 +2320,6 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier) } EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies); -/** - * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration - * @device: Pointer to the &struct acpi_device to check - * - * Check if the device is present and has no unmet dependencies. - * - * Return true if the device is ready for enumeratino. Otherwise, return false. - */ -bool acpi_dev_ready_for_enumeration(const struct acpi_device *device) -{ - if (device->flags.honor_deps && device->dep_unmet) - return false; - - return acpi_device_is_present(device); -} -EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration); - /** * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier * @supplier: Pointer to the dependee device @@ -2502,33 +2438,42 @@ int acpi_bus_register_early_device(int type) } EXPORT_SYMBOL_GPL(acpi_bus_register_early_device); -static void acpi_bus_scan_fixed(void) +static int acpi_bus_scan_fixed(void) { - if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { - struct acpi_device *adev = NULL; + int result = 0; - acpi_add_single_object(&adev, NULL, ACPI_BUS_TYPE_POWER_BUTTON, - false); - if (adev) { - adev->flags.match_driver = true; - if (device_attach(&adev->dev) >= 0) - device_init_wakeup(&adev->dev, true); - else - dev_dbg(&adev->dev, "No driver\n"); - } + /* + * Enumerate all fixed-feature devices. + */ + if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { + struct acpi_device *device = NULL; + + result = acpi_add_single_object(&device, NULL, + ACPI_BUS_TYPE_POWER_BUTTON, false); + if (result) + return result; + + device->flags.match_driver = true; + result = device_attach(&device->dev); + if (result < 0) + return result; + + device_init_wakeup(&device->dev, true); } if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) { - struct acpi_device *adev = NULL; + struct acpi_device *device = NULL; - acpi_add_single_object(&adev, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON, - false); - if (adev) { - adev->flags.match_driver = true; - if (device_attach(&adev->dev) < 0) - dev_dbg(&adev->dev, "No driver\n"); - } + result = acpi_add_single_object(&device, NULL, + ACPI_BUS_TYPE_SLEEP_BUTTON, false); + if (result) + return result; + + device->flags.match_driver = true; + result = device_attach(&device->dev); } + + return result < 0 ? result : 0; } static void __init acpi_get_spcr_uart_addr(void) @@ -2549,8 +2494,9 @@ static void __init acpi_get_spcr_uart_addr(void) static bool acpi_scan_initialized; -void __init acpi_scan_init(void) +int __init acpi_scan_init(void) { + int result; acpi_status status; struct acpi_table_stao *stao_ptr; @@ -2600,23 +2546,33 @@ void __init acpi_scan_init(void) /* * Enumerate devices in the ACPI namespace. */ - if (acpi_bus_scan(ACPI_ROOT_OBJECT)) - goto unlock; + result = acpi_bus_scan(ACPI_ROOT_OBJECT); + if (result) + goto out; - acpi_root = acpi_fetch_acpi_dev(ACPI_ROOT_OBJECT); - if (!acpi_root) - goto unlock; + result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); + if (result) + goto out; /* Fixed feature devices do not exist on HW-reduced platform */ - if (!acpi_gbl_reduced_hardware) - acpi_bus_scan_fixed(); + if (!acpi_gbl_reduced_hardware) { + result = acpi_bus_scan_fixed(); + if (result) { + acpi_detach_data(acpi_root->handle, + acpi_scan_drop_device); + acpi_device_del(acpi_root); + acpi_bus_put_acpi_device(acpi_root); + goto out; + } + } acpi_turn_off_unused_power_resources(); acpi_scan_initialized = true; -unlock: + out: mutex_unlock(&acpi_scan_lock); + return result; } static struct acpi_probe_entry *ape; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index d4fbea91ab..7ae09e4b45 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -73,6 +73,7 @@ static int acpi_sleep_prepare(u32 acpi_state) acpi_set_waking_vector(acpi_wakeup_address); } + ACPI_FLUSH_CPU_CACHE(); #endif pr_info("Preparing to enter system sleep state S%d\n", acpi_state); acpi_enable_wakeup_devices(acpi_state); @@ -565,6 +566,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) u32 acpi_state = acpi_target_sleep_state; int error; + ACPI_FLUSH_CPU_CACHE(); + trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true); switch (acpi_state) { case ACPI_STATE_S1: @@ -736,15 +739,21 @@ bool acpi_s2idle_wake(void) return true; } - /* - * Check non-EC GPE wakeups and if there are none, cancel the - * SCI-related wakeup and dispatch the EC GPE. - */ + /* Check non-EC GPE wakeups and dispatch the EC GPE. */ if (acpi_ec_dispatch_gpe()) { pm_pr_dbg("ACPI non-EC GPE wakeup\n"); return true; } + /* + * Cancel the SCI wakeup and process all pending events in case + * there are any wakeup ones in there. + * + * Note that if any non-EC GPEs are active at this point, the + * SCI will retrigger after the rearming below, so no events + * should be missed by canceling the wakeup here. + */ + pm_system_cancel_wakeup(); acpi_os_wait_events_complete(); /* @@ -807,18 +816,14 @@ void __weak acpi_s2idle_setup(void) static void acpi_sleep_suspend_setup(void) { - bool suspend_ops_needed = false; int i; for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) - if (acpi_sleep_state_supported(i)) { + if (acpi_sleep_state_supported(i)) sleep_states[i] = 1; - suspend_ops_needed = true; - } - if (suspend_ops_needed) - suspend_set_ops(old_suspend_ordering ? - &acpi_suspend_ops_old : &acpi_suspend_ops); + suspend_set_ops(old_suspend_ordering ? + &acpi_suspend_ops_old : &acpi_suspend_ops); acpi_s2idle_setup(); } @@ -869,11 +874,11 @@ static inline void acpi_sleep_syscore_init(void) {} #ifdef CONFIG_HIBERNATION static unsigned long s4_hardware_signature; static struct acpi_table_facs *facs; -static int sigcheck = -1; /* Default behaviour is just to warn */ +static bool nosigcheck; -void __init acpi_check_s4_hw_signature(int check) +void __init acpi_no_s4_hw_signature(void) { - sigcheck = check; + nosigcheck = true; } static int acpi_hibernation_begin(pm_message_t stage) @@ -895,6 +900,8 @@ static int acpi_hibernation_enter(void) { acpi_status status = AE_OK; + ACPI_FLUSH_CPU_CACHE(); + /* This shouldn't return. If it returns, we have a problem */ status = acpi_enter_sleep_state(ACPI_STATE_S4); /* Reprogram control registers */ @@ -999,28 +1006,12 @@ static void acpi_sleep_hibernate_setup(void) hibernation_set_ops(old_suspend_ordering ? &acpi_hibernation_ops_old : &acpi_hibernation_ops); sleep_states[ACPI_STATE_S4] = 1; - if (!sigcheck) + if (nosigcheck) return; acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs); - if (facs) { - /* - * s4_hardware_signature is the local variable which is just - * used to warn about mismatch after we're attempting to - * resume (in violation of the ACPI specification.) - */ + if (facs) s4_hardware_signature = facs->hardware_signature; - - if (sigcheck > 0) { - /* - * If we're actually obeying the ACPI specification - * then the signature is written out as part of the - * swsusp header, in order to allow the boot kernel - * to gracefully decline to resume. - */ - swsusp_hardware_signature = facs->hardware_signature; - } - } } #else /* !CONFIG_HIBERNATION */ static inline void acpi_sleep_hibernate_setup(void) {} diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index d589543875..25c2d0be95 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -107,13 +107,8 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console) pr_info("SPCR table version %d\n", table->header.revision); if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { - u32 bit_width = table->serial_port.access_width; - - if (bit_width > ACPI_ACCESS_BIT_MAX) { - pr_err("Unacceptable wide SPCR Access Width. Defaulting to byte size\n"); - bit_width = ACPI_ACCESS_BIT_DEFAULT; - } - switch (ACPI_ACCESS_BIT_WIDTH((bit_width))) { + switch (ACPI_ACCESS_BIT_WIDTH(( + table->serial_port.access_width))) { default: pr_err("Unexpected SPCR Access Width. Defaulting to byte size\n"); fallthrough; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index a4b638bea6..00c0ebaab2 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -939,11 +939,10 @@ static struct attribute *hotplug_profile_attrs[] = { &hotplug_enabled_attr.attr, NULL }; -ATTRIBUTE_GROUPS(hotplug_profile); static struct kobj_type acpi_hotplug_profile_ktype = { .sysfs_ops = &kobj_sysfs_ops, - .default_groups = hotplug_profile_groups, + .default_attrs = hotplug_profile_attrs, }; void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 34600b5b9d..71419eb16e 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -35,13 +35,12 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" }; static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; -static int acpi_apic_instance __initdata_or_acpilib; +static int acpi_apic_instance __initdata; enum acpi_subtable_type { ACPI_SUBTABLE_COMMON, ACPI_SUBTABLE_HMAT, ACPI_SUBTABLE_PRMT, - ACPI_SUBTABLE_CEDT, }; struct acpi_subtable_entry { @@ -53,7 +52,7 @@ struct acpi_subtable_entry { * Disable table checksum verification for the early stage due to the size * limitation of the current x86 early mapping implementation. */ -static bool acpi_verify_table_checksum __initdata_or_acpilib = false; +static bool acpi_verify_table_checksum __initdata = false; void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { @@ -217,7 +216,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) } } -static unsigned long __init_or_acpilib +static unsigned long __init acpi_get_entry_type(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -227,13 +226,11 @@ acpi_get_entry_type(struct acpi_subtable_entry *entry) return entry->hdr->hmat.type; case ACPI_SUBTABLE_PRMT: return 0; - case ACPI_SUBTABLE_CEDT: - return entry->hdr->cedt.type; } return 0; } -static unsigned long __init_or_acpilib +static unsigned long __init acpi_get_entry_length(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -243,13 +240,11 @@ acpi_get_entry_length(struct acpi_subtable_entry *entry) return entry->hdr->hmat.length; case ACPI_SUBTABLE_PRMT: return entry->hdr->prmt.length; - case ACPI_SUBTABLE_CEDT: - return entry->hdr->cedt.length; } return 0; } -static unsigned long __init_or_acpilib +static unsigned long __init acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) { switch (entry->type) { @@ -259,40 +254,20 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry) return sizeof(entry->hdr->hmat); case ACPI_SUBTABLE_PRMT: return sizeof(entry->hdr->prmt); - case ACPI_SUBTABLE_CEDT: - return sizeof(entry->hdr->cedt); } return 0; } -static enum acpi_subtable_type __init_or_acpilib +static enum acpi_subtable_type __init acpi_get_subtable_type(char *id) { if (strncmp(id, ACPI_SIG_HMAT, 4) == 0) return ACPI_SUBTABLE_HMAT; if (strncmp(id, ACPI_SIG_PRMT, 4) == 0) return ACPI_SUBTABLE_PRMT; - if (strncmp(id, ACPI_SIG_CEDT, 4) == 0) - return ACPI_SUBTABLE_CEDT; return ACPI_SUBTABLE_COMMON; } -static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc) -{ - return proc->handler || proc->handler_arg; -} - -static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc, - union acpi_subtable_headers *hdr, - unsigned long end) -{ - if (proc->handler) - return proc->handler(hdr, end); - if (proc->handler_arg) - return proc->handler_arg(hdr, proc->arg, end); - return -EINVAL; -} - /** * acpi_parse_entries_array - for each proc_num find a suitable subtable * @@ -316,10 +291,10 @@ static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc, * On success returns sum of all matching entries for all proc handlers. * Otherwise, -ENODEV or -EINVAL is returned. */ -static int __init_or_acpilib acpi_parse_entries_array( - char *id, unsigned long table_size, - struct acpi_table_header *table_header, struct acpi_subtable_proc *proc, - int proc_num, unsigned int max_entries) +static int __init acpi_parse_entries_array(char *id, unsigned long table_size, + struct acpi_table_header *table_header, + struct acpi_subtable_proc *proc, int proc_num, + unsigned int max_entries) { struct acpi_subtable_entry entry; unsigned long table_end, subtable_len, entry_len; @@ -343,9 +318,8 @@ static int __init_or_acpilib acpi_parse_entries_array( for (i = 0; i < proc_num; i++) { if (acpi_get_entry_type(&entry) != proc[i].id) continue; - if (!has_handler(&proc[i]) || - (!errs && - call_handler(&proc[i], entry.hdr, table_end))) { + if (!proc[i].handler || + (!errs && proc[i].handler(entry.hdr, table_end))) { errs++; continue; } @@ -378,9 +352,10 @@ static int __init_or_acpilib acpi_parse_entries_array( return errs ? -EINVAL : count; } -int __init_or_acpilib acpi_table_parse_entries_array( - char *id, unsigned long table_size, struct acpi_subtable_proc *proc, - int proc_num, unsigned int max_entries) +int __init acpi_table_parse_entries_array(char *id, + unsigned long table_size, + struct acpi_subtable_proc *proc, int proc_num, + unsigned int max_entries) { struct acpi_table_header *table_header = NULL; int count; @@ -400,7 +375,7 @@ int __init_or_acpilib acpi_table_parse_entries_array( acpi_get_table(id, instance, &table_header); if (!table_header) { - pr_debug("%4.4s not present\n", id); + pr_warn("%4.4s not present\n", id); return -ENODEV; } @@ -411,41 +386,21 @@ int __init_or_acpilib acpi_table_parse_entries_array( return count; } -static int __init_or_acpilib __acpi_table_parse_entries( - char *id, unsigned long table_size, int entry_id, - acpi_tbl_entry_handler handler, acpi_tbl_entry_handler_arg handler_arg, - void *arg, unsigned int max_entries) +int __init acpi_table_parse_entries(char *id, + unsigned long table_size, + int entry_id, + acpi_tbl_entry_handler handler, + unsigned int max_entries) { struct acpi_subtable_proc proc = { .id = entry_id, .handler = handler, - .handler_arg = handler_arg, - .arg = arg, }; return acpi_table_parse_entries_array(id, table_size, &proc, 1, max_entries); } -int __init_or_acpilib -acpi_table_parse_cedt(enum acpi_cedt_type id, - acpi_tbl_entry_handler_arg handler_arg, void *arg) -{ - return __acpi_table_parse_entries(ACPI_SIG_CEDT, - sizeof(struct acpi_table_cedt), id, - NULL, handler_arg, arg, 0); -} -EXPORT_SYMBOL_ACPI_LIB(acpi_table_parse_cedt); - -int __init acpi_table_parse_entries(char *id, unsigned long table_size, - int entry_id, - acpi_tbl_entry_handler handler, - unsigned int max_entries) -{ - return __acpi_table_parse_entries(id, table_size, entry_id, handler, - NULL, NULL, max_entries); -} - int __init acpi_table_parse_madt(enum acpi_madt_type id, acpi_tbl_entry_handler handler, unsigned int max_entries) { @@ -545,7 +500,7 @@ static const char table_sigs[][ACPI_NAMESEG_SIZE] __initconst = { ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT, - ACPI_SIG_NHLT, ACPI_SIG_AEST }; + ACPI_SIG_NHLT }; #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) @@ -768,7 +723,7 @@ static void __init acpi_table_initrd_scan(void) /* * Mark the table to avoid being used in * acpi_table_initrd_override(). Though this is not possible - * because override is disabled in acpi_install_physical_table(). + * because override is disabled in acpi_install_table(). */ if (test_and_set_bit(table_index, acpi_initrd_installed)) { acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); @@ -779,7 +734,7 @@ static void __init acpi_table_initrd_scan(void) table->signature, table->oem_id, table->oem_table_id); acpi_os_unmap_memory(table, ACPI_HEADER_SIZE); - acpi_install_physical_table(acpi_tables_addr + table_offset); + acpi_install_table(acpi_tables_addr + table_offset, TRUE); next_table: table_offset += table_length; table_index++; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 539660ef93..95105db642 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -697,6 +697,7 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, struct acpi_device *device = cdev->devdata; struct acpi_thermal *tz = thermal->devdata; struct acpi_device *dev; + acpi_status status; acpi_handle handle; int i; int j; @@ -714,8 +715,8 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, for (i = 0; i < tz->trips.passive.devices.count; i++) { handle = tz->trips.passive.devices.handles[i]; - dev = acpi_fetch_acpi_dev(handle); - if (dev != device) + status = acpi_bus_get_device(handle, &dev); + if (ACPI_FAILURE(status) || dev != device) continue; if (bind) result = @@ -740,8 +741,8 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, j < tz->trips.active[i].devices.count; j++) { handle = tz->trips.active[i].devices.handles[j]; - dev = acpi_fetch_acpi_dev(handle); - if (dev != device) + status = acpi_bus_get_device(handle, &dev); + if (ACPI_FAILURE(status) || dev != device) continue; if (bind) result = thermal_zone_bind_cooling_device @@ -1097,6 +1098,8 @@ static int acpi_thermal_resume(struct device *dev) return -EINVAL; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { + if (!(&tz->trips.active[i])) + break; if (!tz->trips.active[i].flags.valid) break; tz->trips.active[i].flags.enabled = 1; diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 4f64713e99..33474fd969 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -59,16 +59,18 @@ static void acpi_video_parse_cmdline(void) static acpi_status find_video(acpi_handle handle, u32 lvl, void *context, void **rv) { - struct acpi_device *acpi_dev = acpi_fetch_acpi_dev(handle); long *cap = context; struct pci_dev *dev; + struct acpi_device *acpi_dev; static const struct acpi_device_id video_ids[] = { {ACPI_VIDEO_HID, 0}, {"", 0}, }; + if (acpi_bus_get_device(handle, &acpi_dev)) + return AE_OK; - if (acpi_dev && !acpi_match_device_ids(acpi_dev, video_ids)) { + if (!acpi_match_device_ids(acpi_dev, video_ids)) { dev = acpi_get_pci_dev(handle); if (!dev) return AE_OK; @@ -113,7 +115,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_vendor, - /* X360 */ + .ident = "X360", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "X360"), @@ -122,7 +124,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - /* Asus UL30VT */ + .ident = "Asus UL30VT", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), @@ -130,7 +132,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - /* Asus UL30A */ + .ident = "Asus UL30A", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), @@ -138,7 +140,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - /* GIGABYTE GB-BXBT-2807 */ + .ident = "GIGABYTE GB-BXBT-2807", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), @@ -146,20 +148,12 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - /* Sony VPCEH3U1E */ + .ident = "Sony VPCEH3U1E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), }, }, - { - .callback = video_detect_force_vendor, - /* Xiaomi Mi Pad 2 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), - DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), - }, - }, /* * These models have a working acpi_video backlight control, and using @@ -170,7 +164,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_video, - /* ThinkPad T420 */ + .ident = "ThinkPad T420", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"), @@ -178,7 +172,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - /* ThinkPad T520 */ + .ident = "ThinkPad T520", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), @@ -186,7 +180,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - /* ThinkPad X201s */ + .ident = "ThinkPad X201s", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"), @@ -194,7 +188,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - /* ThinkPad X201T */ + .ident = "ThinkPad X201T", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"), @@ -205,7 +199,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */ .callback = video_detect_force_video, - /* HP ENVY 15 Notebook */ + .ident = "HP ENVY 15 Notebook", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), @@ -213,7 +207,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - /* SAMSUNG 870Z5E/880Z5E/680Z5E */ + .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), @@ -221,7 +215,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */ + .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -231,7 +225,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */ .callback = video_detect_force_video, - /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */ + .ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -241,7 +235,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ .callback = video_detect_force_video, - /* SAMSUNG 670Z5E */ + .ident = "SAMSUNG 670Z5E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), @@ -250,7 +244,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ .callback = video_detect_force_video, - /* SAMSUNG 730U3E/740U3E */ + .ident = "SAMSUNG 730U3E/740U3E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), @@ -259,7 +253,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */ .callback = video_detect_force_video, - /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */ + .ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -269,7 +263,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */ .callback = video_detect_force_video, - /* Dell XPS14 L421X */ + .ident = "Dell XPS14 L421X", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), @@ -278,7 +272,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ .callback = video_detect_force_video, - /* Dell XPS15 L521X */ + .ident = "Dell XPS15 L521X", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), @@ -287,7 +281,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */ .callback = video_detect_force_video, - /* SAMSUNG 530U4E/540U4E */ + .ident = "SAMSUNG 530U4E/540U4E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), @@ -296,7 +290,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { /* https://bugs.launchpad.net/bugs/1894667 */ { .callback = video_detect_force_video, - /* HP 635 Notebook */ + .ident = "HP 635 Notebook", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"), @@ -307,7 +301,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */ .callback = video_detect_force_native, - /* Lenovo Ideapad S405 */ + .ident = "Lenovo Ideapad S405", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"), @@ -316,7 +310,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ .callback = video_detect_force_native, - /* Lenovo Ideapad Z570 */ + .ident = "Lenovo Ideapad Z570", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), @@ -324,7 +318,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* Lenovo E41-25 */ + .ident = "Lenovo E41-25", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "81FS"), @@ -332,7 +326,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* Lenovo E41-45 */ + .ident = "Lenovo E41-45", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), @@ -341,7 +335,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */ .callback = video_detect_force_native, - /* Apple MacBook Pro 12,1 */ + .ident = "Apple MacBook Pro 12,1", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), @@ -349,7 +343,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* Dell Vostro V131 */ + .ident = "Dell Vostro V131", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), @@ -358,7 +352,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */ .callback = video_detect_force_native, - /* Dell XPS 17 L702X */ + .ident = "Dell XPS 17 L702X", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"), @@ -366,7 +360,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* Dell Precision 7510 */ + .ident = "Dell Precision 7510", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"), @@ -374,7 +368,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* Acer Aspire 5738z */ + .ident = "Acer Aspire 5738z", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), @@ -384,7 +378,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */ .callback = video_detect_force_native, - /* Acer TravelMate 5735Z */ + .ident = "Acer TravelMate 5735Z", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"), @@ -393,7 +387,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA401 */ + .ident = "ASUSTeK COMPUTER INC. GA401", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), @@ -401,7 +395,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA502 */ + .ident = "ASUSTeK COMPUTER INC. GA502", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), @@ -409,7 +403,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - /* ASUSTeK COMPUTER INC. GA503 */ + .ident = "ASUSTeK COMPUTER INC. GA503", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), @@ -422,7 +416,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_none, - /* Dell OptiPlex 9020M */ + .ident = "Dell OptiPlex 9020M", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), @@ -430,7 +424,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_none, - /* MSI MS-7721 */ + .ident = "MSI MS-7721", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MSI"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"), diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index ed889f827f..e0185e841b 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -293,9 +293,9 @@ static void lpi_check_constraints(void) for (i = 0; i < lpi_constraints_table_size; ++i) { acpi_handle handle = lpi_constraints_table[i].handle; - struct acpi_device *adev = acpi_fetch_acpi_dev(handle); + struct acpi_device *adev; - if (!adev) + if (!handle || acpi_bus_get_device(handle, &adev)) continue; acpi_handle_debug(handle, diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index ffdeed5334..b3fb428461 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -8,11 +8,8 @@ * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. */ -#define pr_fmt(fmt) "ACPI: " fmt - #include #include -#include #include #include #include "../internal.h" @@ -74,12 +71,6 @@ static const struct override_status_id override_status_ids[] = { PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}), PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}), - /* The Xiaomi Mi Pad 2 uses PWM2 for touchkeys backlight control */ - PRESENT_ENTRY_HID("80862289", "2", ATOM_AIRMONT, { - DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), - DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), - }), - /* * The INT0002 device is necessary to clear wakeup interrupt sources * on Cherry Trail devices, without it we get nobody cared IRQ msgs. @@ -211,183 +202,3 @@ bool force_storage_d3(void) { return x86_match_cpu(storage_d3_cpu_ids); } - -/* - * x86 ACPI boards which ship with only Android as their factory image usually - * declare a whole bunch of bogus I2C devices in their ACPI tables and sometimes - * there are issues with serdev devices on these boards too, e.g. the resource - * points to the wrong serdev_controller. - * - * Instantiating I2C / serdev devs for these bogus devs causes various issues, - * e.g. GPIO/IRQ resource conflicts because sometimes drivers do bind to them. - * The Android x86 kernel fork shipped on these devices has some special code - * to remove the bogus I2C clients (and AFAICT serdevs are ignored completely). - * - * The acpi_quirk_skip_*_enumeration() functions below are used by the I2C or - * serdev code to skip instantiating any I2C or serdev devs on broken boards. - * - * In case of I2C an exception is made for HIDs on the i2c_acpi_known_good_ids - * list. These are known to always be correct (and in case of the audio-codecs - * the drivers heavily rely on the codec being enumerated through ACPI). - * - * Note these boards typically do actually have I2C and serdev devices, - * just different ones then the ones described in their DSDT. The devices - * which are actually present are manually instantiated by the - * drivers/platform/x86/x86-android-tablets.c kernel module. - */ -#define ACPI_QUIRK_SKIP_I2C_CLIENTS BIT(0) -#define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(1) -#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(2) -#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(3) - -static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { - /* - * 1. Devices with only the skip / don't-skip AC and battery quirks, - * sorted alphabetically. - */ - { - /* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */ - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - .driver_data = (void *)ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY - }, - { - /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "80XF"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), - }, - .driver_data = (void *)ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY - }, - - /* - * 2. Devices which also have the skip i2c/serdev quirks and which - * need the x86-android-tablets module to properly work. - */ -#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) - { - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), - }, - .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | - ACPI_QUIRK_UART1_TTY_UART2_SKIP | - ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), - }, - .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | - ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), - }, - { - /* Whitelabel (sold as various brands) TM800A550L */ - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), - /* Above strings are too generic, also match on BIOS version */ - DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), - }, - .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | - ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), - }, -#endif - {} -}; - -#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) -static const struct acpi_device_id i2c_acpi_known_good_ids[] = { - { "10EC5640", 0 }, /* RealTek ALC5640 audio codec */ - { "INT33F4", 0 }, /* X-Powers AXP288 PMIC */ - { "INT33FD", 0 }, /* Intel Crystal Cove PMIC */ - { "NPCE69A", 0 }, /* Asus Transformer keyboard dock */ - {} -}; - -bool acpi_quirk_skip_i2c_client_enumeration(struct acpi_device *adev) -{ - const struct dmi_system_id *dmi_id; - long quirks; - - dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); - if (!dmi_id) - return false; - - quirks = (unsigned long)dmi_id->driver_data; - if (!(quirks & ACPI_QUIRK_SKIP_I2C_CLIENTS)) - return false; - - return acpi_match_device_ids(adev, i2c_acpi_known_good_ids); -} -EXPORT_SYMBOL_GPL(acpi_quirk_skip_i2c_client_enumeration); - -int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip) -{ - struct acpi_device *adev = ACPI_COMPANION(controller_parent); - const struct dmi_system_id *dmi_id; - long quirks = 0; - - *skip = false; - - /* !dev_is_platform() to not match on PNP enumerated debug UARTs */ - if (!adev || !adev->pnp.unique_id || !dev_is_platform(controller_parent)) - return 0; - - dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); - if (dmi_id) - quirks = (unsigned long)dmi_id->driver_data; - - if (quirks & ACPI_QUIRK_UART1_TTY_UART2_SKIP) { - if (!strcmp(adev->pnp.unique_id, "1")) - return -ENODEV; /* Create tty cdev instead of serdev */ - - if (!strcmp(adev->pnp.unique_id, "2")) - *skip = true; - } - - return 0; -} -EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration); -#endif - -/* Lists of PMIC ACPI HIDs with an (often better) native charger driver */ -static const struct { - const char *hid; - int hrv; -} acpi_skip_ac_and_battery_pmic_ids[] = { - { "INT33F4", -1 }, /* X-Powers AXP288 PMIC */ - { "INT34D3", 3 }, /* Intel Cherrytrail Whiskey Cove PMIC */ -}; - -bool acpi_quirk_skip_acpi_ac_and_battery(void) -{ - const struct dmi_system_id *dmi_id; - long quirks = 0; - int i; - - dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); - if (dmi_id) - quirks = (unsigned long)dmi_id->driver_data; - - if (quirks & ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY) - return true; - - if (quirks & ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY) - return false; - - for (i = 0; i < ARRAY_SIZE(acpi_skip_ac_and_battery_pmic_ids); i++) { - if (acpi_dev_present(acpi_skip_ac_and_battery_pmic_ids[i].hid, "1", - acpi_skip_ac_and_battery_pmic_ids[i].hrv)) { - pr_info_once("found native %s PMIC, skipping ACPI AC and battery devices\n", - acpi_skip_ac_and_battery_pmic_ids[i].hid); - return true; - } - } - - return false; -} -EXPORT_SYMBOL_GPL(acpi_quirk_skip_acpi_ac_and_battery); diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 8351c56388..99ae919255 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -69,7 +69,7 @@ #include -#include +#include #include "binder_internal.h" #include "binder_trace.h" @@ -1946,7 +1946,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_FD: { /* * No need to close the file here since user-space - * closes it for successfully delivered + * closes it for for successfully delivered * transactions. For transactions that weren't * delivered, the new fd was never allocated so * there is no need to close and the fput on the @@ -2233,258 +2233,16 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset, return ret; } -/** - * struct binder_ptr_fixup - data to be fixed-up in target buffer - * @offset offset in target buffer to fixup - * @skip_size bytes to skip in copy (fixup will be written later) - * @fixup_data data to write at fixup offset - * @node list node - * - * This is used for the pointer fixup list (pf) which is created and consumed - * during binder_transaction() and is only accessed locally. No - * locking is necessary. - * - * The list is ordered by @offset. - */ -struct binder_ptr_fixup { - binder_size_t offset; - size_t skip_size; - binder_uintptr_t fixup_data; - struct list_head node; -}; - -/** - * struct binder_sg_copy - scatter-gather data to be copied - * @offset offset in target buffer - * @sender_uaddr user address in source buffer - * @length bytes to copy - * @node list node - * - * This is used for the sg copy list (sgc) which is created and consumed - * during binder_transaction() and is only accessed locally. No - * locking is necessary. - * - * The list is ordered by @offset. - */ -struct binder_sg_copy { - binder_size_t offset; - const void __user *sender_uaddr; - size_t length; - struct list_head node; -}; - -/** - * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data - * @alloc: binder_alloc associated with @buffer - * @buffer: binder buffer in target process - * @sgc_head: list_head of scatter-gather copy list - * @pf_head: list_head of pointer fixup list - * - * Processes all elements of @sgc_head, applying fixups from @pf_head - * and copying the scatter-gather data from the source process' user - * buffer to the target's buffer. It is expected that the list creation - * and processing all occurs during binder_transaction() so these lists - * are only accessed in local context. - * - * Return: 0=success, else -errno - */ -static int binder_do_deferred_txn_copies(struct binder_alloc *alloc, - struct binder_buffer *buffer, - struct list_head *sgc_head, - struct list_head *pf_head) -{ - int ret = 0; - struct binder_sg_copy *sgc, *tmpsgc; - struct binder_ptr_fixup *pf = - list_first_entry_or_null(pf_head, struct binder_ptr_fixup, - node); - - list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { - size_t bytes_copied = 0; - - while (bytes_copied < sgc->length) { - size_t copy_size; - size_t bytes_left = sgc->length - bytes_copied; - size_t offset = sgc->offset + bytes_copied; - - /* - * We copy up to the fixup (pointed to by pf) - */ - copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) - : bytes_left; - if (!ret && copy_size) - ret = binder_alloc_copy_user_to_buffer( - alloc, buffer, - offset, - sgc->sender_uaddr + bytes_copied, - copy_size); - bytes_copied += copy_size; - if (copy_size != bytes_left) { - BUG_ON(!pf); - /* we stopped at a fixup offset */ - if (pf->skip_size) { - /* - * we are just skipping. This is for - * BINDER_TYPE_FDA where the translated - * fds will be fixed up when we get - * to target context. - */ - bytes_copied += pf->skip_size; - } else { - /* apply the fixup indicated by pf */ - if (!ret) - ret = binder_alloc_copy_to_buffer( - alloc, buffer, - pf->offset, - &pf->fixup_data, - sizeof(pf->fixup_data)); - bytes_copied += sizeof(pf->fixup_data); - } - list_del(&pf->node); - kfree(pf); - pf = list_first_entry_or_null(pf_head, - struct binder_ptr_fixup, node); - } - } - list_del(&sgc->node); - kfree(sgc); - } - BUG_ON(!list_empty(pf_head)); - BUG_ON(!list_empty(sgc_head)); - - return ret > 0 ? -EINVAL : ret; -} - -/** - * binder_cleanup_deferred_txn_lists() - free specified lists - * @sgc_head: list_head of scatter-gather copy list - * @pf_head: list_head of pointer fixup list - * - * Called to clean up @sgc_head and @pf_head if there is an - * error. - */ -static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head, - struct list_head *pf_head) -{ - struct binder_sg_copy *sgc, *tmpsgc; - struct binder_ptr_fixup *pf, *tmppf; - - list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { - list_del(&sgc->node); - kfree(sgc); - } - list_for_each_entry_safe(pf, tmppf, pf_head, node) { - list_del(&pf->node); - kfree(pf); - } -} - -/** - * binder_defer_copy() - queue a scatter-gather buffer for copy - * @sgc_head: list_head of scatter-gather copy list - * @offset: binder buffer offset in target process - * @sender_uaddr: user address in source process - * @length: bytes to copy - * - * Specify a scatter-gather block to be copied. The actual copy must - * be deferred until all the needed fixups are identified and queued. - * Then the copy and fixups are done together so un-translated values - * from the source are never visible in the target buffer. - * - * We are guaranteed that repeated calls to this function will have - * monotonically increasing @offset values so the list will naturally - * be ordered. - * - * Return: 0=success, else -errno - */ -static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset, - const void __user *sender_uaddr, size_t length) -{ - struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL); - - if (!bc) - return -ENOMEM; - - bc->offset = offset; - bc->sender_uaddr = sender_uaddr; - bc->length = length; - INIT_LIST_HEAD(&bc->node); - - /* - * We are guaranteed that the deferred copies are in-order - * so just add to the tail. - */ - list_add_tail(&bc->node, sgc_head); - - return 0; -} - -/** - * binder_add_fixup() - queue a fixup to be applied to sg copy - * @pf_head: list_head of binder ptr fixup list - * @offset: binder buffer offset in target process - * @fixup: bytes to be copied for fixup - * @skip_size: bytes to skip when copying (fixup will be applied later) - * - * Add the specified fixup to a list ordered by @offset. When copying - * the scatter-gather buffers, the fixup will be copied instead of - * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup - * will be applied later (in target process context), so we just skip - * the bytes specified by @skip_size. If @skip_size is 0, we copy the - * value in @fixup. - * - * This function is called *mostly* in @offset order, but there are - * exceptions. Since out-of-order inserts are relatively uncommon, - * we insert the new element by searching backward from the tail of - * the list. - * - * Return: 0=success, else -errno - */ -static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset, - binder_uintptr_t fixup, size_t skip_size) -{ - struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL); - struct binder_ptr_fixup *tmppf; - - if (!pf) - return -ENOMEM; - - pf->offset = offset; - pf->fixup_data = fixup; - pf->skip_size = skip_size; - INIT_LIST_HEAD(&pf->node); - - /* Fixups are *mostly* added in-order, but there are some - * exceptions. Look backwards through list for insertion point. - */ - list_for_each_entry_reverse(tmppf, pf_head, node) { - if (tmppf->offset < pf->offset) { - list_add(&pf->node, &tmppf->node); - return 0; - } - } - /* - * if we get here, then the new offset is the lowest so - * insert at the head - */ - list_add(&pf->node, pf_head); - return 0; -} - -static int binder_translate_fd_array(struct list_head *pf_head, - struct binder_fd_array_object *fda, - const void __user *sender_ubuffer, +static int binder_translate_fd_array(struct binder_fd_array_object *fda, struct binder_buffer_object *parent, - struct binder_buffer_object *sender_uparent, struct binder_transaction *t, struct binder_thread *thread, struct binder_transaction *in_reply_to) { binder_size_t fdi, fd_buf_size; binder_size_t fda_offset; - const void __user *sender_ufda_base; struct binder_proc *proc = thread->proc; - int ret; + struct binder_proc *target_proc = t->to_proc; fd_buf_size = sizeof(u32) * fda->num_fds; if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { @@ -2508,25 +2266,19 @@ static int binder_translate_fd_array(struct list_head *pf_head, */ fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) + fda->parent_offset; - sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + - fda->parent_offset; - - if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) || - !IS_ALIGNED((unsigned long)sender_ufda_base, sizeof(u32))) { + if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) { binder_user_error("%d:%d parent offset not aligned correctly.\n", proc->pid, thread->pid); return -EINVAL; } - ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); - if (ret) - return ret; - for (fdi = 0; fdi < fda->num_fds; fdi++) { u32 fd; + int ret; binder_size_t offset = fda_offset + fdi * sizeof(fd); - binder_size_t sender_uoffset = fdi * sizeof(fd); - ret = copy_from_user(&fd, sender_ufda_base + sender_uoffset, sizeof(fd)); + ret = binder_alloc_copy_from_buffer(&target_proc->alloc, + &fd, t->buffer, + offset, sizeof(fd)); if (!ret) ret = binder_translate_fd(fd, offset, t, thread, in_reply_to); @@ -2536,8 +2288,7 @@ static int binder_translate_fd_array(struct list_head *pf_head, return 0; } -static int binder_fixup_parent(struct list_head *pf_head, - struct binder_transaction *t, +static int binder_fixup_parent(struct binder_transaction *t, struct binder_thread *thread, struct binder_buffer_object *bp, binder_size_t off_start_offset, @@ -2583,7 +2334,14 @@ static int binder_fixup_parent(struct list_head *pf_head, } buffer_offset = bp->parent_offset + (uintptr_t)parent->buffer - (uintptr_t)b->user_data; - return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); + if (binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset, + &bp->buffer, sizeof(bp->buffer))) { + binder_user_error("%d:%d got transaction with invalid parent offset\n", + proc->pid, thread->pid); + return -EINVAL; + } + + return 0; } /** @@ -2725,12 +2483,8 @@ static void binder_transaction(struct binder_proc *proc, int t_debug_id = atomic_inc_return(&binder_last_id); char *secctx = NULL; u32 secctx_sz = 0; - struct list_head sgc_head; - struct list_head pf_head; const void __user *user_buffer = (const void __user *) (uintptr_t)tr->data.ptr.buffer; - INIT_LIST_HEAD(&sgc_head); - INIT_LIST_HEAD(&pf_head); e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3197,8 +2951,6 @@ static void binder_transaction(struct binder_proc *proc, case BINDER_TYPE_FDA: { struct binder_object ptr_object; binder_size_t parent_offset; - struct binder_object user_object; - size_t user_parent_size; struct binder_fd_array_object *fda = to_binder_fd_array_object(hdr); size_t num_valid = (buffer_offset - off_start_offset) / @@ -3230,27 +2982,8 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_bad_parent; } - /* - * We need to read the user version of the parent - * object to get the original user offset - */ - user_parent_size = - binder_get_object(proc, user_buffer, t->buffer, - parent_offset, &user_object); - if (user_parent_size != sizeof(user_object.bbo)) { - binder_user_error("%d:%d invalid ptr object size: %zd vs %zd\n", - proc->pid, thread->pid, - user_parent_size, - sizeof(user_object.bbo)); - return_error = BR_FAILED_REPLY; - return_error_param = -EINVAL; - return_error_line = __LINE__; - goto err_bad_parent; - } - ret = binder_translate_fd_array(&pf_head, fda, - user_buffer, parent, - &user_object.bbo, t, - thread, in_reply_to); + ret = binder_translate_fd_array(fda, parent, t, thread, + in_reply_to); if (!ret) ret = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, @@ -3280,14 +3013,19 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_bad_offset; } - ret = binder_defer_copy(&sgc_head, sg_buf_offset, - (const void __user *)(uintptr_t)bp->buffer, - bp->length); - if (ret) { + if (binder_alloc_copy_user_to_buffer( + &target_proc->alloc, + t->buffer, + sg_buf_offset, + (const void __user *) + (uintptr_t)bp->buffer, + bp->length)) { + binder_user_error("%d:%d got transaction with invalid offsets ptr\n", + proc->pid, thread->pid); + return_error_param = -EFAULT; return_error = BR_FAILED_REPLY; - return_error_param = ret; return_error_line = __LINE__; - goto err_translate_failed; + goto err_copy_data_failed; } /* Fixup buffer pointer to target proc address space */ bp->buffer = (uintptr_t) @@ -3296,8 +3034,7 @@ static void binder_transaction(struct binder_proc *proc, num_valid = (buffer_offset - off_start_offset) / sizeof(binder_size_t); - ret = binder_fixup_parent(&pf_head, t, - thread, bp, + ret = binder_fixup_parent(t, thread, bp, off_start_offset, num_valid, last_fixup_obj_off, @@ -3337,17 +3074,6 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_copy_data_failed; } - - ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, - &sgc_head, &pf_head); - if (ret) { - binder_user_error("%d:%d got transaction with invalid offsets ptr\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - return_error_param = ret; - return_error_line = __LINE__; - goto err_copy_data_failed; - } if (t->buffer->oneway_spam_suspect) tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; else @@ -3421,7 +3147,6 @@ static void binder_transaction(struct binder_proc *proc, err_bad_offset: err_bad_parent: err_copy_data_failed: - binder_cleanup_deferred_txn_lists(&sgc_head, &pf_head); binder_free_txn_fixups(t); trace_binder_transaction_failed_buffer_release(t->buffer); binder_transaction_buffer_release(target_proc, NULL, t->buffer, diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cb54631fd9..a7da8ea7b3 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -146,7 +146,7 @@ config SATA_AHCI_PLATFORM config AHCI_BRCM tristate "Broadcom AHCI SATA support" depends on ARCH_BRCMSTB || BMIPS_GENERIC || ARCH_BCM_NSP || \ - ARCH_BCM_63XX || COMPILE_TEST + ARCH_BCM_63XX select SATA_HOST help This option enables support for the AHCI SATA3 controller found on @@ -156,7 +156,7 @@ config AHCI_BRCM config AHCI_DA850 tristate "DaVinci DA850 AHCI SATA support" - depends on ARCH_DAVINCI_DA850 || COMPILE_TEST + depends on ARCH_DAVINCI_DA850 select SATA_HOST help This option enables support for the DaVinci DA850 SoC's @@ -166,7 +166,7 @@ config AHCI_DA850 config AHCI_DM816 tristate "DaVinci DM816 AHCI SATA support" - depends on ARCH_OMAP2PLUS || COMPILE_TEST + depends on ARCH_OMAP2PLUS select SATA_HOST help This option enables support for the DaVinci DM816 SoC's @@ -206,7 +206,7 @@ config AHCI_CEVA config AHCI_MTK tristate "MediaTek AHCI SATA support" - depends on ARCH_MEDIATEK || COMPILE_TEST + depends on ARCH_MEDIATEK select MFD_SYSCON select SATA_HOST help @@ -217,7 +217,7 @@ config AHCI_MTK config AHCI_MVEBU tristate "Marvell EBU AHCI SATA support" - depends on ARCH_MVEBU || COMPILE_TEST + depends on ARCH_MVEBU select SATA_HOST help This option enables support for the Marvebu EBU SoC's @@ -236,7 +236,7 @@ config AHCI_OCTEON config AHCI_SUNXI tristate "Allwinner sunxi AHCI SATA support" - depends on ARCH_SUNXI || COMPILE_TEST + depends on ARCH_SUNXI select SATA_HOST help This option enables support for the Allwinner sunxi SoC's @@ -246,7 +246,7 @@ config AHCI_SUNXI config AHCI_TEGRA tristate "NVIDIA Tegra AHCI SATA support" - depends on ARCH_TEGRA || COMPILE_TEST + depends on ARCH_TEGRA select SATA_HOST help This option enables support for the NVIDIA Tegra SoC's @@ -256,7 +256,7 @@ config AHCI_TEGRA config AHCI_XGENE tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" - depends on PHY_XGENE || COMPILE_TEST + depends on PHY_XGENE select SATA_HOST help This option enables support for APM X-Gene SoC SATA host controller. @@ -273,7 +273,7 @@ config AHCI_QORIQ config SATA_FSL tristate "Freescale 3.0Gbps SATA support" - depends on FSL_SOC || COMPILE_TEST + depends on FSL_SOC select SATA_HOST help This option enables support for Freescale 3.0Gbps SATA controller. @@ -294,7 +294,7 @@ config SATA_GEMINI config SATA_AHCI_SEATTLE tristate "AMD Seattle 6.0Gbps AHCI SATA host controller support" - depends on ARCH_SEATTLE || COMPILE_TEST + depends on ARCH_SEATTLE select SATA_HOST help This option enables support for AMD Seattle SATA host controller. @@ -432,6 +432,18 @@ config SATA_DWC_OLD_DMA This option enables support for old device trees without the "dmas" property. +config SATA_DWC_DEBUG + bool "Debugging driver version" + depends on SATA_DWC + help + This option enables debugging output in the driver. + +config SATA_DWC_VDEBUG + bool "Verbose debug output" + depends on SATA_DWC_DEBUG + help + This option enables the taskfile dumping and NCQ debugging. + config SATA_HIGHBANK tristate "Calxeda Highbank SATA support" depends on ARCH_HIGHBANK || COMPILE_TEST @@ -599,7 +611,7 @@ config PATA_ATP867X config PATA_BK3710 tristate "Palmchip BK3710 PATA support" - depends on ARCH_DAVINCI || COMPILE_TEST + depends on ARCH_DAVINCI select PATA_TIMINGS help This option enables support for the integrated IDE controller on @@ -637,7 +649,7 @@ config PATA_CS5530 config PATA_CS5535 tristate "CS5535 PATA support (Experimental)" - depends on PCI && (X86_32 || (X86_64 && COMPILE_TEST)) + depends on PCI && X86_32 help This option enables support for the NatSemi/AMD CS5535 companion chip used with the Geode processor family. @@ -685,7 +697,7 @@ config PATA_EP93XX config PATA_FTIDE010 tristate "Faraday Technology FTIDE010 PATA support" depends on OF - depends on ARM || COMPILE_TEST + depends on ARM depends on SATA_GEMINI help This option enables support for the Faraday FTIDE010 @@ -748,7 +760,7 @@ config PATA_ICSIDE config PATA_IMX tristate "PATA support for Freescale iMX" - depends on ARCH_MXC || COMPILE_TEST + depends on ARCH_MXC select PATA_TIMINGS help This option enables support for the PATA host available on Freescale @@ -969,7 +981,7 @@ config PATA_VIA config PATA_PXA tristate "PXA DMA-capable PATA support" - depends on ARCH_PXA || COMPILE_TEST + depends on ARCH_PXA help This option enables support for harddrive attached to PXA CPU's bus. @@ -1145,7 +1157,7 @@ config PATA_RZ1000 config PATA_SAMSUNG_CF tristate "Samsung SoC PATA support" - depends on SAMSUNG_DEV_IDE || COMPILE_TEST + depends on SAMSUNG_DEV_IDE select PATA_TIMINGS help This option enables basic support for Samsung's S3C/S5P board diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 536d4cb8f0..2a04e8abd3 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -185,6 +185,8 @@ static unsigned int acard_ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) struct acard_sg *acard_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; unsigned int si, last_si = 0; + VPRINTK("ENTER\n"); + /* * Next, the S/G list. */ @@ -360,6 +362,8 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id struct ata_host *host; int n_ports, i, rc; + VPRINTK("ENTER\n"); + WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS); ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ab5811ef5a..812731e80f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -51,7 +51,6 @@ enum board_ids { board_ahci, board_ahci_ign_iferr, board_ahci_mobile, - board_ahci_no_debounce_delay, board_ahci_nomsi, board_ahci_noncq, board_ahci_nosntf, @@ -142,13 +141,6 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, - [board_ahci_no_debounce_delay] = { - .flags = AHCI_FLAG_COMMON, - .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY, - .pio_mask = ATA_PIO4, - .udma_mask = ATA_UDMA6, - .port_ops = &ahci_ops, - }, [board_ahci_nomsi] = { AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), .flags = AHCI_FLAG_COMMON, @@ -266,7 +258,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ - { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8/Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */ { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ @@ -324,7 +316,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ - { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG/Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */ @@ -366,8 +358,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */ - { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg/Lewisburg AHCI*/ - { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg/Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ + { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x43d4), board_ahci }, /* Rocket Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0x43d5), board_ahci }, /* Rocket Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0x43d6), board_ahci }, /* Rocket Lake PCH-H RAID */ @@ -402,6 +394,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ + { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ @@ -445,7 +441,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci_al }, /* AMD */ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ - { PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */ { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ /* AMD is using RAID class only for ahci controllers */ @@ -598,7 +593,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */ { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */ - { PCI_VDEVICE(ASMEDIA, 0x0624), board_ahci }, /* ASM1062+JMB575 */ /* * Samsung SSDs found on some macbooks. NCQ times out if MSI is @@ -693,7 +687,7 @@ static void ahci_pci_init_controller(struct ata_host *host) /* clear port IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); - dev_dbg(&pdev->dev, "PORT_IRQ_STAT 0x%x\n", tmp); + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); if (tmp) writel(tmp, port_mmio + PORT_IRQ_STAT); } @@ -709,6 +703,8 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, bool online; int rc; + DPRINTK("ENTER\n"); + hpriv->stop_engine(ap); rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), @@ -716,6 +712,8 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, hpriv->start_engine(ap); + DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); + /* vt8251 doesn't clear BSY on signature FIS reception, * request follow-up softreset. */ @@ -795,6 +793,8 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, bool online; int rc, i; + DPRINTK("ENTER\n"); + hpriv->stop_engine(ap); for (i = 0; i < 2; i++) { @@ -832,6 +832,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, if (online) *class = ahci_dev_classify(ap); + DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); return rc; } @@ -1478,6 +1479,7 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance) u32 irq_stat, irq_masked; unsigned int handled = 1; + VPRINTK("ENTER\n"); hpriv = host->private_data; mmio = hpriv->mmio; irq_stat = readl(mmio + HOST_IRQ_STAT); @@ -1494,6 +1496,7 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance) irq_stat = readl(mmio + HOST_IRQ_STAT); spin_unlock(&host->lock); } while (irq_stat); + VPRINTK("EXIT\n"); return IRQ_RETVAL(handled); } @@ -1657,7 +1660,7 @@ static ssize_t remapped_nvme_show(struct device *dev, struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; - return sysfs_emit(buf, "%u\n", hpriv->remapped_nvme); + return sprintf(buf, "%u\n", hpriv->remapped_nvme); } static DEVICE_ATTR_RO(remapped_nvme); @@ -1673,6 +1676,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) int n_ports, i, rc; int ahci_pci_bar = AHCI_PCI_BAR_STANDARD; + VPRINTK("ENTER\n"); + WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS); ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index eeac5482f1..2e89499bd9 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -376,8 +376,8 @@ struct ahci_host_priv { extern int ahci_ignore_sss; -extern const struct attribute_group *ahci_shost_groups[]; -extern const struct attribute_group *ahci_sdev_groups[]; +extern struct device_attribute *ahci_shost_attrs[]; +extern struct device_attribute *ahci_sdev_attrs[]; /* * This must be instantiated by the edge drivers. Read the comments @@ -388,8 +388,8 @@ extern const struct attribute_group *ahci_sdev_groups[]; .can_queue = AHCI_MAX_CMDS, \ .sg_tablesize = AHCI_MAX_SG, \ .dma_boundary = AHCI_DMA_BOUNDARY, \ - .shost_groups = ahci_shost_groups, \ - .sdev_groups = ahci_sdev_groups, \ + .shost_attrs = ahci_shost_attrs, \ + .sdev_attrs = ahci_sdev_attrs, \ .change_queue_depth = ata_scsi_change_queue_depth, \ .tag_alloc_policy = BLK_TAG_ALLOC_RR, \ .slave_configure = ata_scsi_slave_config diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 64dd8aa397..6e9c5ade4c 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -246,7 +246,7 @@ static void brcm_sata_init(struct brcm_ahci_priv *priv) } static unsigned int brcm_ahci_read_id(struct ata_device *dev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { struct ata_port *ap = dev->link->ap; struct ata_host *host = ap->host; @@ -333,7 +333,7 @@ static struct ata_port_operations ahci_brcm_platform_ops = { static const struct ata_port_info ahci_brcm_port_info = { .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, - .link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY, + .link_flags = ATA_LFLAG_NO_DB_DELAY, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_brcm_platform_ops, diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c index acf59f51b3..50b56cd003 100644 --- a/drivers/ata/ahci_ceva.c +++ b/drivers/ata/ahci_ceva.c @@ -92,7 +92,7 @@ struct ceva_ahci_priv { }; static unsigned int ceva_ahci_read_id(struct ata_device *dev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { u32 err_mask; diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index bf5b388bd4..5b46fc9aeb 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -103,6 +103,8 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, int rc; bool ls1021a_workaround = (qoriq_priv->type == AHCI_LS1021A); + DPRINTK("ENTER\n"); + hpriv->stop_engine(ap); /* @@ -144,6 +146,8 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, if (online) *class = ahci_dev_classify(ap); + + DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); return rc; } diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 8e206379d6..dffc432b9d 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -193,7 +193,7 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) struct xgene_ahci_context *ctx = hpriv->plat_data; int rc = 0; u32 port_fbs; - void __iomem *port_mmio = ahci_port_base(ap); + void *port_mmio = ahci_port_base(ap); /* * Write the pmp value to PxFBS.DEV @@ -237,7 +237,7 @@ static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx) * does not support DEVSLP. */ static unsigned int xgene_ahci_read_id(struct ata_device *dev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { u32 err_mask; @@ -454,7 +454,7 @@ static int xgene_ahci_pmp_softreset(struct ata_link *link, unsigned int *class, int pmp = sata_srst_pmp(link); struct ata_port *ap = link->ap; u32 rc; - void __iomem *port_mmio = ahci_port_base(ap); + void *port_mmio = ahci_port_base(ap); u32 port_fbs; /* @@ -499,7 +499,7 @@ static int xgene_ahci_softreset(struct ata_link *link, unsigned int *class, struct ata_port *ap = link->ap; struct ahci_host_priv *hpriv = ap->host->private_data; struct xgene_ahci_context *ctx = hpriv->plat_data; - void __iomem *port_mmio = ahci_port_base(ap); + void *port_mmio = ahci_port_base(ap); u32 port_fbs; u32 port_fbs_save; u32 retry = 1; @@ -588,6 +588,8 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance) void __iomem *mmio; u32 irq_stat, irq_masked; + VPRINTK("ENTER\n"); + hpriv = host->private_data; mmio = hpriv->mmio; @@ -610,6 +612,8 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance) spin_unlock(&host->lock); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(rc); } diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 27b0d903f9..3ca7720e7d 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -77,7 +77,6 @@ #include #include #include -#include #define DRV_NAME "ata_piix" #define DRV_VERSION "2.13" @@ -817,15 +816,10 @@ static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, static bool piix_irq_check(struct ata_port *ap) { - unsigned char host_stat; - if (unlikely(!ap->ioaddr.bmdma_addr)) return false; - host_stat = ap->ops->bmdma_status(ap); - trace_ata_bmdma_status(ap, host_stat); - - return host_stat & ATA_DMA_INTR; + return ap->ops->bmdma_status(ap) & ATA_DMA_INTR; } #ifdef CONFIG_PM_SLEEP @@ -1091,16 +1085,14 @@ static struct ata_port_operations ich_pata_ops = { .set_dmamode = ich_set_dmamode, }; -static struct attribute *piix_sidpr_shost_attrs[] = { - &dev_attr_link_power_management_policy.attr, +static struct device_attribute *piix_sidpr_shost_attrs[] = { + &dev_attr_link_power_management_policy, NULL }; -ATTRIBUTE_GROUPS(piix_sidpr_shost); - static struct scsi_host_template piix_sidpr_sht = { ATA_BMDMA_SHT(DRV_NAME), - .shost_groups = piix_sidpr_shost_groups, + .shost_attrs = piix_sidpr_shost_attrs, }; static struct ata_port_operations piix_sidpr_sata_ops = { @@ -1351,6 +1343,7 @@ static void piix_init_pcs(struct ata_host *host, new_pcs = pcs | map_db->port_enable; if (new_pcs != pcs) { + DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs); pci_write_config_word(pdev, ICH5_PCS, new_pcs); msleep(150); } @@ -1774,12 +1767,14 @@ static int __init piix_init(void) { int rc; + DPRINTK("pci_register_driver\n"); rc = pci_register_driver(&piix_pci_driver); if (rc) return rc; in_module_init = 0; + DPRINTK("done\n"); return 0; } diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 0ed484e04f..395772fa39 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -108,46 +108,28 @@ static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, ahci_read_em_buffer, ahci_store_em_buffer); static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); -static struct attribute *ahci_shost_attrs[] = { - &dev_attr_link_power_management_policy.attr, - &dev_attr_em_message_type.attr, - &dev_attr_em_message.attr, - &dev_attr_ahci_host_caps.attr, - &dev_attr_ahci_host_cap2.attr, - &dev_attr_ahci_host_version.attr, - &dev_attr_ahci_port_cmd.attr, - &dev_attr_em_buffer.attr, - &dev_attr_em_message_supported.attr, +struct device_attribute *ahci_shost_attrs[] = { + &dev_attr_link_power_management_policy, + &dev_attr_em_message_type, + &dev_attr_em_message, + &dev_attr_ahci_host_caps, + &dev_attr_ahci_host_cap2, + &dev_attr_ahci_host_version, + &dev_attr_ahci_port_cmd, + &dev_attr_em_buffer, + &dev_attr_em_message_supported, NULL }; +EXPORT_SYMBOL_GPL(ahci_shost_attrs); -static const struct attribute_group ahci_shost_attr_group = { - .attrs = ahci_shost_attrs -}; - -const struct attribute_group *ahci_shost_groups[] = { - &ahci_shost_attr_group, +struct device_attribute *ahci_sdev_attrs[] = { + &dev_attr_sw_activity, + &dev_attr_unload_heads, + &dev_attr_ncq_prio_supported, + &dev_attr_ncq_prio_enable, NULL }; -EXPORT_SYMBOL_GPL(ahci_shost_groups); - -static struct attribute *ahci_sdev_attrs[] = { - &dev_attr_sw_activity.attr, - &dev_attr_unload_heads.attr, - &dev_attr_ncq_prio_supported.attr, - &dev_attr_ncq_prio_enable.attr, - NULL -}; - -static const struct attribute_group ahci_sdev_attr_group = { - .attrs = ahci_sdev_attrs -}; - -const struct attribute_group *ahci_sdev_groups[] = { - &ahci_sdev_attr_group, - NULL -}; -EXPORT_SYMBOL_GPL(ahci_sdev_groups); +EXPORT_SYMBOL_GPL(ahci_sdev_attrs); struct ata_port_operations ahci_ops = { .inherits = &sata_pmp_port_ops, @@ -1234,12 +1216,12 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap, /* clear SError */ tmp = readl(port_mmio + PORT_SCR_ERR); - dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp); + VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); writel(tmp, port_mmio + PORT_SCR_ERR); /* clear port IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); - dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp); + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); if (tmp) writel(tmp, port_mmio + PORT_IRQ_STAT); @@ -1270,10 +1252,10 @@ void ahci_init_controller(struct ata_host *host) } tmp = readl(mmio + HOST_CTL); - dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); + VPRINTK("HOST_CTL 0x%x\n", tmp); writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); tmp = readl(mmio + HOST_CTL); - dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp); + VPRINTK("HOST_CTL 0x%x\n", tmp); } EXPORT_SYMBOL_GPL(ahci_init_controller); @@ -1300,7 +1282,7 @@ unsigned int ahci_dev_classify(struct ata_port *ap) tf.lbal = (tmp >> 8) & 0xff; tf.nsect = (tmp) & 0xff; - return ata_port_classify(ap, &tf); + return ata_dev_classify(&tf); } EXPORT_SYMBOL_GPL(ahci_dev_classify); @@ -1415,6 +1397,8 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, bool fbs_disabled = false; int rc; + DPRINTK("ENTER\n"); + /* prepare for SRST (AHCI-1.1 10.4.1) */ rc = ahci_kick_engine(ap); if (rc && rc != -EOPNOTSUPP) @@ -1474,6 +1458,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, if (fbs_disabled) ahci_enable_fbs(ap); + DPRINTK("EXIT, class=%u\n", *class); return 0; fail: @@ -1495,6 +1480,8 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, { int pmp = sata_srst_pmp(link); + DPRINTK("ENTER\n"); + return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); } EXPORT_SYMBOL_GPL(ahci_do_softreset); @@ -1524,6 +1511,8 @@ static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class, int rc; u32 irq_sts; + DPRINTK("ENTER\n"); + rc = ahci_do_softreset(link, class, pmp, deadline, ahci_bad_pmp_check_ready); @@ -1557,6 +1546,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, struct ata_taskfile tf; int rc; + DPRINTK("ENTER\n"); + hpriv->stop_engine(ap); /* clear D2H reception area to properly wait for D2H FIS */ @@ -1572,6 +1563,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, if (*online) *class = ahci_dev_classify(ap); + DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); return rc; } EXPORT_SYMBOL_GPL(ahci_do_hardreset); @@ -1610,6 +1602,8 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) struct ahci_sg *ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; unsigned int si; + VPRINTK("ENTER\n"); + /* * Next, the S/G list. */ @@ -1683,6 +1677,7 @@ static void ahci_fbs_dec_intr(struct ata_port *ap) u32 fbs = readl(port_mmio + PORT_FBS); int retries = 3; + DPRINTK("ENTER\n"); BUG_ON(!pp->fbs_enabled); /* time to wait for DEC is not specified by AHCI spec, @@ -1911,6 +1906,8 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance) void __iomem *port_mmio = ahci_port_base(ap); u32 status; + VPRINTK("ENTER\n"); + status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); @@ -1918,6 +1915,8 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance) ahci_handle_port_interrupt(ap, port_mmio, status); spin_unlock(ap->lock); + VPRINTK("EXIT\n"); + return IRQ_HANDLED; } @@ -1934,7 +1933,9 @@ u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) ap = host->ports[i]; if (ap) { ahci_port_intr(ap); + VPRINTK("port %u\n", i); } else { + VPRINTK("port %u (no irq)\n", i); if (ata_ratelimit()) dev_warn(host->dev, "interrupt on disabled port %u\n", i); @@ -1955,6 +1956,8 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) void __iomem *mmio; u32 irq_stat, irq_masked; + VPRINTK("ENTER\n"); + hpriv = host->private_data; mmio = hpriv->mmio; @@ -1982,6 +1985,8 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) spin_unlock(&host->lock); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(rc); } diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 18296443cc..0910441321 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -579,8 +579,11 @@ int ahci_platform_init_host(struct platform_device *pdev, int i, irq, n_ports, rc; irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + if (irq != -EPROBE_DEFER) + dev_err(dev, "no irq\n"); return irq; + } if (!irq) return -EINVAL; @@ -639,8 +642,13 @@ int ahci_platform_init_host(struct platform_device *pdev, if (hpriv->cap & HOST_CAP_64) { rc = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); if (rc) { - dev_err(dev, "Failed to enable 64-bit DMA.\n"); - return rc; + rc = dma_coerce_mask_and_coherent(dev, + DMA_BIT_MASK(32)); + if (rc) { + dev_err(dev, "Failed to enable 64-bit DMA.\n"); + return rc; + } + dev_warn(dev, "Enable 32-bit DMA instead of 64-bit.\n"); } } diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 8cfa8c96bb..7a7d6642ed 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -402,6 +402,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm); */ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) { + struct ata_port *ap = dev->link->ap; acpi_status status; struct acpi_buffer output; union acpi_object *out_obj; @@ -417,6 +418,10 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) output.length = ACPI_ALLOCATE_BUFFER; output.pointer = NULL; /* ACPI-CA sets this; save/free it later */ + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: ENTER: port#: %d\n", + __func__, ap->port_no); + /* _GTF has no input parameters */ status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_GTF", NULL, &output); @@ -432,9 +437,11 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) } if (!output.length || !output.pointer) { - ata_dev_dbg(dev, "Run _GTF: length or ptr is NULL (0x%llx, 0x%p)\n", - (unsigned long long)output.length, - output.pointer); + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: Run _GTF: length or ptr is NULL (0x%llx, 0x%p)\n", + __func__, + (unsigned long long)output.length, + output.pointer); rc = -EINVAL; goto out_free; } @@ -457,8 +464,9 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) rc = out_obj->buffer.length / REGS_PER_GTF; if (gtf) { *gtf = (void *)out_obj->buffer.pointer; - ata_dev_dbg(dev, "returning gtf=%p, gtf_count=%d\n", - *gtf, rc); + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: returning gtf=%p, gtf_count=%d\n", + __func__, *gtf, rc); } return rc; @@ -642,7 +650,9 @@ static int ata_acpi_run_tf(struct ata_device *dev, struct ata_taskfile *pptf = NULL; struct ata_taskfile tf, ptf, rtf; unsigned int err_mask; + const char *level; const char *descr; + char msg[60]; int rc; if ((gtf->tf[0] == 0) && (gtf->tf[1] == 0) && (gtf->tf[2] == 0) @@ -656,8 +666,6 @@ static int ata_acpi_run_tf(struct ata_device *dev, pptf = &ptf; } - descr = ata_get_cmd_name(tf.command); - if (!ata_acpi_filter_tf(dev, &tf, pptf)) { rtf = tf; err_mask = ata_exec_internal(dev, &rtf, NULL, @@ -665,42 +673,40 @@ static int ata_acpi_run_tf(struct ata_device *dev, switch (err_mask) { case 0: - ata_dev_dbg(dev, - "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x" - "(%s) succeeded\n", - tf.command, tf.feature, tf.nsect, tf.lbal, - tf.lbam, tf.lbah, tf.device, descr); + level = KERN_DEBUG; + snprintf(msg, sizeof(msg), "succeeded"); rc = 1; break; case AC_ERR_DEV: - ata_dev_info(dev, - "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x" - "(%s) rejected by device (Stat=0x%02x Err=0x%02x)", - tf.command, tf.feature, tf.nsect, tf.lbal, - tf.lbam, tf.lbah, tf.device, descr, - rtf.command, rtf.feature); + level = KERN_INFO; + snprintf(msg, sizeof(msg), + "rejected by device (Stat=0x%02x Err=0x%02x)", + rtf.command, rtf.feature); rc = 0; break; default: - ata_dev_err(dev, - "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x" - "(%s) failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", - tf.command, tf.feature, tf.nsect, tf.lbal, - tf.lbam, tf.lbah, tf.device, descr, - err_mask, rtf.command, rtf.feature); + level = KERN_ERR; + snprintf(msg, sizeof(msg), + "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", + err_mask, rtf.command, rtf.feature); rc = -EIO; break; } } else { - ata_dev_info(dev, - "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x" - "(%s) filtered out\n", - tf.command, tf.feature, tf.nsect, tf.lbal, - tf.lbam, tf.lbah, tf.device, descr); + level = KERN_INFO; + snprintf(msg, sizeof(msg), "filtered out"); rc = 0; } + descr = ata_get_cmd_descript(tf.command); + + ata_dev_printk(dev, level, + "ACPI cmd %02x/%02x:%02x:%02x:%02x:%02x:%02x (%s) %s\n", + tf.command, tf.feature, tf.nsect, tf.lbal, + tf.lbam, tf.lbah, tf.device, + (descr ? descr : "unknown"), msg); + return rc; } @@ -770,8 +776,9 @@ static int ata_acpi_push_id(struct ata_device *dev) struct acpi_object_list input; union acpi_object in_params[1]; - ata_dev_dbg(dev, "%s: ix = %d, port#: %d\n", - __func__, dev->devno, ap->port_no); + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: ix = %d, port#: %d\n", + __func__, dev->devno, ap->port_no); /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0c854aebfe..24b67d78cb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -764,6 +764,9 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, head = track % dev->heads; sect = (u32)block % dev->sectors + 1; + DPRINTK("block %u track %u cyl %u head %u sect %u\n", + (u32)block, track, cyl, head, sect); + /* Check whether the converted CHS can fit. Cylinder: 0-65535 Head: 0-15 @@ -1007,21 +1010,32 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) * SEMB signature. This is worked around in * ata_dev_read_id(). */ - if (tf->lbam == 0 && tf->lbah == 0) + if ((tf->lbam == 0) && (tf->lbah == 0)) { + DPRINTK("found ATA device by sig\n"); return ATA_DEV_ATA; + } - if (tf->lbam == 0x14 && tf->lbah == 0xeb) + if ((tf->lbam == 0x14) && (tf->lbah == 0xeb)) { + DPRINTK("found ATAPI device by sig\n"); return ATA_DEV_ATAPI; + } - if (tf->lbam == 0x69 && tf->lbah == 0x96) + if ((tf->lbam == 0x69) && (tf->lbah == 0x96)) { + DPRINTK("found PMP device by sig\n"); return ATA_DEV_PMP; + } - if (tf->lbam == 0x3c && tf->lbah == 0xc3) + if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { + DPRINTK("found SEMB device by sig (could be ATA device)\n"); return ATA_DEV_SEMB; + } - if (tf->lbam == 0xcd && tf->lbah == 0xab) + if ((tf->lbam == 0xcd) && (tf->lbah == 0xab)) { + DPRINTK("found ZAC device by sig\n"); return ATA_DEV_ZAC; + } + DPRINTK("unknown device\n"); return ATA_DEV_UNKNOWN; } EXPORT_SYMBOL_GPL(ata_dev_classify); @@ -1341,7 +1355,6 @@ static int ata_hpa_resize(struct ata_device *dev) /** * ata_dump_id - IDENTIFY DEVICE info debugging output - * @dev: device from which the information is fetched * @id: IDENTIFY DEVICE page to dump * * Dump selected 16-bit words from the given IDENTIFY DEVICE @@ -1351,14 +1364,32 @@ static int ata_hpa_resize(struct ata_device *dev) * caller. */ -static inline void ata_dump_id(struct ata_device *dev, const u16 *id) +static inline void ata_dump_id(const u16 *id) { - ata_dev_dbg(dev, - "49==0x%04x 53==0x%04x 63==0x%04x 64==0x%04x 75==0x%04x\n" - "80==0x%04x 81==0x%04x 82==0x%04x 83==0x%04x 84==0x%04x\n" - "88==0x%04x 93==0x%04x\n", - id[49], id[53], id[63], id[64], id[75], id[80], - id[81], id[82], id[83], id[84], id[88], id[93]); + DPRINTK("49==0x%04x " + "53==0x%04x " + "63==0x%04x " + "64==0x%04x " + "75==0x%04x \n", + id[49], + id[53], + id[63], + id[64], + id[75]); + DPRINTK("80==0x%04x " + "81==0x%04x " + "82==0x%04x " + "83==0x%04x " + "84==0x%04x \n", + id[80], + id[81], + id[82], + id[83], + id[84]); + DPRINTK("88==0x%04x " + "93==0x%04x\n", + id[88], + id[93]); } /** @@ -1571,8 +1602,9 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, else ata_qc_complete(qc); - ata_dev_warn(dev, "qc timeout (cmd 0x%x)\n", - command); + if (ata_msg_warn(ap)) + ata_dev_warn(dev, "qc timeout (cmd 0x%x)\n", + command); } spin_unlock_irqrestore(ap->lock, flags); @@ -1722,7 +1754,7 @@ static u32 ata_pio_mask_no_iordy(const struct ata_device *adev) * this function is wrapped or replaced by the driver */ unsigned int ata_do_dev_read_id(struct ata_device *dev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { return ata_exec_internal(dev, tf, NULL, DMA_FROM_DEVICE, id, sizeof(id[0]) * ATA_ID_WORDS, 0); @@ -1762,6 +1794,9 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int may_fallback = 1, tried_spinup = 0; int rc; + if (ata_msg_ctl(ap)) + ata_dev_dbg(dev, "%s: ENTER\n", __func__); + retry: ata_tf_init(dev, &tf); @@ -1795,9 +1830,9 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, tf.flags |= ATA_TFLAG_POLLING; if (ap->ops->read_id) - err_mask = ap->ops->read_id(dev, &tf, (__le16 *)id); + err_mask = ap->ops->read_id(dev, &tf, id); else - err_mask = ata_do_dev_read_id(dev, &tf, (__le16 *)id); + err_mask = ata_do_dev_read_id(dev, &tf, id); if (err_mask) { if (err_mask & AC_ERR_NODEV_HINT) { @@ -1844,10 +1879,10 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, } if (dev->horkage & ATA_HORKAGE_DUMP_ID) { - ata_dev_info(dev, "dumping IDENTIFY data, " + ata_dev_dbg(dev, "dumping IDENTIFY data, " "class=%d may_fallback=%d tried_spinup=%d\n", class, may_fallback, tried_spinup); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 2, id, ATA_ID_WORDS * sizeof(*id), true); } @@ -1931,8 +1966,9 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, return 0; err_out: - ata_dev_warn(dev, "failed to IDENTIFY (%s, err_mask=0x%x)\n", - reason, err_mask); + if (ata_msg_warn(ap)) + ata_dev_warn(dev, "failed to IDENTIFY (%s, err_mask=0x%x)\n", + reason, err_mask); return rc; } @@ -1960,7 +1996,7 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, unsigned int err_mask; bool dma = false; - ata_dev_dbg(dev, "read log page - log 0x%x, page 0x%x\n", log, page); + DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page); /* * Return error without actually issuing the command on controllers @@ -2007,9 +2043,6 @@ static bool ata_log_supported(struct ata_device *dev, u8 log) { struct ata_port *ap = dev->link->ap; - if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR) - return false; - if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) return false; return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; @@ -2020,19 +2053,8 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page) struct ata_port *ap = dev->link->ap; unsigned int err, i; - if (dev->horkage & ATA_HORKAGE_NO_ID_DEV_LOG) - return false; - if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE)) { - /* - * IDENTIFY DEVICE data log is defined as mandatory starting - * with ACS-3 (ATA version 10). Warn about the missing log - * for drives which implement this ATA level or above. - */ - if (ata_id_major_version(dev->id) >= 10) - ata_dev_warn(dev, - "ATA Identify Device Log not supported\n"); - dev->horkage |= ATA_HORKAGE_NO_ID_DEV_LOG; + ata_dev_warn(dev, "ATA Identify Device Log not supported\n"); return false; } @@ -2357,6 +2379,7 @@ static void ata_dev_config_trusted(struct ata_device *dev) static int ata_dev_config_lba(struct ata_device *dev) { + struct ata_port *ap = dev->link->ap; const u16 *id = dev->id; const char *lba_desc; char ncq_desc[24]; @@ -2378,7 +2401,7 @@ static int ata_dev_config_lba(struct ata_device *dev) ret = ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); /* print device info to dmesg */ - if (ata_dev_print_info(dev)) + if (ata_msg_drv(ap) && ata_dev_print_info(dev)) ata_dev_info(dev, "%llu sectors, multi %u: %s %s\n", (unsigned long long)dev->n_sectors, @@ -2389,6 +2412,7 @@ static int ata_dev_config_lba(struct ata_device *dev) static void ata_dev_config_chs(struct ata_device *dev) { + struct ata_port *ap = dev->link->ap; const u16 *id = dev->id; if (ata_id_current_chs_valid(id)) { @@ -2404,7 +2428,7 @@ static void ata_dev_config_chs(struct ata_device *dev) } /* print device info to dmesg */ - if (ata_dev_print_info(dev)) + if (ata_msg_drv(ap) && ata_dev_print_info(dev)) ata_dev_info(dev, "%llu sectors, multi %u, CHS %u/%u/%u\n", (unsigned long long)dev->n_sectors, @@ -2440,68 +2464,18 @@ static void ata_dev_config_devslp(struct ata_device *dev) } } -static void ata_dev_config_cpr(struct ata_device *dev) -{ - unsigned int err_mask; - size_t buf_len; - int i, nr_cpr = 0; - struct ata_cpr_log *cpr_log = NULL; - u8 *desc, *buf = NULL; - - if (ata_id_major_version(dev->id) < 11 || - !ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES)) - goto out; - - /* - * Read the concurrent positioning ranges log (0x47). We can have at - * most 255 32B range descriptors plus a 64B header. - */ - buf_len = (64 + 255 * 32 + 511) & ~511; - buf = kzalloc(buf_len, GFP_KERNEL); - if (!buf) - goto out; - - err_mask = ata_read_log_page(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES, - 0, buf, buf_len >> 9); - if (err_mask) - goto out; - - nr_cpr = buf[0]; - if (!nr_cpr) - goto out; - - cpr_log = kzalloc(struct_size(cpr_log, cpr, nr_cpr), GFP_KERNEL); - if (!cpr_log) - goto out; - - cpr_log->nr_cpr = nr_cpr; - desc = &buf[64]; - for (i = 0; i < nr_cpr; i++, desc += 32) { - cpr_log->cpr[i].num = desc[0]; - cpr_log->cpr[i].num_storage_elements = desc[1]; - cpr_log->cpr[i].start_lba = get_unaligned_le64(&desc[8]); - cpr_log->cpr[i].num_lbas = get_unaligned_le64(&desc[16]); - } - -out: - swap(dev->cpr_log, cpr_log); - kfree(cpr_log); - kfree(buf); -} - static void ata_dev_print_features(struct ata_device *dev) { if (!(dev->flags & ATA_DFLAG_FEATURES_MASK)) return; ata_dev_info(dev, - "Features:%s%s%s%s%s%s\n", + "Features:%s%s%s%s%s\n", dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "", dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "", dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "", dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "", - dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "", - dev->cpr_log ? " CPR" : ""); + dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : ""); } /** @@ -2529,11 +2503,14 @@ int ata_dev_configure(struct ata_device *dev) char modelbuf[ATA_ID_PROD_LEN+1]; int rc; - if (!ata_dev_enabled(dev)) { - ata_dev_dbg(dev, "no device\n"); + if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { + ata_dev_info(dev, "%s: ENTER/EXIT -- nodev\n", __func__); return 0; } + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: ENTER\n", __func__); + /* set horkage */ dev->horkage |= ata_dev_blacklisted(dev); ata_force_horkage(dev); @@ -2581,12 +2558,13 @@ int ata_dev_configure(struct ata_device *dev) return rc; /* print device capabilities */ - ata_dev_dbg(dev, - "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " - "85:%04x 86:%04x 87:%04x 88:%04x\n", - __func__, - id[49], id[82], id[83], id[84], - id[85], id[86], id[87], id[88]); + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, + "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " + "85:%04x 86:%04x 87:%04x 88:%04x\n", + __func__, + id[49], id[82], id[83], id[84], + id[85], id[86], id[87], id[88]); /* initialize to-be-configured parameters */ dev->flags &= ~ATA_DFLAG_CFG_MASK; @@ -2605,7 +2583,8 @@ int ata_dev_configure(struct ata_device *dev) /* find max transfer mode; for printk only */ xfer_mask = ata_id_xfermask(id); - ata_dump_id(dev, id); + if (ata_msg_probe(ap)) + ata_dump_id(id); /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV, @@ -2643,7 +2622,7 @@ int ata_dev_configure(struct ata_device *dev) } /* print device info to dmesg */ - if (print_info) + if (ata_msg_drv(ap) && print_info) ata_dev_info(dev, "%s: %s, %s, max %s\n", revbuf, modelbuf, fwrevbuf, ata_mode_string(xfer_mask)); @@ -2660,10 +2639,9 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_config_sense_reporting(dev); ata_dev_config_zac(dev); ata_dev_config_trusted(dev); - ata_dev_config_cpr(dev); dev->cdb_len = 32; - if (print_info) + if (ata_msg_drv(ap) && print_info) ata_dev_print_features(dev); } @@ -2676,7 +2654,8 @@ int ata_dev_configure(struct ata_device *dev) rc = atapi_cdb_len(id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { - ata_dev_warn(dev, "unsupported CDB len %d\n", rc); + if (ata_msg_warn(ap)) + ata_dev_warn(dev, "unsupported CDB len\n"); rc = -EINVAL; goto err_out_nosup; } @@ -2720,7 +2699,7 @@ int ata_dev_configure(struct ata_device *dev) } /* print device info to dmesg */ - if (print_info) + if (ata_msg_drv(ap) && print_info) ata_dev_info(dev, "ATAPI: %s, %s, max %s%s%s%s\n", modelbuf, fwrevbuf, @@ -2737,7 +2716,7 @@ int ata_dev_configure(struct ata_device *dev) /* Limit PATA drive on SATA cable bridge transfers to udma5, 200 sectors */ if (ata_dev_knobble(dev)) { - if (print_info) + if (ata_msg_drv(ap) && print_info) ata_dev_info(dev, "applying bridge limits\n"); dev->udma_mask &= ATA_UDMA5; dev->max_sectors = ATA_MAX_SECTORS; @@ -2786,6 +2765,8 @@ int ata_dev_configure(struct ata_device *dev) return 0; err_out_nosup: + if (ata_msg_probe(ap)) + ata_dev_dbg(dev, "%s: EXIT, err\n", __func__); return rc; } @@ -3328,8 +3309,8 @@ static int ata_dev_set_mode(struct ata_device *dev) dev_err_whine = " (device error ignored)"; } - ata_dev_dbg(dev, "xfer_shift=%u, xfer_mode=0x%x\n", - dev->xfer_shift, (int)dev->xfer_mode); + DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", + dev->xfer_shift, (int)dev->xfer_mode); if (!(ehc->i.flags & ATA_EHI_QUIET) || ehc->i.flags & ATA_EHI_DID_HARDRESET) @@ -3643,12 +3624,16 @@ void ata_std_postreset(struct ata_link *link, unsigned int *classes) { u32 serror; + DPRINTK("ENTER\n"); + /* reset complete, clear SError */ if (!sata_scr_read(link, SCR_ERROR, &serror)) sata_scr_write(link, SCR_ERROR, serror); /* print link status */ sata_print_link_status(link); + + DPRINTK("EXIT\n"); } EXPORT_SYMBOL_GPL(ata_std_postreset); @@ -4075,13 +4060,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "WDC WD3000JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, { "WDC WD3200JD-*", NULL, ATA_HORKAGE_WD_BROKEN_LPM }, - /* - * This sata dom device goes on a walkabout when the ATA_LOG_DIRECTORY - * log page is accessed. Ensure we never ask for this log page with - * these devices. - */ - { "SATADOM-ML 3ME", NULL, ATA_HORKAGE_NO_LOG_DIR }, - /* End Marker */ { } }; @@ -4283,7 +4261,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) unsigned int err_mask; /* set up set-features taskfile */ - ata_dev_dbg(dev, "set features - xfer mode\n"); + DPRINTK("set features - xfer mode\n"); /* Some controllers and ATAPI devices show flaky interrupt * behavior after setting xfer mode. Use polling instead. @@ -4305,6 +4283,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev) /* On some disks, this command causes spin-up, so we need longer timeout */ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000); + DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; } @@ -4330,7 +4309,7 @@ unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature) unsigned long timeout = 0; /* set up set-features taskfile */ - ata_dev_dbg(dev, "set features - SATA features\n"); + DPRINTK("set features - SATA features\n"); ata_tf_init(dev, &tf); tf.command = ATA_CMD_SET_FEATURES; @@ -4344,6 +4323,7 @@ unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable, u8 feature) ata_probe_timeout * 1000 : SETFEATURES_SPINUP_TIMEOUT; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, timeout); + DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; } EXPORT_SYMBOL_GPL(ata_dev_set_feature); @@ -4371,7 +4351,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, return AC_ERR_INVALID; /* set up init dev params taskfile */ - ata_dev_dbg(dev, "init dev params \n"); + DPRINTK("init dev params \n"); ata_tf_init(dev, &tf); tf.command = ATA_CMD_INIT_DEV_PARAMS; @@ -4387,6 +4367,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED)) err_mask = 0; + DPRINTK("EXIT, err_mask=%x\n", err_mask); return err_mask; } @@ -4498,6 +4479,8 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) WARN_ON_ONCE(sg == NULL); + VPRINTK("unmapping %u sg elements\n", qc->n_elem); + if (qc->n_elem) dma_unmap_sg(ap->dev, sg, qc->orig_n_elem, dir); @@ -4523,10 +4506,13 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; unsigned int n_elem; + VPRINTK("ENTER, ata%u\n", ap->print_id); + n_elem = dma_map_sg(ap->dev, qc->sg, qc->n_elem, qc->dma_dir); if (n_elem < 1) return -1; + VPRINTK("%d sg elements mapped\n", n_elem); qc->orig_n_elem = qc->n_elem; qc->n_elem = n_elem; qc->flags |= ATA_QCFLAG_DMAMAP; @@ -4881,7 +4867,6 @@ void ata_qc_issue(struct ata_queued_cmd *qc) return; } - trace_ata_qc_prep(qc); qc->err_mask |= ap->ops->qc_prep(qc); if (unlikely(qc->err_mask)) goto err; @@ -5327,6 +5312,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host) { struct ata_port *ap; + DPRINTK("ENTER\n"); + ap = kzalloc(sizeof(*ap), GFP_KERNEL); if (!ap) return NULL; @@ -5338,6 +5325,15 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->host = host; ap->dev = host->dev; +#if defined(ATA_VERBOSE_DEBUG) + /* turn on all debugging levels */ + ap->msg_enable = 0x00FF; +#elif defined(ATA_DEBUG) + ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR; +#else + ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; +#endif + mutex_init(&ap->scsi_scan_mutex); INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); @@ -5434,6 +5430,8 @@ struct ata_host *ata_host_alloc(struct device *dev, int max_ports) int i; void *dr; + DPRINTK("ENTER\n"); + /* alloc a container for our list of ATA ports (buses) */ sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *); host = kzalloc(sz, GFP_KERNEL); @@ -5723,7 +5721,9 @@ int ata_port_probe(struct ata_port *ap) __ata_port_probe(ap); ata_port_wait_eh(ap); } else { + DPRINTK("ata%u: bus probe begin\n", ap->print_id); rc = ata_bus_probe(ap); + DPRINTK("ata%u: bus probe end\n", ap->print_id); } return rc; } @@ -6490,14 +6490,69 @@ const struct ata_port_info ata_dummy_port_info = { }; EXPORT_SYMBOL_GPL(ata_dummy_port_info); +/* + * Utility print functions + */ +void ata_port_printk(const struct ata_port *ap, const char *level, + const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + printk("%sata%u: %pV", level, ap->print_id, &vaf); + + va_end(args); +} +EXPORT_SYMBOL(ata_port_printk); + +void ata_link_printk(const struct ata_link *link, const char *level, + const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + if (sata_pmp_attached(link->ap) || link->ap->slave_link) + printk("%sata%u.%02u: %pV", + level, link->ap->print_id, link->pmp, &vaf); + else + printk("%sata%u: %pV", + level, link->ap->print_id, &vaf); + + va_end(args); +} +EXPORT_SYMBOL(ata_link_printk); + +void ata_dev_printk(const struct ata_device *dev, const char *level, + const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + printk("%sata%u.%02u: %pV", + level, dev->link->ap->print_id, dev->link->pmp + dev->devno, + &vaf); + + va_end(args); +} +EXPORT_SYMBOL(ata_dev_printk); + void ata_print_version(const struct device *dev, const char *version) { dev_printk(KERN_DEBUG, dev, "version %s\n", version); } EXPORT_SYMBOL(ata_print_version); - -EXPORT_TRACEPOINT_SYMBOL_GPL(ata_tf_load); -EXPORT_TRACEPOINT_SYMBOL_GPL(ata_exec_command); -EXPORT_TRACEPOINT_SYMBOL_GPL(ata_bmdma_setup); -EXPORT_TRACEPOINT_SYMBOL_GPL(ata_bmdma_start); -EXPORT_TRACEPOINT_SYMBOL_GPL(ata_bmdma_status); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7951fd946b..1d4a6f1e88 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -533,6 +533,8 @@ void ata_scsi_error(struct Scsi_Host *host) unsigned long flags; LIST_HEAD(eh_work_q); + DPRINTK("ENTER\n"); + spin_lock_irqsave(host->host_lock, flags); list_splice_init(&host->eh_cmd_q, &eh_work_q); spin_unlock_irqrestore(host->host_lock, flags); @@ -546,6 +548,7 @@ void ata_scsi_error(struct Scsi_Host *host) /* finish or retry handled scmd's and clean up */ WARN_ON(!list_empty(&eh_work_q)); + DPRINTK("EXIT\n"); } /** @@ -937,7 +940,7 @@ void ata_std_sched_eh(struct ata_port *ap) ata_eh_set_pending(ap, 1); scsi_schedule_eh(ap->scsi_host); - trace_ata_std_sched_eh(ap); + DPRINTK("port EH scheduled\n"); } EXPORT_SYMBOL_GPL(ata_std_sched_eh); @@ -1067,7 +1070,7 @@ static void __ata_port_freeze(struct ata_port *ap) ap->pflags |= ATA_PFLAG_FROZEN; - trace_ata_port_freeze(ap); + DPRINTK("ata%u port frozen\n", ap->print_id); } /** @@ -1144,7 +1147,7 @@ void ata_eh_thaw_port(struct ata_port *ap) spin_unlock_irqrestore(ap->lock, flags); - trace_ata_port_thaw(ap); + DPRINTK("ata%u port thawed\n", ap->print_id); } static void ata_eh_scsidone(struct scsi_cmnd *scmd) @@ -1214,7 +1217,8 @@ void ata_dev_disable(struct ata_device *dev) if (!ata_dev_enabled(dev)) return; - ata_dev_warn(dev, "disable device\n"); + if (ata_msg_drv(dev->link->ap)) + ata_dev_warn(dev, "disabled\n"); ata_acpi_on_disable(dev); ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET); dev->class++; @@ -1283,8 +1287,6 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, struct ata_eh_context *ehc = &link->eh_context; unsigned long flags; - trace_ata_eh_about_to_do(link, dev ? dev->devno : 0, action); - spin_lock_irqsave(ap->lock, flags); ata_eh_clear_action(link, dev, ehi, action); @@ -1315,8 +1317,6 @@ void ata_eh_done(struct ata_link *link, struct ata_device *dev, { struct ata_eh_context *ehc = &link->eh_context; - trace_ata_eh_done(link, dev ? dev->devno : 0, action); - ata_eh_clear_action(link, dev, &ehc->i, action); } @@ -1421,6 +1421,8 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc, return; } + DPRINTK("ATA request sense\n"); + ata_tf_init(dev, &tf); tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48; @@ -1461,6 +1463,8 @@ unsigned int atapi_eh_request_sense(struct ata_device *dev, struct ata_port *ap = dev->link->ap; struct ata_taskfile tf; + DPRINTK("ATAPI request sense\n"); + memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE); /* initialize sense_buf with the error register, @@ -1924,6 +1928,8 @@ static void ata_eh_link_autopsy(struct ata_link *link) u32 serror; int rc; + DPRINTK("ENTER\n"); + if (ehc->i.flags & ATA_EHI_NO_AUTOPSY) return; @@ -2030,6 +2036,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask); trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask); } + DPRINTK("EXIT\n"); } /** @@ -2079,15 +2086,16 @@ void ata_eh_autopsy(struct ata_port *ap) } /** - * ata_get_cmd_name - get name for ATA command - * @command: ATA command code to get name for + * ata_get_cmd_descript - get description for ATA command + * @command: ATA command code to get description for * - * Return a textual name of the given command or "unknown" + * Return a textual description of the given command, or NULL if the + * command is not known. * * LOCKING: * None */ -const char *ata_get_cmd_name(u8 command) +const char *ata_get_cmd_descript(u8 command) { #ifdef CONFIG_ATA_VERBOSE_ERROR static const struct @@ -2195,9 +2203,9 @@ const char *ata_get_cmd_name(u8 command) return cmd_descr[i].text; #endif - return "unknown"; + return NULL; } -EXPORT_SYMBOL_GPL(ata_get_cmd_name); +EXPORT_SYMBOL_GPL(ata_get_cmd_descript); /** * ata_eh_link_report - report error handling to user @@ -2346,9 +2354,12 @@ static void ata_eh_link_report(struct ata_link *link) } __scsi_format_command(cdb_buf, sizeof(cdb_buf), cdb, cdb_len); - } else - ata_dev_err(qc->dev, "failed command: %s\n", - ata_get_cmd_name(cmd->command)); + } else { + const char *descr = ata_get_cmd_descript(cmd->command); + if (descr) + ata_dev_err(qc->dev, "failed command: %s\n", + descr); + } ata_dev_err(qc->dev, "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " @@ -2585,19 +2596,12 @@ int ata_eh_reset(struct ata_link *link, int classify, /* mark that this EH session started with reset */ ehc->last_reset = jiffies; - if (reset == hardreset) { + if (reset == hardreset) ehc->i.flags |= ATA_EHI_DID_HARDRESET; - trace_ata_link_hardreset_begin(link, classes, deadline); - } else { + else ehc->i.flags |= ATA_EHI_DID_SOFTRESET; - trace_ata_link_softreset_begin(link, classes, deadline); - } rc = ata_do_reset(link, reset, classes, deadline, true); - if (reset == hardreset) - trace_ata_link_hardreset_end(link, classes, rc); - else - trace_ata_link_softreset_end(link, classes, rc); if (rc && rc != -EAGAIN) { failed_link = link; goto fail; @@ -2611,11 +2615,8 @@ int ata_eh_reset(struct ata_link *link, int classify, ata_link_info(slave, "hard resetting link\n"); ata_eh_about_to_do(slave, NULL, ATA_EH_RESET); - trace_ata_slave_hardreset_begin(slave, classes, - deadline); tmp = ata_do_reset(slave, reset, classes, deadline, false); - trace_ata_slave_hardreset_end(slave, classes, tmp); switch (tmp) { case -EAGAIN: rc = -EAGAIN; @@ -2643,9 +2644,7 @@ int ata_eh_reset(struct ata_link *link, int classify, } ata_eh_about_to_do(link, NULL, ATA_EH_RESET); - trace_ata_link_softreset_begin(link, classes, deadline); rc = ata_do_reset(link, reset, classes, deadline, true); - trace_ata_link_softreset_end(link, classes, rc); if (rc) { failed_link = link; goto fail; @@ -2699,11 +2698,8 @@ int ata_eh_reset(struct ata_link *link, int classify, */ if (postreset) { postreset(link, classes); - trace_ata_link_postreset(link, classes, rc); - if (slave) { + if (slave) postreset(slave, classes); - trace_ata_slave_postreset(slave, classes, rc); - } } /* @@ -2925,6 +2921,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, unsigned long flags; int rc = 0; + DPRINTK("ENTER\n"); + /* For PATA drive side cable detection to work, IDENTIFY must * be done backwards such that PDIAG- is released by the slave * device before the master device is identified. @@ -3038,6 +3036,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, err: *r_failed_dev = dev; + DPRINTK("EXIT rc=%d\n", rc); return rc; } @@ -3552,6 +3551,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, int rc, nr_fails; unsigned long flags, deadline; + DPRINTK("ENTER\n"); + /* prep for recovery */ ata_for_each_link(link, ap, EDGE) { struct ata_eh_context *ehc = &link->eh_context; @@ -3759,6 +3760,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, if (rc && r_failed_link) *r_failed_link = link; + DPRINTK("EXIT, rc=%d\n", rc); return rc; } diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index e2e9cbd405..ba7be3f386 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -652,6 +652,8 @@ static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) u32 *gscr = (void *)ap->sector_buf; int rc; + DPRINTK("ENTER\n"); + ata_eh_about_to_do(link, NULL, ATA_EH_REVALIDATE); if (!ata_dev_enabled(dev)) { @@ -684,10 +686,12 @@ static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) ata_eh_done(link, NULL, ATA_EH_REVALIDATE); + DPRINTK("EXIT, rc=0\n"); return 0; fail: ata_dev_err(dev, "PMP revalidation failed (errno=%d)\n", rc); + DPRINTK("EXIT, rc=%d\n", rc); return rc; } @@ -755,6 +759,8 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, int detach = 0, rc = 0; int reval_failed = 0; + DPRINTK("ENTER\n"); + if (dev->flags & ATA_DFLAG_DETACH) { detach = 1; rc = -ENODEV; @@ -822,6 +828,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, /* okay, PMP resurrected */ ehc->i.flags = 0; + DPRINTK("EXIT, rc=0\n"); return 0; fail: @@ -831,6 +838,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap, else ata_dev_disable(dev); + DPRINTK("EXIT, rc=%d\n", rc); return rc; } diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 071158c0c4..8f3ff830ab 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -317,7 +317,7 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params, * immediately after resuming. Delay 200ms before * debouncing. */ - if (!(link->flags & ATA_LFLAG_NO_DEBOUNCE_DELAY)) + if (!(link->flags & ATA_LFLAG_NO_DB_DELAY)) ata_msleep(link->ap, 200); /* is SControl restored correctly? */ @@ -533,6 +533,8 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, u32 scontrol; int rc; + DPRINTK("ENTER\n"); + if (online) *online = false; @@ -608,6 +610,7 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, *online = false; ata_link_err(link, "COMRESET failed (errno=%d)\n", rc); } + DPRINTK("EXIT, rc=%d\n", rc); return rc; } EXPORT_SYMBOL_GPL(sata_link_hardreset); @@ -824,7 +827,7 @@ static ssize_t ata_scsi_lpm_show(struct device *dev, if (ap->target_lpm_policy >= ARRAY_SIZE(ata_lpm_policy_names)) return -EINVAL; - return sysfs_emit(buf, "%s\n", + return snprintf(buf, PAGE_SIZE, "%s\n", ata_lpm_policy_names[ap->target_lpm_policy]); } DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR, @@ -873,7 +876,7 @@ static ssize_t ata_ncq_prio_enable_show(struct device *device, ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE; spin_unlock_irq(ap->lock); - return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_enable); + return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable); } static ssize_t ata_ncq_prio_enable_store(struct device *device, @@ -919,22 +922,13 @@ DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR, ata_ncq_prio_enable_show, ata_ncq_prio_enable_store); EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable); -static struct attribute *ata_ncq_sdev_attrs[] = { - &dev_attr_unload_heads.attr, - &dev_attr_ncq_prio_enable.attr, - &dev_attr_ncq_prio_supported.attr, +struct device_attribute *ata_ncq_sdev_attrs[] = { + &dev_attr_unload_heads, + &dev_attr_ncq_prio_enable, + &dev_attr_ncq_prio_supported, NULL }; - -static const struct attribute_group ata_ncq_sdev_attr_group = { - .attrs = ata_ncq_sdev_attrs -}; - -const struct attribute_group *ata_ncq_sdev_groups[] = { - &ata_ncq_sdev_attr_group, - NULL -}; -EXPORT_SYMBOL_GPL(ata_ncq_sdev_groups); +EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs); static ssize_t ata_scsi_em_message_store(struct device *dev, struct device_attribute *attr, @@ -969,7 +963,7 @@ ata_scsi_em_message_type_show(struct device *dev, struct device_attribute *attr, struct Scsi_Host *shost = class_to_shost(dev); struct ata_port *ap = ata_shost_to_port(shost); - return sysfs_emit(buf, "%d\n", ap->em_message_type); + return snprintf(buf, 23, "%d\n", ap->em_message_type); } DEVICE_ATTR(em_message_type, S_IRUGO, ata_scsi_em_message_type_show, NULL); @@ -1258,11 +1252,13 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) { int rc = 0; + ata_scsi_dump_cdb(ap, cmd); + if (likely(ata_dev_enabled(ap->link.device))) rc = __ata_scsi_queuecmd(cmd, ap->link.device); else { cmd->result = (DID_BAD_TARGET << 16); - scsi_done(cmd); + cmd->scsi_done(cmd); } return rc; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ed8be585a9..10303611d1 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -121,7 +121,7 @@ static ssize_t ata_scsi_park_show(struct device *device, unlock: spin_unlock_irq(ap->lock); - return rc ? rc : sysfs_emit(buf, "%u\n", msecs); + return rc ? rc : snprintf(buf, 20, "%u\n", msecs); } static ssize_t ata_scsi_park_store(struct device *device, @@ -234,20 +234,11 @@ static void ata_scsi_set_invalid_parameter(struct ata_device *dev, field, 0xff, 0); } -static struct attribute *ata_common_sdev_attrs[] = { - &dev_attr_unload_heads.attr, +struct device_attribute *ata_common_sdev_attrs[] = { + &dev_attr_unload_heads, NULL }; - -static const struct attribute_group ata_common_sdev_attr_group = { - .attrs = ata_common_sdev_attrs -}; - -const struct attribute_group *ata_common_sdev_groups[] = { - &ata_common_sdev_attr_group, - NULL -}; -EXPORT_SYMBOL_GPL(ata_common_sdev_groups); +EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); /** * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. @@ -643,7 +634,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc = ata_qc_new_init(dev, scsi_cmd_to_rq(cmd)->tag); if (qc) { qc->scsicmd = cmd; - qc->scsidone = scsi_done; + qc->scsidone = cmd->scsi_done; qc->sg = scsi_sglist(cmd); qc->n_elem = scsi_sg_count(cmd); @@ -652,7 +643,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc->flags |= ATA_QCFLAG_QUIET; } else { cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL; - scsi_done(cmd); + cmd->scsi_done(cmd); } return qc; @@ -668,7 +659,7 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) /** * ata_dump_status - user friendly display of error info - * @ap: the port in question + * @id: id of the port in question * @tf: ptr to filled out taskfile * * Decode and dump the ATA error/status registers for the user so @@ -678,32 +669,37 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) * LOCKING: * inherited from caller */ -static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf) +static void ata_dump_status(unsigned id, struct ata_taskfile *tf) { u8 stat = tf->command, err = tf->feature; + pr_warn("ata%u: status=0x%02x { ", id, stat); if (stat & ATA_BUSY) { - ata_port_warn(ap, "status=0x%02x {Busy} ", stat); + pr_cont("Busy }\n"); /* Data is not valid in this case */ } else { - ata_port_warn(ap, "status=0x%02x { %s%s%s%s%s%s%s} ", stat, - stat & ATA_DRDY ? "DriveReady " : "", - stat & ATA_DF ? "DeviceFault " : "", - stat & ATA_DSC ? "SeekComplete " : "", - stat & ATA_DRQ ? "DataRequest " : "", - stat & ATA_CORR ? "CorrectedError " : "", - stat & ATA_SENSE ? "Sense " : "", - stat & ATA_ERR ? "Error " : ""); - if (err) - ata_port_warn(ap, "error=0x%02x {%s%s%s%s%s%s", err, - err & ATA_ABORTED ? - "DriveStatusError " : "", - err & ATA_ICRC ? - (err & ATA_ABORTED ? - "BadCRC " : "Sector ") : "", - err & ATA_UNC ? "UncorrectableError " : "", - err & ATA_IDNF ? "SectorIdNotFound " : "", - err & ATA_TRK0NF ? "TrackZeroNotFound " : "", - err & ATA_AMNF ? "AddrMarkNotFound " : ""); + if (stat & ATA_DRDY) pr_cont("DriveReady "); + if (stat & ATA_DF) pr_cont("DeviceFault "); + if (stat & ATA_DSC) pr_cont("SeekComplete "); + if (stat & ATA_DRQ) pr_cont("DataRequest "); + if (stat & ATA_CORR) pr_cont("CorrectedError "); + if (stat & ATA_SENSE) pr_cont("Sense "); + if (stat & ATA_ERR) pr_cont("Error "); + pr_cont("}\n"); + + if (err) { + pr_warn("ata%u: error=0x%02x { ", id, err); + if (err & ATA_ABORTED) pr_cont("DriveStatusError "); + if (err & ATA_ICRC) { + if (err & ATA_ABORTED) + pr_cont("BadCRC "); + else pr_cont("Sector "); + } + if (err & ATA_UNC) pr_cont("UncorrectableError "); + if (err & ATA_IDNF) pr_cont("SectorIdNotFound "); + if (err & ATA_TRK0NF) pr_cont("TrackZeroNotFound "); + if (err & ATA_AMNF) pr_cont("AddrMarkNotFound "); + pr_cont("}\n"); + } } } @@ -1294,6 +1290,8 @@ static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen) u64 lba = 0; u32 len; + VPRINTK("six-byte command\n"); + lba |= ((u64)(cdb[1] & 0x1f)) << 16; lba |= ((u64)cdb[2]) << 8; lba |= ((u64)cdb[3]); @@ -1319,6 +1317,8 @@ static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) u64 lba = 0; u32 len = 0; + VPRINTK("ten-byte command\n"); + lba |= ((u64)cdb[2]) << 24; lba |= ((u64)cdb[3]) << 16; lba |= ((u64)cdb[4]) << 8; @@ -1346,6 +1346,8 @@ static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) u64 lba = 0; u32 len = 0; + VPRINTK("sixteen-byte command\n"); + lba |= ((u64)cdb[2]) << 56; lba |= ((u64)cdb[3]) << 48; lba |= ((u64)cdb[4]) << 40; @@ -1458,6 +1460,9 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) head = track % dev->heads; sect = (u32)block % dev->sectors + 1; + DPRINTK("block %u track %u cyl %u head %u sect %u\n", + (u32)block, track, cyl, head, sect); + /* Check whether the converted CHS can fit. Cylinder: 0-65535 Head: 0-15 @@ -1580,6 +1585,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) goto invalid_fld; break; default: + DPRINTK("no-byte command\n"); fp = 0; goto invalid_fld; } @@ -1657,7 +1663,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) cmd->result = SAM_STAT_GOOD; if (need_sense && !ap->ops->error_handler) - ata_dump_status(ap, &qc->result_tf); + ata_dump_status(ap->print_id, &qc->result_tf); ata_qc_done(qc); } @@ -1695,6 +1701,8 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, struct ata_queued_cmd *qc; int rc; + VPRINTK("ENTER\n"); + qc = ata_scsi_qc_new(dev, cmd); if (!qc) goto err_mem; @@ -1725,22 +1733,26 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, /* select device, send command to hardware */ ata_qc_issue(qc); + VPRINTK("EXIT\n"); return 0; early_finish: ata_qc_free(qc); - scsi_done(cmd); + cmd->scsi_done(cmd); + DPRINTK("EXIT - early finish (good or error)\n"); return 0; err_did: ata_qc_free(qc); cmd->result = (DID_ERROR << 16); - scsi_done(cmd); + cmd->scsi_done(cmd); err_mem: + DPRINTK("EXIT - internal\n"); return 0; defer: ata_qc_free(qc); + DPRINTK("EXIT - defer\n"); if (rc == ATA_DEFER_LINK) return SCSI_MLQUEUE_DEVICE_BUSY; else @@ -1837,6 +1849,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) 2 }; + VPRINTK("ENTER\n"); + /* set scsi removable (RMB) bit per ata bit, or if the * AHCI port says it's external (Hotplug-capable, eSATA). */ @@ -1881,7 +1895,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) */ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) { - int i, num_pages = 0; + int num_pages; static const u8 pages[] = { 0x00, /* page 0x00, this page */ 0x80, /* page 0x80, unit serial no page */ @@ -1891,17 +1905,13 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) 0xb1, /* page 0xb1, block device characteristics page */ 0xb2, /* page 0xb2, thin provisioning page */ 0xb6, /* page 0xb6, zoned block device characteristics */ - 0xb9, /* page 0xb9, concurrent positioning ranges */ }; - for (i = 0; i < sizeof(pages); i++) { - if (pages[i] == 0xb6 && - !(args->dev->flags & ATA_DFLAG_ZAC)) - continue; - rbuf[num_pages + 4] = pages[i]; - num_pages++; - } + num_pages = sizeof(pages); + if (!(args->dev->flags & ATA_DFLAG_ZAC)) + num_pages--; rbuf[3] = num_pages; /* number of supported VPD pages */ + memcpy(rbuf + 4, pages, num_pages); return 0; } @@ -2111,26 +2121,6 @@ static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf) return 0; } -static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf) -{ - struct ata_cpr_log *cpr_log = args->dev->cpr_log; - u8 *desc = &rbuf[64]; - int i; - - /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */ - rbuf[1] = 0xb9; - put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[3]); - - for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) { - desc[0] = cpr_log->cpr[i].num; - desc[1] = cpr_log->cpr[i].num_storage_elements; - put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]); - put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]); - } - - return 0; -} - /** * modecpy - Prepare response for MODE SENSE * @dest: output buffer @@ -2271,6 +2261,8 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) u8 dpofua, bp = 0xff; u16 fp; + VPRINTK("ENTER\n"); + six_byte = (scsicmd[0] == MODE_SENSE); ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */ /* @@ -2388,6 +2380,8 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) log2_per_phys = ata_id_log2_per_physical_sector(dev->id); lowest_aligned = ata_id_logical_sector_offset(dev->id, log2_per_phys); + VPRINTK("ENTER\n"); + if (args->cmd->cmnd[0] == READ_CAPACITY) { if (last_lba >= 0xffffffffULL) last_lba = 0xffffffff; @@ -2454,6 +2448,7 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) */ static unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf) { + VPRINTK("ENTER\n"); rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */ return 0; @@ -2484,6 +2479,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct scsi_cmnd *cmd = qc->scsicmd; + DPRINTK("ATAPI request sense\n"); + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); #ifdef CONFIG_ATA_SFF @@ -2522,6 +2519,8 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; ata_qc_issue(qc); + + DPRINTK("EXIT\n"); } /* @@ -2549,6 +2548,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) struct scsi_cmnd *cmd = qc->scsicmd; unsigned int err_mask = qc->err_mask; + VPRINTK("ENTER, err_mask 0x%X\n", err_mask); + /* handle completion from new EH */ if (unlikely(qc->ap->ops->error_handler && (err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID))) { @@ -2629,6 +2630,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; if (scmd->sc_data_direction == DMA_TO_DEVICE) { qc->tf.flags |= ATA_TFLAG_WRITE; + DPRINTK("direction: write\n"); } qc->tf.command = ATA_CMD_PACKET; @@ -2990,7 +2992,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) ata_qc_set_pc_nbytes(qc); /* We may not issue DMA commands if no DMA mode is set */ - if (tf->protocol == ATA_PROT_DMA && !ata_dma_enabled(dev)) { + if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) { fp = 1; goto invalid_fld; } @@ -3140,7 +3142,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) u8 unmap = cdb[1] & 0x8; /* we may not issue DMA commands if no DMA mode is set */ - if (unlikely(!ata_dma_enabled(dev))) + if (unlikely(!dev->dma_mode)) goto invalid_opcode; /* @@ -3556,7 +3558,10 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, */ if (len != CACHE_MPAGE_LEN - 2) { - *fp = min(len, CACHE_MPAGE_LEN - 2); + if (len < CACHE_MPAGE_LEN - 2) + *fp = len; + else + *fp = CACHE_MPAGE_LEN - 2; return -EINVAL; } @@ -3609,7 +3614,10 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, */ if (len != CONTROL_MPAGE_LEN - 2) { - *fp = min(len, CONTROL_MPAGE_LEN - 2); + if (len < CONTROL_MPAGE_LEN - 2) + *fp = len; + else + *fp = CONTROL_MPAGE_LEN - 2; return -EINVAL; } @@ -3657,6 +3665,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) u8 buffer[64]; const u8 *p = buffer; + VPRINTK("ENTER\n"); + six_byte = (cdb[0] == MODE_SELECT); if (six_byte) { if (scmd->cmd_len < 5) { @@ -3954,47 +3964,72 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) return NULL; } +/** + * ata_scsi_dump_cdb - dump SCSI command contents to dmesg + * @ap: ATA port to which the command was being sent + * @cmd: SCSI command to dump + * + * Prints the contents of a SCSI command via printk(). + */ + +void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd) +{ +#ifdef ATA_VERBOSE_DEBUG + struct scsi_device *scsidev = cmd->device; + + VPRINTK("CDB (%u:%d,%d,%lld) %9ph\n", + ap->print_id, + scsidev->channel, scsidev->id, scsidev->lun, + cmd->cmnd); +#endif +} + int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) { u8 scsi_op = scmd->cmnd[0]; ata_xlat_func_t xlat_func; - - if (unlikely(!scmd->cmd_len)) - goto bad_cdb_len; + int rc = 0; if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) { - if (unlikely(scmd->cmd_len > dev->cdb_len)) + if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) goto bad_cdb_len; xlat_func = ata_get_xlat_func(dev, scsi_op); - } else if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { - /* relay SCSI command to ATAPI device */ - int len = COMMAND_SIZE(scsi_op); - - if (unlikely(len > scmd->cmd_len || - len > dev->cdb_len || - scmd->cmd_len > ATAPI_CDB_LEN)) - goto bad_cdb_len; - - xlat_func = atapi_xlat; } else { - /* ATA_16 passthru, treat as an ATA command */ - if (unlikely(scmd->cmd_len > 16)) + if (unlikely(!scmd->cmd_len)) goto bad_cdb_len; - xlat_func = ata_get_xlat_func(dev, scsi_op); + xlat_func = NULL; + if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { + /* relay SCSI command to ATAPI device */ + int len = COMMAND_SIZE(scsi_op); + if (unlikely(len > scmd->cmd_len || + len > dev->cdb_len || + scmd->cmd_len > ATAPI_CDB_LEN)) + goto bad_cdb_len; + + xlat_func = atapi_xlat; + } else { + /* ATA_16 passthru, treat as an ATA command */ + if (unlikely(scmd->cmd_len > 16)) + goto bad_cdb_len; + + xlat_func = ata_get_xlat_func(dev, scsi_op); + } } if (xlat_func) - return ata_scsi_translate(dev, scmd, xlat_func); + rc = ata_scsi_translate(dev, scmd, xlat_func); + else + ata_scsi_simulate(dev, scmd); - ata_scsi_simulate(dev, scmd); - - return 0; + return rc; bad_cdb_len: + DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n", + scmd->cmd_len, scsi_op, dev->cdb_len); scmd->result = DID_ERROR << 16; - scsi_done(scmd); + scmd->scsi_done(scmd); return 0; } @@ -4029,12 +4064,14 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) spin_lock_irqsave(ap->lock, irq_flags); + ata_scsi_dump_cdb(ap, cmd); + dev = ata_scsi_find_dev(ap, scsidev); if (likely(dev)) rc = __ata_scsi_queuecmd(cmd, dev); else { cmd->result = (DID_BAD_TARGET << 16); - scsi_done(cmd); + cmd->scsi_done(cmd); } spin_unlock_irqrestore(ap->lock, irq_flags); @@ -4094,17 +4131,11 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); break; case 0xb6: - if (dev->flags & ATA_DFLAG_ZAC) + if (dev->flags & ATA_DFLAG_ZAC) { ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6); - else - ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); - break; - case 0xb9: - if (dev->cpr_log) - ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9); - else - ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); - break; + break; + } + fallthrough; default: ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); break; @@ -4168,7 +4199,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) break; } - scsi_done(cmd); + cmd->scsi_done(cmd); } int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) @@ -4461,9 +4492,12 @@ void ata_scsi_hotplug(struct work_struct *work) container_of(work, struct ata_port, hotplug_task.work); int i; - if (ap->pflags & ATA_PFLAG_UNLOADING) + if (ap->pflags & ATA_PFLAG_UNLOADING) { + DPRINTK("ENTER/EXIT - unloading\n"); return; + } + DPRINTK("ENTER\n"); mutex_lock(&ap->scsi_scan_mutex); /* Unplug detached devices. We cannot use link iterator here @@ -4479,6 +4513,7 @@ void ata_scsi_hotplug(struct work_struct *work) ata_scsi_scan_host(ap, 0); mutex_unlock(&ap->scsi_scan_mutex); + DPRINTK("EXIT\n"); } /** diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 75217828df..b71ea4a680 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -18,7 +18,7 @@ #include #include #include -#include + #include "libata.h" static struct workqueue_struct *ata_sff_wq; @@ -330,6 +330,10 @@ EXPORT_SYMBOL_GPL(ata_sff_dev_select); static void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep) { + if (ata_msg_probe(ap)) + ata_port_info(ap, "ata_dev_select: ENTER, device %u, wait %u\n", + device, wait); + if (wait) ata_wait_idle(ap); @@ -405,6 +409,12 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) iowrite8(tf->hob_lbal, ioaddr->lbal_addr); iowrite8(tf->hob_lbam, ioaddr->lbam_addr); iowrite8(tf->hob_lbah, ioaddr->lbah_addr); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); } if (is_addr) { @@ -413,10 +423,18 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) iowrite8(tf->lbal, ioaddr->lbal_addr); iowrite8(tf->lbam, ioaddr->lbam_addr); iowrite8(tf->lbah, ioaddr->lbah_addr); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); } - if (tf->flags & ATA_TFLAG_DEVICE) + if (tf->flags & ATA_TFLAG_DEVICE) { iowrite8(tf->device, ioaddr->device_addr); + VPRINTK("device 0x%X\n", tf->device); + } ata_wait_idle(ap); } @@ -476,6 +494,8 @@ EXPORT_SYMBOL_GPL(ata_sff_tf_read); */ void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + iowrite8(tf->command, ap->ioaddr.command_addr); ata_sff_pause(ap); } @@ -485,7 +505,6 @@ EXPORT_SYMBOL_GPL(ata_sff_exec_command); * ata_tf_to_host - issue ATA taskfile to host controller * @ap: port to which command is being issued * @tf: ATA taskfile register set - * @tag: tag of the associated command * * Issues ATA taskfile register set to ATA host controller, * with proper synchronization with interrupt handler and @@ -495,12 +514,9 @@ EXPORT_SYMBOL_GPL(ata_sff_exec_command); * spin_lock_irqsave(host lock) */ static inline void ata_tf_to_host(struct ata_port *ap, - const struct ata_taskfile *tf, - unsigned int tag) + const struct ata_taskfile *tf) { - trace_ata_tf_load(ap, tf); ap->ops->sff_tf_load(ap, tf); - trace_ata_exec_command(ap, tf, tag); ap->ops->sff_exec_command(ap, tf); } @@ -664,7 +680,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; - trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size); + DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); /* * Split the transfer when it splits a page boundary. Note that the @@ -734,7 +750,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) { /* send SCSI cdb */ - trace_atapi_send_cdb(qc, 0, qc->dev->cdb_len); + DPRINTK("send cdb\n"); WARN_ON_ONCE(qc->dev->cdb_len < 12); ap->ops->sff_data_xfer(qc, qc->cdb, qc->dev->cdb_len, 1); @@ -752,7 +768,6 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) case ATAPI_PROT_DMA: ap->hsm_task_state = HSM_ST_LAST; /* initiate bmdma */ - trace_ata_bmdma_start(ap, &qc->tf, qc->tag); ap->ops->bmdma_start(qc); break; #endif /* CONFIG_ATA_BMDMA */ @@ -805,7 +820,7 @@ static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) /* don't cross page boundaries */ count = min(count, (unsigned int)PAGE_SIZE - offset); - trace_atapi_pio_transfer_data(qc, offset, count); + DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); /* do the actual data transfer */ buf = kmap_atomic(page); @@ -873,6 +888,8 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) if (unlikely(!bytes)) goto atapi_check; + VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); + if (unlikely(__atapi_pio_bytes(qc, bytes))) goto err_out; ata_sff_sync(ap); /* flush */ @@ -985,7 +1002,8 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, WARN_ON_ONCE(in_wq != ata_hsm_ok_in_wq(ap, qc)); fsm_start: - trace_ata_sff_hsm_state(qc, status); + DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n", + ap->print_id, qc->tf.protocol, ap->hsm_task_state, status); switch (ap->hsm_task_state) { case HSM_ST_FIRST: @@ -1186,7 +1204,8 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, } /* no more data to transfer */ - trace_ata_sff_hsm_command_complete(qc, status); + DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n", + ap->print_id, qc->dev->devno, status); WARN_ON_ONCE(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM)); @@ -1243,7 +1262,7 @@ EXPORT_SYMBOL_GPL(ata_sff_queue_pio_task); void ata_sff_flush_pio_task(struct ata_port *ap) { - trace_ata_sff_flush_pio_task(ap); + DPRINTK("ENTER\n"); cancel_delayed_work_sync(&ap->sff_pio_task); @@ -1260,6 +1279,9 @@ void ata_sff_flush_pio_task(struct ata_port *ap) spin_unlock_irq(ap->lock); ap->sff_pio_task_link = NULL; + + if (ata_msg_ctl(ap)) + ata_port_dbg(ap, "%s: EXIT\n", __func__); } static void ata_sff_pio_task(struct work_struct *work) @@ -1354,7 +1376,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_POLLING) ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf, qc->tag); + ata_tf_to_host(ap, &qc->tf); ap->hsm_task_state = HSM_ST_LAST; if (qc->tf.flags & ATA_TFLAG_POLLING) @@ -1366,7 +1388,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_POLLING) ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf, qc->tag); + ata_tf_to_host(ap, &qc->tf); if (qc->tf.flags & ATA_TFLAG_WRITE) { /* PIO data out protocol */ @@ -1396,7 +1418,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_POLLING) ata_qc_set_polling(qc); - ata_tf_to_host(ap, &qc->tf, qc->tag); + ata_tf_to_host(ap, &qc->tf); ap->hsm_task_state = HSM_ST_FIRST; @@ -1456,7 +1478,8 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap, { u8 status; - trace_ata_sff_port_intr(qc, hsmv_on_idle); + VPRINTK("ata%u: protocol %d task_state %d\n", + ap->print_id, qc->tf.protocol, ap->hsm_task_state); /* Check whether we are expecting interrupt in this state */ switch (ap->hsm_task_state) { @@ -1830,7 +1853,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, return ATA_DEV_NONE; /* determine if device is ATA or ATAPI */ - class = ata_port_classify(ap, &tf); + class = ata_dev_classify(&tf); if (class == ATA_DEV_UNKNOWN) { /* If the device failed diagnostic, it's likely to @@ -1933,6 +1956,8 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, { struct ata_ioports *ioaddr = &ap->ioaddr; + DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); + if (ap->ioaddr.ctl_addr) { /* software reset. causes dev0 to be selected */ iowrite8(ap->ctl, ioaddr->ctl_addr); @@ -1970,6 +1995,8 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes, int rc; u8 err; + DPRINTK("ENTER\n"); + /* determine if device 0/1 are present */ if (ata_devchk(ap, 0)) devmask |= (1 << 0); @@ -1980,6 +2007,7 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes, ap->ops->sff_dev_select(ap, 0); /* issue bus reset */ + DPRINTK("about to softreset, devmask=%x\n", devmask); rc = ata_bus_softreset(ap, devmask, deadline); /* if link is occupied, -ENODEV too is an error */ if (rc && (rc != -ENODEV || sata_scr_valid(link))) { @@ -1994,6 +2022,7 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes, classes[1] = ata_sff_dev_classify(&link->device[1], devmask & (1 << 1), &err); + DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); return 0; } EXPORT_SYMBOL_GPL(ata_sff_softreset); @@ -2026,6 +2055,7 @@ int sata_sff_hardreset(struct ata_link *link, unsigned int *class, if (online) *class = ata_sff_dev_classify(link->device, 1, NULL); + DPRINTK("EXIT, class=%u\n", *class); return rc; } EXPORT_SYMBOL_GPL(sata_sff_hardreset); @@ -2055,8 +2085,10 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) ap->ops->sff_dev_select(ap, 0); /* bail out if no device is present */ - if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) + if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { + DPRINTK("EXIT, no device\n"); return; + } /* set up device control */ if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) { @@ -2091,6 +2123,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc) && count < 65536; count += 2) ioread16(ap->ioaddr.data_addr); + /* Can become DEBUG later */ if (count) ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count); @@ -2434,6 +2467,8 @@ static int ata_pci_init_one(struct pci_dev *pdev, struct ata_host *host = NULL; int rc; + DPRINTK("ENTER\n"); + pi = ata_sff_find_valid_pi(ppi); if (!pi) { dev_err(&pdev->dev, "no valid port_info specified\n"); @@ -2579,6 +2614,7 @@ static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc) prd[pi].addr = cpu_to_le32(addr); prd[pi].flags_len = cpu_to_le32(len & 0xffff); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len); pi++; sg_len -= len; @@ -2638,6 +2674,7 @@ static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc) prd[++pi].addr = cpu_to_le32(addr + 0x8000); } prd[pi].flags_len = cpu_to_le32(blen); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len); pi++; sg_len -= len; @@ -2719,11 +2756,8 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) case ATA_PROT_DMA: WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING); - trace_ata_tf_load(ap, &qc->tf); ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */ - trace_ata_bmdma_setup(ap, &qc->tf, qc->tag); ap->ops->bmdma_setup(qc); /* set up bmdma */ - trace_ata_bmdma_start(ap, &qc->tf, qc->tag); ap->ops->bmdma_start(qc); /* initiate bmdma */ ap->hsm_task_state = HSM_ST_LAST; break; @@ -2731,9 +2765,7 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) case ATAPI_PROT_DMA: WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING); - trace_ata_tf_load(ap, &qc->tf); ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */ - trace_ata_bmdma_setup(ap, &qc->tf, qc->tag); ap->ops->bmdma_setup(qc); /* set up bmdma */ ap->hsm_task_state = HSM_ST_FIRST; @@ -2774,14 +2806,13 @@ unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) { /* check status of DMA engine */ host_stat = ap->ops->bmdma_status(ap); - trace_ata_bmdma_status(ap, host_stat); + VPRINTK("ata%u: host_stat 0x%X\n", ap->print_id, host_stat); /* if it's not our irq... */ if (!(host_stat & ATA_DMA_INTR)) return ata_sff_idle_irq(ap); /* before we do anything else, clear DMA-Start bit */ - trace_ata_bmdma_stop(ap, &qc->tf, qc->tag); ap->ops->bmdma_stop(qc); bmdma_stopped = true; @@ -2850,7 +2881,6 @@ void ata_bmdma_error_handler(struct ata_port *ap) u8 host_stat; host_stat = ap->ops->bmdma_status(ap); - trace_ata_bmdma_status(ap, host_stat); /* BMDMA controllers indicate host bus error by * setting DMA_ERR bit and timing out. As it wasn't @@ -2862,7 +2892,6 @@ void ata_bmdma_error_handler(struct ata_port *ap) thaw = true; } - trace_ata_bmdma_stop(ap, &qc->tf, qc->tag); ap->ops->bmdma_stop(qc); /* if we're gonna thaw, make sure IRQ is clear */ @@ -2896,7 +2925,6 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) if (ata_is_dma(qc->tf.protocol)) { spin_lock_irqsave(ap->lock, flags); - trace_ata_bmdma_stop(ap, &qc->tf, qc->tag); ap->ops->bmdma_stop(qc); spin_unlock_irqrestore(ap->lock, flags); } diff --git a/drivers/ata/libata-trace.c b/drivers/ata/libata-trace.c index e0e4d0d5a1..08e001303a 100644 --- a/drivers/ata/libata-trace.c +++ b/drivers/ata/libata-trace.c @@ -38,24 +38,6 @@ libata_trace_parse_status(struct trace_seq *p, unsigned char status) return ret; } -const char * -libata_trace_parse_host_stat(struct trace_seq *p, unsigned char host_stat) -{ - const char *ret = trace_seq_buffer_ptr(p); - - trace_seq_printf(p, "{ "); - if (host_stat & ATA_DMA_INTR) - trace_seq_printf(p, "INTR "); - if (host_stat & ATA_DMA_ERR) - trace_seq_printf(p, "ERR "); - if (host_stat & ATA_DMA_ACTIVE) - trace_seq_printf(p, "ACTIVE "); - trace_seq_putc(p, '}'); - trace_seq_putc(p, 0); - - return ret; -} - const char * libata_trace_parse_eh_action(struct trace_seq *p, unsigned int eh_action) { @@ -155,35 +137,6 @@ libata_trace_parse_qc_flags(struct trace_seq *p, unsigned int qc_flags) return ret; } -const char * -libata_trace_parse_tf_flags(struct trace_seq *p, unsigned int tf_flags) -{ - const char *ret = trace_seq_buffer_ptr(p); - - trace_seq_printf(p, "%x", tf_flags); - if (tf_flags) { - trace_seq_printf(p, "{ "); - if (tf_flags & ATA_TFLAG_LBA48) - trace_seq_printf(p, "LBA48 "); - if (tf_flags & ATA_TFLAG_ISADDR) - trace_seq_printf(p, "ISADDR "); - if (tf_flags & ATA_TFLAG_DEVICE) - trace_seq_printf(p, "DEV "); - if (tf_flags & ATA_TFLAG_WRITE) - trace_seq_printf(p, "WRITE "); - if (tf_flags & ATA_TFLAG_LBA) - trace_seq_printf(p, "LBA "); - if (tf_flags & ATA_TFLAG_FUA) - trace_seq_printf(p, "FUA "); - if (tf_flags & ATA_TFLAG_POLLING) - trace_seq_printf(p, "POLL "); - trace_seq_putc(p, '}'); - } - trace_seq_putc(p, 0); - - return ret; -} - const char * libata_trace_parse_subcmd(struct trace_seq *p, unsigned char cmd, unsigned char feature, unsigned char hob_nsect) diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index ca129854a8..34bb4608bd 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -163,7 +163,7 @@ static struct { { AC_ERR_INVALID, "InvalidArg" }, { AC_ERR_OTHER, "Unknown" }, { AC_ERR_NODEV_HINT, "NoDeviceHint" }, - { AC_ERR_NCQ, "NCQError" } + { AC_ERR_NCQ, "NCQError" } }; ata_bitfield_name_match(err, ata_err_names) @@ -321,43 +321,13 @@ int ata_tport_add(struct device *parent, return error; } -/** - * ata_port_classify - determine device type based on ATA-spec signature - * @ap: ATA port device on which the classification should be run - * @tf: ATA taskfile register set for device to be identified - * - * A wrapper around ata_dev_classify() to provide additional logging - * - * RETURNS: - * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP, - * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure. - */ -unsigned int ata_port_classify(struct ata_port *ap, - const struct ata_taskfile *tf) -{ - int i; - unsigned int class = ata_dev_classify(tf); - - /* Start with index '1' to skip the 'unknown' entry */ - for (i = 1; i < ARRAY_SIZE(ata_class_names); i++) { - if (ata_class_names[i].value == class) { - ata_port_dbg(ap, "found %s device by sig\n", - ata_class_names[i].name); - return class; - } - } - - ata_port_info(ap, "found unknown device (class %u)\n", class); - return class; -} -EXPORT_SYMBOL_GPL(ata_port_classify); /* * ATA link attributes */ static int noop(int x) { return x; } -#define ata_link_show_linkspeed(field, format) \ +#define ata_link_show_linkspeed(field, format) \ static ssize_t \ show_ata_link_##field(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -446,7 +416,7 @@ int ata_tlink_add(struct ata_link *link) dev->release = ata_tlink_release; if (ata_is_host_link(link)) dev_set_name(dev, "link%d", ap->print_id); - else + else dev_set_name(dev, "link%d.%d", ap->print_id, link->pmp); transport_setup_device(dev); @@ -502,7 +472,7 @@ ata_dev_attr(xfer, dma_mode); ata_dev_attr(xfer, xfer_mode); -#define ata_dev_show_simple(field, format_string, cast) \ +#define ata_dev_show_simple(field, format_string, cast) \ static ssize_t \ show_ata_dev_##field(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -512,9 +482,9 @@ show_ata_dev_##field(struct device *dev, \ return scnprintf(buf, 20, format_string, cast ata_dev->field); \ } -#define ata_dev_simple_attr(field, format_string, type) \ +#define ata_dev_simple_attr(field, format_string, type) \ ata_dev_show_simple(field, format_string, (type)) \ - static DEVICE_ATTR(field, S_IRUGO, \ +static DEVICE_ATTR(field, S_IRUGO, \ show_ata_dev_##field, NULL) ata_dev_simple_attr(spdn_cnt, "%d\n", int); @@ -532,7 +502,7 @@ static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg) seconds = div_u64_rem(ent->timestamp, HZ, &rem); arg->written += sprintf(arg->buf + arg->written, - "[%5llu.%09lu]", seconds, + "[%5llu.%09lu]", seconds, rem * NSEC_PER_SEC / HZ); arg->written += get_ata_err_names(ent->err_mask, arg->buf + arg->written); @@ -697,7 +667,7 @@ static int ata_tdev_add(struct ata_device *ata_dev) dev->release = ata_tdev_release; if (ata_is_host_link(link)) dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno); - else + else dev_set_name(dev, "dev%d.%d.0", ap->print_id, link->pmp); transport_setup_device(dev); @@ -719,7 +689,7 @@ static int ata_tdev_add(struct ata_device *ata_dev) */ #define SETUP_TEMPLATE(attrb, field, perm, test) \ - i->private_##attrb[count] = dev_attr_##field; \ + i->private_##attrb[count] = dev_attr_##field; \ i->private_##attrb[count].attr.mode = perm; \ i->attrb[count] = &i->private_##attrb[count]; \ if (test) \ diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 51e01acdd2..68cdd81d74 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -148,6 +148,7 @@ extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, unsigned int id, u64 lun); void ata_scsi_sdev_config(struct scsi_device *sdev); int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev); +void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd); int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev); /* libata-eh.c */ @@ -165,7 +166,7 @@ extern void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, extern void ata_eh_done(struct ata_link *link, struct ata_device *dev, unsigned int action); extern void ata_eh_autopsy(struct ata_port *ap); -const char *ata_get_cmd_name(u8 command); +const char *ata_get_cmd_descript(u8 command); extern void ata_eh_report(struct ata_port *ap); extern int ata_eh_reset(struct ata_link *link, int classify, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, @@ -178,7 +179,7 @@ extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, extern void ata_eh_finish(struct ata_port *ap); extern int ata_ering_map(struct ata_ering *ering, int (*map_fn)(struct ata_ering_entry *, void *), - void *arg); + void *arg); extern unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key); extern unsigned int atapi_eh_request_sense(struct ata_device *dev, u8 *sense_buf, u8 dfl_sense_key); diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 1b90cda272..557ecf4661 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -37,7 +37,7 @@ #define DRV_NAME "pata_ali" #define DRV_VERSION "0.7.8" -static int ali_atapi_dma; +static int ali_atapi_dma = 0; module_param_named(atapi_dma, ali_atapi_dma, int, 0644); MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); @@ -123,7 +123,7 @@ static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask) mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num)); if (strstr(model_num, "WDC")) - mask &= ~ATA_MASK_UDMA; + return mask &= ~ATA_MASK_UDMA; return mask; } @@ -215,7 +215,7 @@ static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev) struct ata_timing p; ata_timing_compute(pair, pair->pio_mode, &p, T, 1); ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT); - if (ata_dma_enabled(pair)) { + if (pair->dma_mode) { ata_timing_compute(pair, pair->dma_mode, &p, T, 1); ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT); } @@ -264,7 +264,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev) struct ata_timing p; ata_timing_compute(pair, pair->pio_mode, &p, T, 1); ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT); - if (ata_dma_enabled(pair)) { + if (pair->dma_mode) { ata_timing_compute(pair, pair->dma_mode, &p, T, 1); ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT); } diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 154748cfcc..c8acba162d 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -66,7 +66,7 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse if (peer) { /* This may be over conservative */ - if (ata_dma_enabled(peer)) { + if (peer->dma_mode) { ata_timing_compute(peer, peer->dma_mode, &apeer, T, UT); ata_timing_merge(&apeer, &at, &at, ATA_TIMING_8BIT); } diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 24c3d5e1fc..63f39440a9 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -39,7 +39,6 @@ #include #include #include -#include #define DRIVER_NAME "arasan_cf" #define TIMEOUT msecs_to_jiffies(3000) @@ -704,11 +703,9 @@ static unsigned int arasan_cf_qc_issue(struct ata_queued_cmd *qc) case ATA_PROT_DMA: WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING); - trace_ata_tf_load(ap, &qc->tf); ap->ops->sff_tf_load(ap, &qc->tf); acdev->dma_status = 0; acdev->qc = qc; - trace_ata_bmdma_start(ap, &qc->tf, qc->tag); arasan_cf_dma_start(acdev); ap->hsm_task_state = HSM_ST_LAST; break; diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index 779d660415..2bc5fc81ef 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c @@ -155,7 +155,7 @@ static int atp867x_get_active_clocks_shifted(struct ata_port *ap, case 1 ... 6: break; default: - ata_port_warn(ap, "ATP867X: active %dclk is invalid. " + printk(KERN_WARNING "ATP867X: active %dclk is invalid. " "Using 12clk.\n", clk); fallthrough; case 9 ... 12: @@ -171,8 +171,7 @@ static int atp867x_get_active_clocks_shifted(struct ata_port *ap, return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT; } -static int atp867x_get_recover_clocks_shifted(struct ata_port *ap, - unsigned int clk) +static int atp867x_get_recover_clocks_shifted(unsigned int clk) { unsigned char clocks = clk; @@ -189,7 +188,7 @@ static int atp867x_get_recover_clocks_shifted(struct ata_port *ap, case 15: break; default: - ata_port_warn(ap, "ATP867X: recover %dclk is invalid. " + printk(KERN_WARNING "ATP867X: recover %dclk is invalid. " "Using default 12clk.\n", clk); fallthrough; case 12: /* default 12 clk */ @@ -226,7 +225,7 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev) iowrite8(b, dp->dma_mode); b = atp867x_get_active_clocks_shifted(ap, t.active) | - atp867x_get_recover_clocks_shifted(ap, t.recover); + atp867x_get_recover_clocks_shifted(t.recover); if (adev->devno & 1) iowrite8(b, dp->slave_piospd); @@ -234,7 +233,7 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev) iowrite8(b, dp->mstr_piospd); b = atp867x_get_active_clocks_shifted(ap, t.act8b) | - atp867x_get_recover_clocks_shifted(ap, t.rec8b); + atp867x_get_recover_clocks_shifted(t.rec8b); iowrite8(b, dp->eightb_piospd); } @@ -271,6 +270,7 @@ static struct ata_port_operations atp867x_ops = { }; +#ifdef ATP867X_DEBUG static void atp867x_check_res(struct pci_dev *pdev) { int i; @@ -280,7 +280,7 @@ static void atp867x_check_res(struct pci_dev *pdev) for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { start = pci_resource_start(pdev, i); len = pci_resource_len(pdev, i); - dev_dbg(&pdev->dev, "ATP867X: resource start:len=%lx:%lx\n", + printk(KERN_DEBUG "ATP867X: resource start:len=%lx:%lx\n", start, len); } } @@ -290,48 +290,49 @@ static void atp867x_check_ports(struct ata_port *ap, int port) struct ata_ioports *ioaddr = &ap->ioaddr; struct atp867x_priv *dp = ap->private_data; - ata_port_dbg(ap, "ATP867X: port[%d] addresses\n" - " cmd_addr =0x%lx, 0x%lx\n" - " ctl_addr =0x%lx, 0x%lx\n" - " bmdma_addr =0x%lx, 0x%lx\n" - " data_addr =0x%lx\n" - " error_addr =0x%lx\n" - " feature_addr =0x%lx\n" - " nsect_addr =0x%lx\n" - " lbal_addr =0x%lx\n" - " lbam_addr =0x%lx\n" - " lbah_addr =0x%lx\n" - " device_addr =0x%lx\n" - " status_addr =0x%lx\n" - " command_addr =0x%lx\n" - " dp->dma_mode =0x%lx\n" - " dp->mstr_piospd =0x%lx\n" - " dp->slave_piospd =0x%lx\n" - " dp->eightb_piospd =0x%lx\n" + printk(KERN_DEBUG "ATP867X: port[%d] addresses\n" + " cmd_addr =0x%llx, 0x%llx\n" + " ctl_addr =0x%llx, 0x%llx\n" + " bmdma_addr =0x%llx, 0x%llx\n" + " data_addr =0x%llx\n" + " error_addr =0x%llx\n" + " feature_addr =0x%llx\n" + " nsect_addr =0x%llx\n" + " lbal_addr =0x%llx\n" + " lbam_addr =0x%llx\n" + " lbah_addr =0x%llx\n" + " device_addr =0x%llx\n" + " status_addr =0x%llx\n" + " command_addr =0x%llx\n" + " dp->dma_mode =0x%llx\n" + " dp->mstr_piospd =0x%llx\n" + " dp->slave_piospd =0x%llx\n" + " dp->eightb_piospd =0x%llx\n" " dp->pci66mhz =0x%lx\n", port, - (unsigned long)ioaddr->cmd_addr, - (unsigned long)ATP867X_IO_PORTBASE(ap, port), - (unsigned long)ioaddr->ctl_addr, - (unsigned long)ATP867X_IO_ALTSTATUS(ap, port), - (unsigned long)ioaddr->bmdma_addr, - (unsigned long)ATP867X_IO_DMABASE(ap, port), - (unsigned long)ioaddr->data_addr, - (unsigned long)ioaddr->error_addr, - (unsigned long)ioaddr->feature_addr, - (unsigned long)ioaddr->nsect_addr, - (unsigned long)ioaddr->lbal_addr, - (unsigned long)ioaddr->lbam_addr, - (unsigned long)ioaddr->lbah_addr, - (unsigned long)ioaddr->device_addr, - (unsigned long)ioaddr->status_addr, - (unsigned long)ioaddr->command_addr, - (unsigned long)dp->dma_mode, - (unsigned long)dp->mstr_piospd, - (unsigned long)dp->slave_piospd, - (unsigned long)dp->eightb_piospd, + (unsigned long long)ioaddr->cmd_addr, + (unsigned long long)ATP867X_IO_PORTBASE(ap, port), + (unsigned long long)ioaddr->ctl_addr, + (unsigned long long)ATP867X_IO_ALTSTATUS(ap, port), + (unsigned long long)ioaddr->bmdma_addr, + (unsigned long long)ATP867X_IO_DMABASE(ap, port), + (unsigned long long)ioaddr->data_addr, + (unsigned long long)ioaddr->error_addr, + (unsigned long long)ioaddr->feature_addr, + (unsigned long long)ioaddr->nsect_addr, + (unsigned long long)ioaddr->lbal_addr, + (unsigned long long)ioaddr->lbam_addr, + (unsigned long long)ioaddr->lbah_addr, + (unsigned long long)ioaddr->device_addr, + (unsigned long long)ioaddr->status_addr, + (unsigned long long)ioaddr->command_addr, + (unsigned long long)dp->dma_mode, + (unsigned long long)dp->mstr_piospd, + (unsigned long long)dp->slave_piospd, + (unsigned long long)dp->eightb_piospd, (unsigned long)dp->pci66mhz); } +#endif static int atp867x_set_priv(struct ata_port *ap) { @@ -369,7 +370,8 @@ static void atp867x_fixup(struct ata_host *host) if (v < 0x80) { v = 0x80; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, v); - dev_dbg(&pdev->dev, "ATP867X: set latency timer to %d\n", v); + printk(KERN_DEBUG "ATP867X: set latency timer of device %s" + " to %d\n", pci_name(pdev), v); } /* @@ -417,11 +419,13 @@ static int atp867x_ata_pci_sff_init_host(struct ata_host *host) return rc; host->iomap = pcim_iomap_table(pdev); +#ifdef ATP867X_DEBUG atp867x_check_res(pdev); for (i = 0; i < PCI_STD_NUM_BARS; i++) - dev_dbg(gdev, "ATP867X: iomap[%d]=0x%p\n", i, - host->iomap[i]); + printk(KERN_DEBUG "ATP867X: iomap[%d]=0x%llx\n", i, + (unsigned long long)(host->iomap[i])); +#endif /* * request, iomap BARs and init port addresses accordingly @@ -440,8 +444,9 @@ static int atp867x_ata_pci_sff_init_host(struct ata_host *host) if (rc) return rc; +#ifdef ATP867X_DEBUG atp867x_check_ports(ap, i); - +#endif ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", (unsigned long)ioaddr->cmd_addr, (unsigned long)ioaddr->ctl_addr); @@ -481,7 +486,7 @@ static int atp867x_init_one(struct pci_dev *pdev, if (rc) return rc; - dev_info(&pdev->dev, "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)", + printk(KERN_INFO "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)", pdev->device); host = ata_host_alloc_pinfo(&pdev->dev, ppi, ATP867X_NUM_PORTS); diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 1a3372a722..d0bcabb58b 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -61,7 +61,7 @@ static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev) struct ata_device *pair = ata_dev_pair(adev); if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) { - ata_dev_err(adev, DRV_NAME ": mode computation failed.\n"); + printk(KERN_ERR DRV_NAME ": mode computation failed.\n"); return; } diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 5baa4a7819..1d74d89b5b 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -116,7 +116,7 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m /* ata_timing_compute is smart and will produce timings for MWDMA that don't violate the drives PIO capabilities. */ if (ata_timing_compute(adev, mode, &t, T, 0) < 0) { - ata_dev_err(adev, DRV_NAME ": mode computation failed.\n"); + printk(KERN_ERR DRV_NAME ": mode computation failed.\n"); return; } if (ap->port_no) { @@ -130,7 +130,7 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m } } - ata_dev_dbg(adev, DRV_NAME ": active %d recovery %d setup %d.\n", + printk(KERN_DEBUG DRV_NAME ": active %d recovery %d setup %d.\n", t.active, t.recover, t.setup); if (t.recover > 16) { t.active += t.recover - 16; diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 24ce8665b1..247c147026 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -153,12 +153,12 @@ static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* Perform set up for DMA */ if (pci_enable_device_io(pdev)) { - dev_err(&pdev->dev, "unable to configure BAR2.\n"); + printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); return -ENODEV; } if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) { - dev_err(&pdev->dev, "unable to configure DMA mask.\n"); + printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n"); return -ENODEV; } diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index ab47aeb558..760ac6e652 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c @@ -263,12 +263,12 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) ppi[1] = &ata_dummy_port_info; if (use_msr) - dev_err(&dev->dev, DRV_NAME ": Using MSR regs instead of PCI\n"); + printk(KERN_ERR DRV_NAME ": Using MSR regs instead of PCI\n"); cs5536_read(dev, CFG, &cfg); if ((cfg & IDE_CFG_CHANEN) == 0) { - dev_err(&dev->dev, DRV_NAME ": disabled by BIOS\n"); + printk(KERN_ERR DRV_NAME ": disabled by BIOS\n"); return -ENODEV; } diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 3be5d52a77..5b3a7a8ebe 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -62,7 +62,7 @@ static void cy82c693_set_piomode(struct ata_port *ap, struct ata_device *adev) u32 addr; if (ata_timing_compute(adev, adev->pio_mode, &t, T, 1) < 0) { - ata_dev_err(adev, DRV_NAME ": mome computation failed.\n"); + printk(KERN_ERR DRV_NAME ": mome computation failed.\n"); return; } diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index b78f71c70f..46208ececb 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -855,6 +855,7 @@ static void ep93xx_pata_drain_fifo(struct ata_queued_cmd *qc) && count < 65536; count += 2) ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_DATA); + /* Can become DEBUG later */ if (count) ata_port_dbg(ap, "drained %d bytes to clear DRQ.\n", count); diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c index 823c88622e..121635aa8c 100644 --- a/drivers/ata/pata_falcon.c +++ b/drivers/ata/pata_falcon.c @@ -55,14 +55,14 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, /* Transfer multiple of 2 bytes */ if (rw == READ) { if (swap) - raw_insw_swapw(data_addr, (u16 *)buf, words); + raw_insw_swapw((u16 *)data_addr, (u16 *)buf, words); else - raw_insw(data_addr, (u16 *)buf, words); + raw_insw((u16 *)data_addr, (u16 *)buf, words); } else { if (swap) - raw_outsw_swapw(data_addr, (u16 *)buf, words); + raw_outsw_swapw((u16 *)data_addr, (u16 *)buf, words); else - raw_outsw(data_addr, (u16 *)buf, words); + raw_outsw((u16 *)data_addr, (u16 *)buf, words); } /* Transfer trailing byte, if any. */ @@ -74,16 +74,16 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, if (rw == READ) { if (swap) - raw_insw_swapw(data_addr, (u16 *)pad, 1); + raw_insw_swapw((u16 *)data_addr, (u16 *)pad, 1); else - raw_insw(data_addr, (u16 *)pad, 1); + raw_insw((u16 *)data_addr, (u16 *)pad, 1); *buf = pad[0]; } else { pad[0] = *buf; if (swap) - raw_outsw_swapw(data_addr, (u16 *)pad, 1); + raw_outsw_swapw((u16 *)data_addr, (u16 *)pad, 1); else - raw_outsw(data_addr, (u16 *)pad, 1); + raw_outsw((u16 *)data_addr, (u16 *)pad, 1); } words++; } diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 778c893f27..06b7c4a9ec 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -14,6 +14,9 @@ * TODO * Look into engine reset on timeout errors. Should not be required. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -180,7 +183,7 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, i = match_string(list, -1, model_num); if (i >= 0) { - ata_dev_warn(dev, "%s is not supported for %s\n", modestr, list[i]); + pr_warn("%s is not supported for %s\n", modestr, list[i]); return 1; } return 0; diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 6fa4a2faf4..9d371859e8 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -14,6 +14,9 @@ * TODO * Look into engine reset on timeout errors. Should not be required. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -228,8 +231,7 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, i = match_string(list, -1, model_num); if (i >= 0) { - ata_dev_warn(dev, "%s is not supported for %s\n", - modestr, list[i]); + pr_warn("%s is not supported for %s\n", modestr, list[i]); return 1; } return 0; @@ -862,8 +864,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) chip_table = &hpt372; break; default: - dev_err(&dev->dev, - "Unknown HPT366 subtype, please report (%d)\n", + pr_err("Unknown HPT366 subtype, please report (%d)\n", rev); return -ENODEV; } @@ -904,8 +905,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) *ppi = &info_hpt374_fn1; break; default: - dev_err(&dev->dev, "PCI table is bogus, please report (%d)\n", - dev->device); + pr_err("PCI table is bogus, please report (%d)\n", dev->device); return -ENODEV; } /* Ok so this is a chip we support */ @@ -967,7 +967,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) u16 sr; u32 total = 0; - dev_warn(&dev->dev, "BIOS has not set timing clocks\n"); + pr_warn("BIOS has not set timing clocks\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -1023,7 +1023,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - dev_err(&dev->dev, "DPLL did not stabilize!\n"); + pr_err("DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1031,7 +1031,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - dev_info(&dev->dev, "bus clock %dMHz, using %dMHz DPLL\n", + pr_info("bus clock %dMHz, using %dMHz DPLL\n", MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; @@ -1046,7 +1046,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) if (clock_slot < 2 && ppi[0] == &info_hpt370a) ppi[0] = &info_hpt370a_33; - dev_info(&dev->dev, "%s using %dMHz bus clock\n", + pr_info("%s using %dMHz bus clock\n", chip_table->name, MHz[clock_slot]); } diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 1d9d4eec5b..48eef338e0 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -15,6 +15,9 @@ * TODO * Work out best PLL policy */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -417,7 +420,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) u16 sr; u32 total = 0; - dev_warn(&pdev->dev, "BIOS clock data not set\n"); + pr_warn("BIOS clock data not set\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { @@ -527,8 +530,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) ppi[0] = &info_hpt372n; break; default: - dev_err(&dev->dev,"PCI table is bogus, please report (%d)\n", - dev->device); + pr_err("PCI table is bogus, please report (%d)\n", dev->device); return -ENODEV; } @@ -577,11 +579,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - dev_err(&dev->dev, "DPLL did not stabilize!\n"); + pr_err("DPLL did not stabilize!\n"); return -ENODEV; } - dev_info(&dev->dev, "bus clock %dMHz, using 66MHz DPLL\n", pci_mhz); + pr_info("bus clock %dMHz, using 66MHz DPLL\n", pci_mhz); /* * Set our private data up. We only need a few flags diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 8a5b4e0079..0e2265978a 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -431,8 +431,7 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc) case ATA_CMD_SET_FEATURES: return ata_bmdma_qc_issue(qc); } - ata_dev_dbg(qc->dev, "it821x: can't process command 0x%02X\n", - qc->tf.command); + printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command); return AC_ERR_DEV; } @@ -508,14 +507,12 @@ static void it821x_dev_config(struct ata_device *adev) if (strstr(model_num, "Integrated Technology Express")) { /* RAID mode */ - if (adev->id[129] == 1) - ata_dev_info(adev, "%sRAID%d volume\n", - adev->id[147] ? "Bootable " : "", - adev->id[129]); - else - ata_dev_info(adev, "%sRAID%d volume (%dK stripe)\n", - adev->id[147] ? "Bootable " : "", - adev->id[129], adev->id[146]); + ata_dev_info(adev, "%sRAID%d volume", + adev->id[147] ? "Bootable " : "", + adev->id[129]); + if (adev->id[129] != 1) + pr_cont("(%dK stripe)", adev->id[146]); + pr_cont("\n"); } /* This is a controller firmware triggered funny, don't report the drive faulty! */ @@ -537,7 +534,7 @@ static void it821x_dev_config(struct ata_device *adev) */ static unsigned int it821x_read_id(struct ata_device *adev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { unsigned int err_mask; unsigned char model_num[ATA_ID_PROD_LEN + 1]; @@ -545,20 +542,21 @@ static unsigned int it821x_read_id(struct ata_device *adev, err_mask = ata_do_dev_read_id(adev, tf, id); if (err_mask) return err_mask; - ata_id_c_string((u16 *)id, model_num, ATA_ID_PROD, sizeof(model_num)); + ata_id_c_string(id, model_num, ATA_ID_PROD, sizeof(model_num)); - id[83] &= cpu_to_le16(~(1 << 12)); /* Cache flush is firmware handled */ - id[84] &= cpu_to_le16(~(1 << 6)); /* No FUA */ - id[85] &= cpu_to_le16(~(1 << 10)); /* No HPA */ - id[76] = 0; /* No NCQ/AN etc */ + id[83] &= ~(1 << 12); /* Cache flush is firmware handled */ + id[83] &= ~(1 << 13); /* Ditto for LBA48 flushes */ + id[84] &= ~(1 << 6); /* No FUA */ + id[85] &= ~(1 << 10); /* No HPA */ + id[76] = 0; /* No NCQ/AN etc */ if (strstr(model_num, "Integrated Technology Express")) { /* Set feature bits the firmware neglects */ - id[49] |= cpu_to_le16(0x0300); /* LBA, DMA */ - id[83] &= cpu_to_le16(0x7FFF); - id[83] |= cpu_to_le16(0x4400); /* Word 83 is valid and LBA48 */ - id[86] |= cpu_to_le16(0x0400); /* LBA48 on */ - id[ATA_ID_MAJOR_VER] |= cpu_to_le16(0x1F); + id[49] |= 0x0300; /* LBA, DMA */ + id[83] &= 0x7FFF; + id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ + id[86] |= 0x0400; /* LBA48 on */ + id[ATA_ID_MAJOR_VER] |= 0x1F; /* Clear the serial number because it's different each boot which breaks validation on resume */ memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); @@ -595,7 +593,6 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) /** * it821x_display_disk - display disk setup - * @ap: ATA port * @n: Device number * @buf: Buffer block from firmware * @@ -603,7 +600,7 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) * by the firmware. */ -static void it821x_display_disk(struct ata_port *ap, int n, u8 *buf) +static void it821x_display_disk(int n, u8 *buf) { unsigned char id[41]; int mode = 0; @@ -636,13 +633,13 @@ static void it821x_display_disk(struct ata_port *ap, int n, u8 *buf) else strcpy(mbuf, "PIO"); if (buf[52] == 4) - ata_port_info(ap, "%d: %-6s %-8s %s %s\n", + printk(KERN_INFO "%d: %-6s %-8s %s %s\n", n, mbuf, types[buf[52]], id, cbl); else - ata_port_info(ap, "%d: %-6s %-8s Volume: %1d %s %s\n", + printk(KERN_INFO "%d: %-6s %-8s Volume: %1d %s %s\n", n, mbuf, types[buf[52]], buf[53], id, cbl); if (buf[125] < 100) - ata_port_info(ap, "%d: Rebuilding: %d%%\n", n, buf[125]); + printk(KERN_INFO "%d: Rebuilding: %d%%\n", n, buf[125]); } /** @@ -679,7 +676,7 @@ static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len) status = ioread8(ap->ioaddr.status_addr); if (status & ATA_ERR) { kfree(buf); - ata_port_err(ap, "%s: rejected\n", __func__); + printk(KERN_ERR "it821x_firmware_command: rejected\n"); return NULL; } if (status & ATA_DRQ) { @@ -689,7 +686,7 @@ static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len) usleep_range(500, 1000); } kfree(buf); - ata_port_err(ap, "%s: timeout\n", __func__); + printk(KERN_ERR "it821x_firmware_command: timeout\n"); return NULL; } @@ -712,13 +709,13 @@ static void it821x_probe_firmware(struct ata_port *ap) buf = it821x_firmware_command(ap, 0xFA, 512); if (buf != NULL) { - ata_port_info(ap, "pata_it821x: Firmware %02X/%02X/%02X%02X\n", + printk(KERN_INFO "pata_it821x: Firmware %02X/%02X/%02X%02X\n", buf[505], buf[506], buf[507], buf[508]); for (i = 0; i < 4; i++) - it821x_display_disk(ap, i, buf + 128 * i); + it821x_display_disk(i, buf + 128 * i); kfree(buf); } } @@ -774,8 +771,7 @@ static int it821x_port_start(struct ata_port *ap) itdev->timing10 = 1; /* Need to disable ATAPI DMA for this case */ if (!itdev->smart) - dev_warn(&pdev->dev, - "Revision 0x10, workarounds activated.\n"); + printk(KERN_WARNING DRV_NAME": Revision 0x10, workarounds activated.\n"); } return 0; @@ -923,14 +919,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } else { /* Force the card into bypass mode if so requested */ if (it8212_noraid) { - dev_info(&pdev->dev, "forcing bypass mode.\n"); + printk(KERN_INFO DRV_NAME ": forcing bypass mode.\n"); it821x_disable_raid(pdev); } pci_read_config_byte(pdev, 0x50, &conf); conf &= 1; - dev_info(&pdev->dev, "controller in %s mode.\n", mode[conf]); - + printk(KERN_INFO DRV_NAME": controller in %s mode.\n", + mode[conf]); if (conf == 0) ppi[0] = &info_passthru; else diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 17b557c91e..99c63087c8 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -114,7 +114,7 @@ static void ixp4xx_set_piomode(struct ata_port *ap, struct ata_device *adev) { struct ixp4xx_pata *ixpp = ap->host->private_data; - ata_dev_info(adev, "configured for PIO%d 8bit\n", + ata_dev_printk(adev, KERN_INFO, "configured for PIO%d 8bit\n", adev->pio_mode - XFER_PIO_0); ixp4xx_set_8bit_timing(ixpp, adev->pio_mode); } @@ -132,8 +132,8 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_queued_cmd *qc, struct ixp4xx_pata *ixpp = ap->host->private_data; unsigned long flags; - ata_dev_dbg(adev, "%s %d bytes\n", (rw == READ) ? "READ" : "WRITE", - buflen); + ata_dev_printk(adev, KERN_DEBUG, "%s %d bytes\n", (rw == READ) ? "READ" : "WRITE", + buflen); spin_lock_irqsave(ap->lock, flags); /* set the expansion bus in 16bit mode and restore diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 16e8aa184a..be0ca8d5b3 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -923,7 +923,7 @@ static struct scsi_host_template pata_macio_sht = { */ .max_segment_size = MAX_DBDMA_SEG, .slave_configure = pata_macio_slave_config, - .sdev_groups = ata_common_sdev_groups, + .sdev_attrs = ata_common_sdev_attrs, .can_queue = ATA_DEF_QUEUE, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 0c5a51970f..361597d14c 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -32,6 +32,7 @@ static int marvell_pata_active(struct pci_dev *pdev) { + int i; u32 devices; void __iomem *barp; @@ -43,6 +44,11 @@ static int marvell_pata_active(struct pci_dev *pdev) if (barp == NULL) return -ENOMEM; + printk("BAR5:"); + for(i = 0; i <= 0x0F; i++) + printk("%02X:%02X ", i, ioread8(barp + i)); + printk("\n"); + devices = ioread32(barp + 0x0C); pci_iounmap(pdev, barp); @@ -143,8 +149,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i #if IS_ENABLED(CONFIG_SATA_AHCI) if (!marvell_pata_active(pdev)) { - dev_info(&pdev->dev, - "PATA port not active, deferring to AHCI driver.\n"); + printk(KERN_INFO DRV_NAME ": PATA port not active, deferring to AHCI driver.\n"); return -ENODEV; } #endif diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 06929e77c4..a7ecc1a204 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -21,13 +21,12 @@ /* No PIO or DMA methods needed for this device */ static unsigned int netcell_read_id(struct ata_device *adev, - struct ata_taskfile *tf, __le16 *id) + struct ata_taskfile *tf, u16 *id) { unsigned int err_mask = ata_do_dev_read_id(adev, tf, id); - /* Firmware forgets to mark words 85-87 valid */ if (err_mask == 0) - id[ATA_ID_CSF_DEFAULT] |= cpu_to_le16(0x4000); + id[ATA_ID_CSF_DEFAULT] |= 0x4000; return err_mask; } diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 05c2ab3757..b5a3f710d7 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -19,7 +19,7 @@ #include #include #include -#include + #include #include @@ -73,12 +73,16 @@ MODULE_PARM_DESC(enable_dma, */ static unsigned int ns_to_tim_reg(unsigned int tim_mult, unsigned int nsecs) { + unsigned int val; + /* * Compute # of eclock periods to get desired duration in * nanoseconds. */ - return DIV_ROUND_UP(nsecs * (octeon_get_io_clock_rate() / 1000000), + val = DIV_ROUND_UP(nsecs * (octeon_get_io_clock_rate() / 1000000), 1000 * tim_mult); + + return val; } static void octeon_cf_set_boot_reg_cfg(int cs, unsigned int multiplier) @@ -269,9 +273,9 @@ static void octeon_cf_set_dmamode(struct ata_port *ap, struct ata_device *dev) dma_tim.s.we_n = ns_to_tim_reg(tim_mult, oe_n); dma_tim.s.we_a = ns_to_tim_reg(tim_mult, oe_a); - ata_dev_dbg(dev, "ns to ticks (mult %d) of %d is: %d\n", tim_mult, 60, + pr_debug("ns to ticks (mult %d) of %d is: %d\n", tim_mult, 60, ns_to_tim_reg(tim_mult, 60)); - ata_dev_dbg(dev, "oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: %d, dmarq: %d, pause: %d\n", + pr_debug("oe_n: %d, oe_a: %d, dmack_s: %d, dmack_h: %d, dmarq: %d, pause: %d\n", dma_tim.s.oe_n, dma_tim.s.oe_a, dma_tim.s.dmack_s, dma_tim.s.dmack_h, dma_tim.s.dmarq, dma_tim.s.pause); @@ -436,6 +440,7 @@ static int octeon_cf_softreset16(struct ata_link *link, unsigned int *classes, int rc; u8 err; + DPRINTK("about to softreset\n"); __raw_writew(ap->ctl, base + 0xe); udelay(20); __raw_writew(ap->ctl | ATA_SRST, base + 0xe); @@ -450,6 +455,7 @@ static int octeon_cf_softreset16(struct ata_link *link, unsigned int *classes, /* determine by signature whether we have ATA or ATAPI devices */ classes[0] = ata_sff_dev_classify(&link->device[0], 1, &err); + DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); return 0; } @@ -473,11 +479,23 @@ static void octeon_cf_tf_load16(struct ata_port *ap, __raw_writew(tf->hob_feature << 8, base + 0xc); __raw_writew(tf->hob_nsect | tf->hob_lbal << 8, base + 2); __raw_writew(tf->hob_lbam | tf->hob_lbah << 8, base + 4); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); } if (is_addr) { __raw_writew(tf->feature << 8, base + 0xc); __raw_writew(tf->nsect | tf->lbal << 8, base + 2); __raw_writew(tf->lbam | tf->lbah << 8, base + 4); + VPRINTK("feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); } ata_wait_idle(ap); } @@ -498,14 +516,20 @@ static void octeon_cf_exec_command16(struct ata_port *ap, { /* The base of the registers is at ioaddr.data_addr. */ void __iomem *base = ap->ioaddr.data_addr; - u16 blob = 0; + u16 blob; - if (tf->flags & ATA_TFLAG_DEVICE) + if (tf->flags & ATA_TFLAG_DEVICE) { + VPRINTK("device 0x%X\n", tf->device); blob = tf->device; + } else { + blob = 0; + } + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); blob |= (tf->command << 8); __raw_writew(blob, base + 6); + ata_wait_idle(ap); } @@ -519,10 +543,12 @@ static void octeon_cf_dma_setup(struct ata_queued_cmd *qc) struct octeon_cf_port *cf_port; cf_port = ap->private_data; + DPRINTK("ENTER\n"); /* issue r/w command */ qc->cursg = qc->sg; cf_port->dma_finished = 0; ap->ops->sff_exec_command(ap, &qc->tf); + DPRINTK("EXIT\n"); } /** @@ -537,6 +563,8 @@ static void octeon_cf_dma_start(struct ata_queued_cmd *qc) union cvmx_mio_boot_dma_intx mio_boot_dma_int; struct scatterlist *sg; + VPRINTK("%d scatterlists\n", qc->n_elem); + /* Get the scatter list entry we need to DMA into */ sg = qc->cursg; BUG_ON(!sg); @@ -577,6 +605,10 @@ static void octeon_cf_dma_start(struct ata_queued_cmd *qc) mio_boot_dma_cfg.s.adr = sg_dma_address(sg); + VPRINTK("%s %d bytes address=%p\n", + (mio_boot_dma_cfg.s.rw) ? "write" : "read", sg->length, + (void *)(unsigned long)mio_boot_dma_cfg.s.adr); + cvmx_write_csr(cf_port->dma_base + DMA_CFG, mio_boot_dma_cfg.u64); } @@ -595,7 +627,9 @@ static unsigned int octeon_cf_dma_finished(struct ata_port *ap, union cvmx_mio_boot_dma_intx dma_int; u8 status; - trace_ata_bmdma_stop(ap, &qc->tf, qc->tag); + VPRINTK("ata%u: protocol %d task_state %d\n", + ap->print_id, qc->tf.protocol, ap->hsm_task_state); + if (ap->hsm_task_state != HSM_ST_LAST) return 0; @@ -644,6 +678,7 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) spin_lock_irqsave(&host->lock, flags); + DPRINTK("ENTER\n"); for (i = 0; i < host->n_ports; i++) { u8 status; struct ata_port *ap; @@ -666,7 +701,6 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) if (!sg_is_last(qc->cursg)) { qc->cursg = sg_next(qc->cursg); handled = 1; - trace_ata_bmdma_start(ap, &qc->tf, qc->tag); octeon_cf_dma_start(qc); continue; } else { @@ -698,6 +732,7 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) } } spin_unlock_irqrestore(&host->lock, flags); + DPRINTK("EXIT\n"); return IRQ_RETVAL(handled); } @@ -765,11 +800,8 @@ static unsigned int octeon_cf_qc_issue(struct ata_queued_cmd *qc) case ATA_PROT_DMA: WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING); - trace_ata_tf_load(ap, &qc->tf); ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */ - trace_ata_bmdma_setup(ap, &qc->tf, qc->tag); octeon_cf_dma_setup(qc); /* set up dma */ - trace_ata_bmdma_start(ap, &qc->tf, qc->tag); octeon_cf_dma_start(qc); /* initiate dma */ ap->hsm_task_state = HSM_ST_LAST; break; diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index c3a40b717d..35aa158fc9 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -25,12 +25,11 @@ static int pata_of_platform_probe(struct platform_device *ofdev) struct device_node *dn = ofdev->dev.of_node; struct resource io_res; struct resource ctl_res; - struct resource irq_res; + struct resource *irq_res; unsigned int reg_shift = 0; int pio_mode = 0; int pio_mask; bool use16bit; - int irq; ret = of_address_to_resource(dn, 0, &io_res); if (ret) { @@ -46,15 +45,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev) return -EINVAL; } - memset(&irq_res, 0, sizeof(irq_res)); - - irq = platform_get_irq_optional(ofdev, 0); - if (irq < 0 && irq != -ENXIO) - return irq; - if (irq > 0) { - irq_res.start = irq; - irq_res.end = irq; - } + irq_res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); of_property_read_u32(dn, "reg-shift", ®_shift); @@ -72,7 +63,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev) pio_mask = 1 << pio_mode; pio_mask |= (1 << pio_mode) - 1; - return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, irq > 0 ? &irq_res : NULL, + return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, irq_res, reg_shift, pio_mask, &pata_platform_sht, use16bit); } diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index ad1090b90e..f6278d9de3 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -153,7 +153,7 @@ static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 if (pair) { u8 pair_addr; /* Hardware constraint */ - if (ata_dma_enabled(pair)) + if (pair->dma_mode) pair_addr = 0; else pair_addr = addr_timing[pci_clock][pair->pio_mode - XFER_PIO_0]; @@ -301,7 +301,7 @@ static u8 optidma_make_bits43(struct ata_device *adev) }; if (!ata_dev_enabled(adev)) return 0; - if (ata_dma_enabled(adev)) + if (adev->dma_mode) return adev->dma_mode - XFER_MW_DMA_0; return bits43[adev->pio_mode - XFER_PIO_0]; } diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 4fbb3eed8b..effc1a0944 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -30,6 +30,13 @@ #define DRV_NAME "pata_pdc2027x" #define DRV_VERSION "1.0" +#undef PDC_DEBUG + +#ifdef PDC_DEBUG +#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) +#else +#define PDPRINTK(fmt, args...) +#endif enum { PDC_MMIO_BAR = 5, @@ -207,11 +214,11 @@ static int pdc2027x_cable_detect(struct ata_port *ap) if (cgcr & (1 << 26)) goto cbl40; - ata_port_dbg(ap, "No cable or 80-conductor cable\n"); + PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no); return ATA_CBL_PATA80; cbl40: - ata_port_info(ap, DRV_NAME ":40-conductor cable detected\n"); + printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no); return ATA_CBL_PATA40; } @@ -285,17 +292,17 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev) unsigned int pio = adev->pio_mode - XFER_PIO_0; u32 ctcr0, ctcr1; - ata_port_dbg(ap, "adev->pio_mode[%X]\n", adev->pio_mode); + PDPRINTK("adev->pio_mode[%X]\n", adev->pio_mode); /* Sanity check */ if (pio > 4) { - ata_port_err(ap, "Unknown pio mode [%d] ignored\n", pio); + printk(KERN_ERR DRV_NAME ": Unknown pio mode [%d] ignored\n", pio); return; } /* Set the PIO timing registers using value table for 133MHz */ - ata_port_dbg(ap, "Set pio regs... \n"); + PDPRINTK("Set pio regs... \n"); ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0)); ctcr0 &= 0xffff0000; @@ -308,7 +315,9 @@ static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev) ctcr1 |= (pdc2027x_pio_timing_tbl[pio].value2 << 24); iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); - ata_port_dbg(ap, "Set to pio mode[%u] \n", pio); + PDPRINTK("Set pio regs done\n"); + + PDPRINTK("Set to pio mode[%u] \n", pio); } /** @@ -341,7 +350,7 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) iowrite32(ctcr1 & ~(1 << 7), dev_mmio(ap, adev, PDC_CTCR1)); } - ata_port_dbg(ap, "Set udma regs... \n"); + PDPRINTK("Set udma regs... \n"); ctcr1 = ioread32(dev_mmio(ap, adev, PDC_CTCR1)); ctcr1 &= 0xff000000; @@ -350,14 +359,16 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) (pdc2027x_udma_timing_tbl[udma_mode].value2 << 16); iowrite32(ctcr1, dev_mmio(ap, adev, PDC_CTCR1)); - ata_port_dbg(ap, "Set to udma mode[%u] \n", udma_mode); + PDPRINTK("Set udma regs done\n"); + + PDPRINTK("Set to udma mode[%u] \n", udma_mode); } else if ((dma_mode >= XFER_MW_DMA_0) && (dma_mode <= XFER_MW_DMA_2)) { /* Set the MDMA timing registers with value table for 133MHz */ unsigned int mdma_mode = dma_mode & 0x07; - ata_port_dbg(ap, "Set mdma regs... \n"); + PDPRINTK("Set mdma regs... \n"); ctcr0 = ioread32(dev_mmio(ap, adev, PDC_CTCR0)); ctcr0 &= 0x0000ffff; @@ -365,10 +376,11 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev) (pdc2027x_mdma_timing_tbl[mdma_mode].value1 << 24); iowrite32(ctcr0, dev_mmio(ap, adev, PDC_CTCR0)); + PDPRINTK("Set mdma regs done\n"); - ata_port_dbg(ap, "Set to mdma mode[%u] \n", mdma_mode); + PDPRINTK("Set to mdma mode[%u] \n", mdma_mode); } else { - ata_port_err(ap, "Unknown dma mode [%u] ignored\n", dma_mode); + printk(KERN_ERR DRV_NAME ": Unknown dma mode [%u] ignored\n", dma_mode); } } @@ -402,7 +414,7 @@ static int pdc2027x_set_mode(struct ata_link *link, struct ata_device **r_failed ctcr1 |= (1 << 25); iowrite32(ctcr1, dev_mmio(ap, dev, PDC_CTCR1)); - ata_dev_dbg(dev, "Turn on prefetch\n"); + PDPRINTK("Turn on prefetch\n"); } else { pdc2027x_set_dmamode(ap, dev); } @@ -473,8 +485,8 @@ static long pdc_read_counter(struct ata_host *host) counter = (bccrh << 15) | bccrl; - dev_dbg(host->dev, "bccrh [%X] bccrl [%X]\n", bccrh, bccrl); - dev_dbg(host->dev, "bccrhv[%X] bccrlv[%X]\n", bccrhv, bccrlv); + PDPRINTK("bccrh [%X] bccrl [%X]\n", bccrh, bccrl); + PDPRINTK("bccrhv[%X] bccrlv[%X]\n", bccrhv, bccrlv); /* * The 30-bit decreasing counter are read by 2 pieces. @@ -483,7 +495,7 @@ static long pdc_read_counter(struct ata_host *host) */ if (retry && !(bccrh == bccrhv && bccrl >= bccrlv)) { retry--; - dev_dbg(host->dev, "rereading counter\n"); + PDPRINTK("rereading counter\n"); goto retry; } @@ -508,19 +520,20 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b /* Sanity check */ if (unlikely(pll_clock_khz < 5000L || pll_clock_khz > 70000L)) { - dev_err(host->dev, "Invalid PLL input clock %ldkHz, give up!\n", - pll_clock_khz); + printk(KERN_ERR DRV_NAME ": Invalid PLL input clock %ldkHz, give up!\n", pll_clock_khz); return; } - dev_dbg(host->dev, "pout_required is %ld\n", pout_required); +#ifdef PDC_DEBUG + PDPRINTK("pout_required is %ld\n", pout_required); /* Show the current clock value of PLL control register * (maybe already configured by the firmware) */ pll_ctl = ioread16(mmio_base + PDC_PLL_CTL); - dev_dbg(host->dev, "pll_ctl[%X]\n", pll_ctl); + PDPRINTK("pll_ctl[%X]\n", pll_ctl); +#endif /* * Calculate the ratio of F, R and OD @@ -539,7 +552,7 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b R = 0x00; } else { /* Invalid ratio */ - dev_err(host->dev, "Invalid ratio %ld, give up!\n", ratio); + printk(KERN_ERR DRV_NAME ": Invalid ratio %ld, give up!\n", ratio); return; } @@ -547,15 +560,15 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b if (unlikely(F < 0 || F > 127)) { /* Invalid F */ - dev_err(host->dev, "F[%d] invalid!\n", F); + printk(KERN_ERR DRV_NAME ": F[%d] invalid!\n", F); return; } - dev_dbg(host->dev, "F[%d] R[%d] ratio*1000[%ld]\n", F, R, ratio); + PDPRINTK("F[%d] R[%d] ratio*1000[%ld]\n", F, R, ratio); pll_ctl = (R << 8) | F; - dev_dbg(host->dev, "Writing pll_ctl[%X]\n", pll_ctl); + PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl); iowrite16(pll_ctl, mmio_base + PDC_PLL_CTL); ioread16(mmio_base + PDC_PLL_CTL); /* flush */ @@ -563,13 +576,15 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b /* Wait the PLL circuit to be stable */ msleep(30); +#ifdef PDC_DEBUG /* * Show the current clock value of PLL control register * (maybe configured by the firmware) */ pll_ctl = ioread16(mmio_base + PDC_PLL_CTL); - dev_dbg(host->dev, "pll_ctl[%X]\n", pll_ctl); + PDPRINTK("pll_ctl[%X]\n", pll_ctl); +#endif return; } @@ -590,7 +605,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) /* Start the test mode */ scr = ioread32(mmio_base + PDC_SYS_CTL); - dev_dbg(host->dev, "scr[%X]\n", scr); + PDPRINTK("scr[%X]\n", scr); iowrite32(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL); ioread32(mmio_base + PDC_SYS_CTL); /* flush */ @@ -607,7 +622,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) /* Stop the test mode */ scr = ioread32(mmio_base + PDC_SYS_CTL); - dev_dbg(host->dev, "scr[%X]\n", scr); + PDPRINTK("scr[%X]\n", scr); iowrite32(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL); ioread32(mmio_base + PDC_SYS_CTL); /* flush */ @@ -617,8 +632,8 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) pll_clock = ((start_count - end_count) & 0x3fffffff) / 100 * (100000000 / usec_elapsed); - dev_dbg(host->dev, "start[%ld] end[%ld] PLL input clock[%ld]HZ\n", - start_count, end_count, pll_clock); + PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); + PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock); return pll_clock; } diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index b998490958..0c5cbcd28d 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -38,6 +38,8 @@ static int pdc2026x_cable_detect(struct ata_port *ap) static void pdc202xx_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + iowrite8(tf->command, ap->ioaddr.command_addr); ndelay(400); } diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 87c7c90676..028329428b 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -128,8 +128,6 @@ int __pata_platform_probe(struct device *dev, struct resource *io_res, ap = host->ports[0]; ap->ops = devm_kzalloc(dev, sizeof(*ap->ops), GFP_KERNEL); - if (!ap->ops) - return -ENOMEM; ap->ops->inherits = &ata_sff_port_ops; ap->ops->cable_detect = ata_cable_unknown; ap->ops->set_mode = pata_platform_set_mode; diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 3aca8fe3fd..8fde4a8640 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -172,8 +172,8 @@ static unsigned int radisys_qc_issue(struct ata_queued_cmd *qc) if (adev != ap->private_data) { /* UDMA timing is not shared */ - if (adev->dma_mode < XFER_UDMA_0 || !ata_dma_enabled(adev)) { - if (ata_dma_enabled(adev)) + if (adev->dma_mode < XFER_UDMA_0) { + if (adev->dma_mode) radisys_set_dmamode(ap, adev); else if (adev->pio_mode) radisys_set_piomode(ap, adev); diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index fb00c3e5fd..3722a67083 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -69,7 +69,7 @@ static int rz1000_fifo_disable(struct pci_dev *pdev) reg &= 0xDFFF; if (pci_write_config_word(pdev, 0x40, reg) != 0) return -1; - dev_info(&pdev->dev, "disabled chipset readahead.\n"); + printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n"); return 0; } @@ -97,7 +97,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en if (rz1000_fifo_disable(pdev) == 0) return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL, 0); - dev_err(&pdev->dev, "failed to disable read-ahead on chipset.\n"); + printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); /* Not safe to use so skip */ return -ENODEV; } diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index e410fe4417..b602e303fb 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -286,13 +286,13 @@ static int serverworks_fixup_osb4(struct pci_dev *pdev) pci_read_config_dword(isa_dev, 0x64, ®); reg &= ~0x00002000; /* disable 600ns interrupt mask */ if (!(reg & 0x00004000)) - dev_info(&pdev->dev, "UDMA not BIOS enabled.\n"); + printk(KERN_DEBUG DRV_NAME ": UDMA not BIOS enabled.\n"); reg |= 0x00004000; /* enable UDMA/33 support */ pci_write_config_dword(isa_dev, 0x64, reg); pci_dev_put(isa_dev); return 0; } - dev_warn(&pdev->dev, "Unable to find bridge.\n"); + printk(KERN_WARNING DRV_NAME ": Unable to find bridge.\n"); return -ENODEV; } diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 0da58ce20d..43215a664b 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -212,6 +212,7 @@ static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev) static void sil680_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); iowrite8(tf->command, ap->ioaddr.command_addr); ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); } @@ -308,17 +309,17 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio) switch (tmpbyte & 0x30) { case 0x00: - dev_info(&pdev->dev, "sil680: 100MHz clock.\n"); + printk(KERN_INFO "sil680: 100MHz clock.\n"); break; case 0x10: - dev_info(&pdev->dev, "sil680: 133MHz clock.\n"); + printk(KERN_INFO "sil680: 133MHz clock.\n"); break; case 0x20: - dev_info(&pdev->dev, "sil680: Using PCI clock.\n"); + printk(KERN_INFO "sil680: Using PCI clock.\n"); break; /* This last case is _NOT_ ok */ case 0x30: - dev_err(&pdev->dev, "sil680: Clock disabled ?\n"); + printk(KERN_ERR "sil680: Clock disabled ?\n"); } return tmpbyte & 0x30; } diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 439ca882f7..4750320489 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -414,6 +414,12 @@ static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) iowrite8(tf->hob_lbal, ioaddr->lbal_addr); iowrite8(tf->hob_lbam, ioaddr->lbam_addr); iowrite8(tf->hob_lbah, ioaddr->lbah_addr); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); } if (is_addr) { @@ -422,6 +428,12 @@ static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) iowrite8(tf->lbal, ioaddr->lbal_addr); iowrite8(tf->lbam, ioaddr->lbam_addr); iowrite8(tf->lbah, ioaddr->lbah_addr); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); } ata_wait_idle(ap); diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 35b823ac20..5db55e1e2a 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -284,6 +284,9 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)(buf + i) = (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4); i += 4; + + VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4, + (unsigned long)addr, len); } if (likely(last_buf)) @@ -299,6 +302,8 @@ static enum ata_completion_errors adma_qc_prep(struct ata_queued_cmd *qc) u32 pkt_dma = (u32)pp->pkt_dma; int i = 0; + VPRINTK("ENTER\n"); + adma_enter_reg_mode(qc->ap); if (qc->tf.protocol != ATA_PROT_DMA) return AC_ERR_OK; @@ -350,6 +355,22 @@ static enum ata_completion_errors adma_qc_prep(struct ata_queued_cmd *qc) i = adma_fill_sg(qc); wmb(); /* flush PRDs and pkt to memory */ +#if 0 + /* dump out CPB + PRDs for debug */ + { + int j, len = 0; + static char obuf[2048]; + for (j = 0; j < i; ++j) { + len += sprintf(obuf+len, "%02x ", buf[j]); + if ((j & 7) == 7) { + printk("%s\n", obuf); + len = 0; + } + } + if (len) + printk("%s\n", obuf); + } +#endif return AC_ERR_OK; } @@ -358,6 +379,8 @@ static inline void adma_packet_start(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; void __iomem *chan = ADMA_PORT_REGS(ap); + VPRINTK("ENTER, ap %p\n", ap); + /* fire up the ADMA engine */ writew(aPIOMD4 | aGO, chan + ADMA_CONTROL); } @@ -452,6 +475,8 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host) u8 status = ata_sff_check_status(ap); if ((status & ATA_BUSY)) continue; + DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", + ap->print_id, qc->tf.protocol, status); /* complete taskfile transaction */ pp->state = adma_state_idle; @@ -479,10 +504,14 @@ static irqreturn_t adma_intr(int irq, void *dev_instance) struct ata_host *host = dev_instance; unsigned int handled = 0; + VPRINTK("ENTER\n"); + spin_lock(&host->lock); handled = adma_intr_pkt(host) | adma_intr_mmio(host); spin_unlock(&host->lock); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); } @@ -518,8 +547,8 @@ static int adma_port_start(struct ata_port *ap) return -ENOMEM; /* paranoia? */ if ((pp->pkt_dma & 7) != 0) { - ata_port_err(ap, "bad alignment for pp->pkt_dma: %08x\n", - (u32)pp->pkt_dma); + printk(KERN_ERR "bad alignment for pp->pkt_dma: %08x\n", + (u32)pp->pkt_dma); return -ENOMEM; } ap->private_data = pp; diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index bec33d781a..338c2e50f7 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -14,6 +14,15 @@ * COPYRIGHT (C) 2005 SYNOPSYS, INC. ALL RIGHTS RESERVED */ +#ifdef CONFIG_SATA_DWC_DEBUG +#define DEBUG +#endif + +#ifdef CONFIG_SATA_DWC_VDEBUG +#define VERBOSE_DEBUG +#define DEBUG_NCQ +#endif + #include #include #include @@ -25,7 +34,6 @@ #include #include #include -#include #include "libata.h" @@ -174,8 +182,10 @@ enum { * Prototypes */ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag); -static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc); -static void sata_dwc_dma_xfer_complete(struct ata_port *ap); +static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc, + u32 check_status); +static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status); +static void sata_dwc_port_stop(struct ata_port *ap); static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag); #ifdef CONFIG_SATA_DWC_OLD_DMA @@ -205,10 +215,9 @@ static int sata_dwc_dma_get_channel_old(struct sata_dwc_device_port *hsdevp) { struct sata_dwc_device *hsdev = hsdevp->hsdev; struct dw_dma_slave *dws = &sata_dwc_dma_dws; - struct device *dev = hsdev->dev; dma_cap_mask_t mask; - dws->dma_dev = dev; + dws->dma_dev = hsdev->dev; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); @@ -216,7 +225,8 @@ static int sata_dwc_dma_get_channel_old(struct sata_dwc_device_port *hsdevp) /* Acquire DMA channel */ hsdevp->chan = dma_request_channel(mask, sata_dwc_dma_filter, hsdevp); if (!hsdevp->chan) { - dev_err(dev, "%s: dma channel unavailable\n", __func__); + dev_err(hsdev->dev, "%s: dma channel unavailable\n", + __func__); return -EAGAIN; } @@ -226,25 +236,26 @@ static int sata_dwc_dma_get_channel_old(struct sata_dwc_device_port *hsdevp) static int sata_dwc_dma_init_old(struct platform_device *pdev, struct sata_dwc_device *hsdev) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; + struct device_node *np = pdev->dev.of_node; + struct resource *res; - hsdev->dma = devm_kzalloc(dev, sizeof(*hsdev->dma), GFP_KERNEL); + hsdev->dma = devm_kzalloc(&pdev->dev, sizeof(*hsdev->dma), GFP_KERNEL); if (!hsdev->dma) return -ENOMEM; - hsdev->dma->dev = dev; + hsdev->dma->dev = &pdev->dev; hsdev->dma->id = pdev->id; /* Get SATA DMA interrupt number */ hsdev->dma->irq = irq_of_parse_and_map(np, 1); if (hsdev->dma->irq == NO_IRQ) { - dev_err(dev, "no SATA DMA irq\n"); + dev_err(&pdev->dev, "no SATA DMA irq\n"); return -ENODEV; } /* Get physical SATA DMA register base address */ - hsdev->dma->regs = devm_platform_ioremap_resource(pdev, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + hsdev->dma->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hsdev->dma->regs)) return PTR_ERR(hsdev->dma->regs); @@ -286,6 +297,35 @@ static const char *get_prot_descript(u8 protocol) } } +static const char *get_dma_dir_descript(int dma_dir) +{ + switch ((enum dma_data_direction)dma_dir) { + case DMA_BIDIRECTIONAL: + return "bidirectional"; + case DMA_TO_DEVICE: + return "to device"; + case DMA_FROM_DEVICE: + return "from device"; + default: + return "none"; + } +} + +static void sata_dwc_tf_dump(struct ata_port *ap, struct ata_taskfile *tf) +{ + dev_vdbg(ap->dev, + "taskfile cmd: 0x%02x protocol: %s flags: 0x%lx device: %x\n", + tf->command, get_prot_descript(tf->protocol), tf->flags, + tf->device); + dev_vdbg(ap->dev, + "feature: 0x%02x nsect: 0x%x lbal: 0x%x lbam: 0x%x lbah: 0x%x\n", + tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah); + dev_vdbg(ap->dev, + "hob_feature: 0x%02x hob_nsect: 0x%x hob_lbal: 0x%x hob_lbam: 0x%x hob_lbah: 0x%x\n", + tf->hob_feature, tf->hob_nsect, tf->hob_lbal, tf->hob_lbam, + tf->hob_lbah); +} + static void dma_dwc_xfer_done(void *hsdev_instance) { unsigned long flags; @@ -315,7 +355,7 @@ static void dma_dwc_xfer_done(void *hsdev_instance) } if ((hsdevp->dma_interrupt_count % 2) == 0) - sata_dwc_dma_xfer_complete(ap); + sata_dwc_dma_xfer_complete(ap, 1); spin_unlock_irqrestore(&host->lock, flags); } @@ -513,7 +553,6 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) * active tag. It is the tag that matches the command about to * be completed. */ - trace_ata_bmdma_start(ap, &qc->tf, tag); qc->ap->link.active_tag = tag; sata_dwc_bmdma_start_by_tag(qc, tag); @@ -547,7 +586,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) if (status & ATA_ERR) { dev_dbg(ap->dev, "interrupt ATA_ERR (0x%x)\n", status); - sata_dwc_qc_complete(ap, qc); + sata_dwc_qc_complete(ap, qc, 1); handled = 1; goto DONE; } @@ -572,13 +611,13 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) } if ((hsdevp->dma_interrupt_count % 2) == 0) - sata_dwc_dma_xfer_complete(ap); + sata_dwc_dma_xfer_complete(ap, 1); } else if (ata_is_pio(qc->tf.protocol)) { ata_sff_hsm_move(ap, qc, status, 0); handled = 1; goto DONE; } else { - if (unlikely(sata_dwc_qc_complete(ap, qc))) + if (unlikely(sata_dwc_qc_complete(ap, qc, 1))) goto DRVSTILLBUSY; } @@ -638,7 +677,7 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) if (status & ATA_ERR) { dev_dbg(ap->dev, "%s ATA_ERR (0x%x)\n", __func__, status); - sata_dwc_qc_complete(ap, qc); + sata_dwc_qc_complete(ap, qc, 1); handled = 1; goto DONE; } @@ -653,9 +692,9 @@ static irqreturn_t sata_dwc_isr(int irq, void *dev_instance) dev_warn(ap->dev, "%s: DMA not pending?\n", __func__); if ((hsdevp->dma_interrupt_count % 2) == 0) - sata_dwc_dma_xfer_complete(ap); + sata_dwc_dma_xfer_complete(ap, 1); } else { - if (unlikely(sata_dwc_qc_complete(ap, qc))) + if (unlikely(sata_dwc_qc_complete(ap, qc, 1))) goto STILLBUSY; } continue; @@ -710,7 +749,7 @@ static void sata_dwc_clear_dmacr(struct sata_dwc_device_port *hsdevp, u8 tag) } } -static void sata_dwc_dma_xfer_complete(struct ata_port *ap) +static void sata_dwc_dma_xfer_complete(struct ata_port *ap, u32 check_status) { struct ata_queued_cmd *qc; struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); @@ -724,6 +763,17 @@ static void sata_dwc_dma_xfer_complete(struct ata_port *ap) return; } +#ifdef DEBUG_NCQ + if (tag > 0) { + dev_info(ap->dev, + "%s tag=%u cmd=0x%02x dma dir=%s proto=%s dmacr=0x%08x\n", + __func__, qc->hw_tag, qc->tf.command, + get_dma_dir_descript(qc->dma_dir), + get_prot_descript(qc->tf.protocol), + sata_dwc_readl(&hsdev->sata_dwc_regs->dmacr)); + } +#endif + if (ata_is_dma(qc->tf.protocol)) { if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_NONE) { dev_err(ap->dev, @@ -733,14 +783,15 @@ static void sata_dwc_dma_xfer_complete(struct ata_port *ap) } hsdevp->dma_pending[tag] = SATA_DWC_DMA_PENDING_NONE; - sata_dwc_qc_complete(ap, qc); + sata_dwc_qc_complete(ap, qc, check_status); ap->link.active_tag = ATA_TAG_POISON; } else { - sata_dwc_qc_complete(ap, qc); + sata_dwc_qc_complete(ap, qc, check_status); } } -static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc) +static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc, + u32 check_status) { u8 status = 0; u32 mask = 0x0; @@ -748,6 +799,7 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc) struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); hsdev->sactive_queued = 0; + dev_dbg(ap->dev, "%s checkstatus? %x\n", __func__, check_status); if (hsdevp->dma_pending[tag] == SATA_DWC_DMA_PENDING_TX) dev_err(ap->dev, "TX DMA PENDING\n"); @@ -928,6 +980,9 @@ static void sata_dwc_exec_command_by_tag(struct ata_port *ap, { struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); + dev_dbg(ap->dev, "%s cmd(0x%02x): %s tag=%d\n", __func__, tf->command, + ata_get_cmd_descript(tf->command), tag); + hsdevp->cmd_issued[tag] = cmd_issued; /* @@ -950,9 +1005,12 @@ static void sata_dwc_bmdma_setup(struct ata_queued_cmd *qc) { u8 tag = qc->hw_tag; - if (!ata_is_ncq(qc->tf.protocol)) + if (ata_is_ncq(qc->tf.protocol)) { + dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n", + __func__, qc->ap->link.sactive, tag); + } else { tag = 0; - + } sata_dwc_bmdma_setup_by_tag(qc, tag); } @@ -979,6 +1037,12 @@ static void sata_dwc_bmdma_start_by_tag(struct ata_queued_cmd *qc, u8 tag) start_dma = 0; } + dev_dbg(ap->dev, + "%s qc=%p tag: %x cmd: 0x%02x dma_dir: %s start_dma? %x\n", + __func__, qc, tag, qc->tf.command, + get_dma_dir_descript(qc->dma_dir), start_dma); + sata_dwc_tf_dump(ap, &qc->tf); + if (start_dma) { sata_dwc_scr_read(&ap->link, SCR_ERROR, ®); if (reg & SATA_DWC_SERROR_ERR_BITS) { @@ -1003,9 +1067,13 @@ static void sata_dwc_bmdma_start(struct ata_queued_cmd *qc) { u8 tag = qc->hw_tag; - if (!ata_is_ncq(qc->tf.protocol)) + if (ata_is_ncq(qc->tf.protocol)) { + dev_dbg(qc->ap->dev, "%s: ap->link.sactive=0x%08x tag=%d\n", + __func__, qc->ap->link.sactive, tag); + } else { tag = 0; - + } + dev_dbg(qc->ap->dev, "%s\n", __func__); sata_dwc_bmdma_start_by_tag(qc, tag); } @@ -1016,6 +1084,16 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); +#ifdef DEBUG_NCQ + if (qc->hw_tag > 0 || ap->link.sactive > 1) + dev_info(ap->dev, + "%s ap id=%d cmd(0x%02x)=%s qc tag=%d prot=%s ap active_tag=0x%08x ap sactive=0x%08x\n", + __func__, ap->print_id, qc->tf.command, + ata_get_cmd_descript(qc->tf.command), + qc->hw_tag, get_prot_descript(qc->tf.protocol), + ap->link.active_tag, ap->link.sactive); +#endif + if (!ata_is_ncq(qc->tf.protocol)) tag = 0; @@ -1032,9 +1110,11 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) sactive |= (0x00000001 << tag); sata_dwc_scr_write(&ap->link, SCR_ACTIVE, sactive); - trace_ata_tf_load(ap, &qc->tf); + dev_dbg(qc->ap->dev, + "%s: tag=%d ap->link.sactive = 0x%08x sactive=0x%08x\n", + __func__, tag, qc->ap->link.sactive, sactive); + ap->ops->sff_tf_load(ap, &qc->tf); - trace_ata_exec_command(ap, &qc->tf, tag); sata_dwc_exec_command_by_tag(ap, &qc->tf, tag, SATA_DWC_CMD_ISSUED_PEND); } else { @@ -1127,8 +1207,6 @@ static const struct ata_port_info sata_dwc_port_info[] = { static int sata_dwc_probe(struct platform_device *ofdev) { - struct device *dev = &ofdev->dev; - struct device_node *np = dev->of_node; struct sata_dwc_device *hsdev; u32 idr, versionr; char *ver = (char *)&versionr; @@ -1138,21 +1216,23 @@ static int sata_dwc_probe(struct platform_device *ofdev) struct ata_host *host; struct ata_port_info pi = sata_dwc_port_info[0]; const struct ata_port_info *ppi[] = { &pi, NULL }; + struct device_node *np = ofdev->dev.of_node; struct resource *res; /* Allocate DWC SATA device */ - host = ata_host_alloc_pinfo(dev, ppi, SATA_DWC_MAX_PORTS); - hsdev = devm_kzalloc(dev, sizeof(*hsdev), GFP_KERNEL); + host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_DWC_MAX_PORTS); + hsdev = devm_kzalloc(&ofdev->dev, sizeof(*hsdev), GFP_KERNEL); if (!host || !hsdev) return -ENOMEM; host->private_data = hsdev; /* Ioremap SATA registers */ - base = devm_platform_get_and_ioremap_resource(ofdev, 0, &res); + res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&ofdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); - dev_dbg(dev, "ioremap done for SATA register address\n"); + dev_dbg(&ofdev->dev, "ioremap done for SATA register address\n"); /* Synopsys DWC SATA specific Registers */ hsdev->sata_dwc_regs = base + SATA_DWC_REG_OFFSET; @@ -1166,10 +1246,11 @@ static int sata_dwc_probe(struct platform_device *ofdev) /* Read the ID and Version Registers */ idr = sata_dwc_readl(&hsdev->sata_dwc_regs->idr); versionr = sata_dwc_readl(&hsdev->sata_dwc_regs->versionr); - dev_notice(dev, "id %d, controller version %c.%c%c\n", idr, ver[0], ver[1], ver[2]); + dev_notice(&ofdev->dev, "id %d, controller version %c.%c%c\n", + idr, ver[0], ver[1], ver[2]); /* Save dev for later use in dev_xxx() routines */ - hsdev->dev = dev; + hsdev->dev = &ofdev->dev; /* Enable SATA Interrupts */ sata_dwc_enable_interrupts(hsdev); @@ -1177,7 +1258,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) /* Get SATA interrupt number */ irq = irq_of_parse_and_map(np, 0); if (irq == NO_IRQ) { - dev_err(dev, "no SATA DMA irq\n"); + dev_err(&ofdev->dev, "no SATA DMA irq\n"); return -ENODEV; } @@ -1189,7 +1270,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) } #endif - hsdev->phy = devm_phy_optional_get(dev, "sata-phy"); + hsdev->phy = devm_phy_optional_get(hsdev->dev, "sata-phy"); if (IS_ERR(hsdev->phy)) return PTR_ERR(hsdev->phy); @@ -1204,7 +1285,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) */ err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); if (err) - dev_err(dev, "failed to activate host"); + dev_err(&ofdev->dev, "failed to activate host"); return 0; @@ -1228,7 +1309,7 @@ static int sata_dwc_remove(struct platform_device *ofdev) sata_dwc_dma_exit_old(hsdev); #endif - dev_dbg(dev, "done\n"); + dev_dbg(&ofdev->dev, "done\n"); return 0; } diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 556034a154..3b31a4f596 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -221,10 +221,10 @@ enum { * 4 Dwords per command slot, command header size == 64 Dwords. */ struct cmdhdr_tbl_entry { - __le32 cda; - __le32 prde_fis_len; - __le32 ttl; - __le32 desc_info; + u32 cda; + u32 prde_fis_len; + u32 ttl; + u32 desc_info; }; /* @@ -246,10 +246,8 @@ enum { struct command_desc { u8 cfis[8 * 4]; u8 sfis[8 * 4]; - struct_group(cdb, - u8 acmd[4 * 4]; - u8 fill[4 * 4]; - ); + u8 acmd[4 * 4]; + u8 fill[4 * 4]; u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4]; u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4]; }; @@ -259,9 +257,9 @@ struct command_desc { */ struct prde { - __le32 dba; + u32 dba; u8 fill[2 * 4]; - __le32 ddc_and_ext; + u32 ddc_and_ext; }; /* @@ -313,16 +311,16 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host, intr_coalescing_ticks = ticks; spin_unlock_irqrestore(&host->lock, flags); - dev_dbg(host->dev, "interrupt coalescing, count = 0x%x, ticks = %x\n", - intr_coalescing_count, intr_coalescing_ticks); - dev_dbg(host->dev, "ICC register status: (hcr base: 0x%p) = 0x%x\n", - hcr_base, ioread32(hcr_base + ICC)); + DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n", + intr_coalescing_count, intr_coalescing_ticks); + DPRINTK("ICC register status: (hcr base: %p) = 0x%x\n", + hcr_base, ioread32(hcr_base + ICC)); } static ssize_t fsl_sata_intr_coalescing_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sysfs_emit(buf, "%u %u\n", + return sprintf(buf, "%d %d\n", intr_coalescing_count, intr_coalescing_ticks); } @@ -332,8 +330,10 @@ static ssize_t fsl_sata_intr_coalescing_store(struct device *dev, { unsigned int coalescing_count, coalescing_ticks; - if (sscanf(buf, "%u%u", &coalescing_count, &coalescing_ticks) != 2) { - dev_err(dev, "fsl-sata: wrong parameter format.\n"); + if (sscanf(buf, "%d%d", + &coalescing_count, + &coalescing_ticks) != 2) { + printk(KERN_ERR "fsl-sata: wrong parameter format.\n"); return -EINVAL; } @@ -355,9 +355,9 @@ static ssize_t fsl_sata_rx_watermark_show(struct device *dev, spin_lock_irqsave(&host->lock, flags); rx_watermark = ioread32(csr_base + TRANSCFG); rx_watermark &= 0x1f; - spin_unlock_irqrestore(&host->lock, flags); - return sysfs_emit(buf, "%u\n", rx_watermark); + spin_unlock_irqrestore(&host->lock, flags); + return sprintf(buf, "%d\n", rx_watermark); } static ssize_t fsl_sata_rx_watermark_store(struct device *dev, @@ -371,8 +371,8 @@ static ssize_t fsl_sata_rx_watermark_store(struct device *dev, void __iomem *csr_base = host_priv->csr_base; u32 temp; - if (kstrtouint(buf, 10, &rx_watermark) < 0) { - dev_err(dev, "fsl-sata: wrong parameter format.\n"); + if (sscanf(buf, "%d", &rx_watermark) != 1) { + printk(KERN_ERR "fsl-sata: wrong parameter format.\n"); return -EINVAL; } @@ -380,32 +380,30 @@ static ssize_t fsl_sata_rx_watermark_store(struct device *dev, temp = ioread32(csr_base + TRANSCFG); temp &= 0xffffffe0; iowrite32(temp | rx_watermark, csr_base + TRANSCFG); - spin_unlock_irqrestore(&host->lock, flags); + spin_unlock_irqrestore(&host->lock, flags); return strlen(buf); } -static inline unsigned int sata_fsl_tag(struct ata_port *ap, - unsigned int tag, +static inline unsigned int sata_fsl_tag(unsigned int tag, void __iomem *hcr_base) { /* We let libATA core do actual (queue) tag allocation */ if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) { - ata_port_dbg(ap, "tag %d invalid : out of range\n", tag); + DPRINTK("tag %d invalid : out of range\n", tag); return 0; } if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) { - ata_port_dbg(ap, "tag %d invalid : in use!!\n", tag); + DPRINTK("tag %d invalid : in use!!\n", tag); return 0; } return tag; } -static void sata_fsl_setup_cmd_hdr_entry(struct ata_port *ap, - struct sata_fsl_port_priv *pp, +static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp, unsigned int tag, u32 desc_info, u32 data_xfer_len, u8 num_prde, u8 fis_len) @@ -423,11 +421,11 @@ static void sata_fsl_setup_cmd_hdr_entry(struct ata_port *ap, pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03); pp->cmdslot[tag].desc_info = cpu_to_le32(desc_info | (tag & 0x1F)); - ata_port_dbg(ap, "cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n", - le32_to_cpu(pp->cmdslot[tag].cda), - le32_to_cpu(pp->cmdslot[tag].prde_fis_len), - le32_to_cpu(pp->cmdslot[tag].ttl), - le32_to_cpu(pp->cmdslot[tag].desc_info)); + VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n", + pp->cmdslot[tag].cda, + pp->cmdslot[tag].prde_fis_len, + pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info); + } static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, @@ -449,6 +447,8 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, dma_addr_t indirect_ext_segment_paddr; unsigned int si; + VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd); + indirect_ext_segment_paddr = cmd_desc_paddr + SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; @@ -456,6 +456,9 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); + VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%llx, sg_len = %d\n", + (unsigned long long)sg_addr, sg_len); + /* warn if each s/g element is not dword aligned */ if (unlikely(sg_addr & 0x03)) ata_port_err(qc->ap, "s/g addr unaligned : 0x%llx\n", @@ -466,6 +469,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, if (num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1) && sg_next(sg) != NULL) { + VPRINTK("setting indirect prde\n"); prd_ptr_to_indirect_ext = prd; prd->dba = cpu_to_le32(indirect_ext_segment_paddr); indirect_ext_segment_sz = 0; @@ -477,6 +481,9 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, prd->dba = cpu_to_le32(sg_addr); prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03)); + VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", + ttl_dwords, prd->dba, prd->ddc_and_ext); + ++num_prde; ++prd; if (prd_ptr_to_indirect_ext) @@ -501,7 +508,7 @@ static enum ata_completion_errors sata_fsl_qc_prep(struct ata_queued_cmd *qc) struct sata_fsl_port_priv *pp = ap->private_data; struct sata_fsl_host_priv *host_priv = ap->host->private_data; void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(ap, qc->hw_tag, hcr_base); + unsigned int tag = sata_fsl_tag(qc->hw_tag, hcr_base); struct command_desc *cd; u32 desc_info = CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE; u32 num_prde = 0; @@ -513,11 +520,19 @@ static enum ata_completion_errors sata_fsl_qc_prep(struct ata_queued_cmd *qc) ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, (u8 *) &cd->cfis); + VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", + cd->cfis[0], cd->cfis[1], cd->cfis[2]); + + if (qc->tf.protocol == ATA_PROT_NCQ) { + VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d\n", + cd->cfis[3], cd->cfis[11]); + } + /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */ if (ata_is_atapi(qc->tf.protocol)) { desc_info |= ATAPI_CMD; - memset(&cd->cdb, 0, sizeof(cd->cdb)); - memcpy(&cd->cdb, qc->cdb, qc->dev->cdb_len); + memset((void *)&cd->acmd, 0, 32); + memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len); } if (qc->flags & ATA_QCFLAG_DMAMAP) @@ -528,10 +543,10 @@ static enum ata_completion_errors sata_fsl_qc_prep(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_NCQ) desc_info |= FPDMA_QUEUED_CMD; - sata_fsl_setup_cmd_hdr_entry(ap, pp, tag, desc_info, ttl_dwords, + sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords, num_prde, 5); - ata_port_dbg(ap, "SATA FSL : di = 0x%x, ttl = %d, num_prde = %d\n", + VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n", desc_info, ttl_dwords, num_prde); return AC_ERR_OK; @@ -542,9 +557,9 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct sata_fsl_host_priv *host_priv = ap->host->private_data; void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(ap, qc->hw_tag, hcr_base); + unsigned int tag = sata_fsl_tag(qc->hw_tag, hcr_base); - ata_port_dbg(ap, "CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n", + VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n", ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CE + hcr_base), ioread32(CC + hcr_base)); @@ -554,10 +569,10 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) /* Simply queue command to the controller/device */ iowrite32(1 << tag, CQ + hcr_base); - ata_port_dbg(ap, "tag=%d, CQ=0x%x, CA=0x%x\n", + VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x\n", tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base)); - ata_port_dbg(ap, "CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n", + VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n", ioread32(CE + hcr_base), ioread32(DE + hcr_base), ioread32(CC + hcr_base), @@ -571,7 +586,7 @@ static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc) struct sata_fsl_port_priv *pp = qc->ap->private_data; struct sata_fsl_host_priv *host_priv = qc->ap->host->private_data; void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(qc->ap, qc->hw_tag, hcr_base); + unsigned int tag = sata_fsl_tag(qc->hw_tag, hcr_base); struct command_desc *cd; cd = pp->cmdentry + tag; @@ -598,7 +613,7 @@ static int sata_fsl_scr_write(struct ata_link *link, return -EINVAL; } - ata_link_dbg(link, "reg_in = %d\n", sc_reg); + VPRINTK("xx_scr_write, reg_in = %d\n", sc_reg); iowrite32(val, ssr_base + (sc_reg * 4)); return 0; @@ -622,7 +637,7 @@ static int sata_fsl_scr_read(struct ata_link *link, return -EINVAL; } - ata_link_dbg(link, "reg_in = %d\n", sc_reg); + VPRINTK("xx_scr_read, reg_in = %d\n", sc_reg); *val = ioread32(ssr_base + (sc_reg * 4)); return 0; @@ -634,18 +649,18 @@ static void sata_fsl_freeze(struct ata_port *ap) void __iomem *hcr_base = host_priv->hcr_base; u32 temp; - ata_port_dbg(ap, "CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n", + VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n", ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CE + hcr_base), ioread32(DE + hcr_base)); - ata_port_dbg(ap, "CmdStat = 0x%x\n", + VPRINTK("CmdStat = 0x%x\n", ioread32(host_priv->csr_base + COMMANDSTAT)); /* disable interrupts on the controller/port */ temp = ioread32(hcr_base + HCONTROL); iowrite32((temp & ~0x3F), hcr_base + HCONTROL); - ata_port_dbg(ap, "HControl = 0x%x, HStatus = 0x%x\n", + VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x\n", ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); } @@ -658,7 +673,7 @@ static void sata_fsl_thaw(struct ata_port *ap) /* ack. any pending IRQs for this controller/port */ temp = ioread32(hcr_base + HSTATUS); - ata_port_dbg(ap, "pending IRQs = 0x%x\n", (temp & 0x3F)); + VPRINTK("xx_thaw, pending IRQs = 0x%x\n", (temp & 0x3F)); if (temp & 0x3F) iowrite32((temp & 0x3F), hcr_base + HSTATUS); @@ -667,7 +682,7 @@ static void sata_fsl_thaw(struct ata_port *ap) temp = ioread32(hcr_base + HCONTROL); iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL); - ata_port_dbg(ap, "HControl = 0x%x, HStatus = 0x%x\n", + VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x\n", ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); } @@ -729,9 +744,8 @@ static int sata_fsl_port_start(struct ata_port *ap) ap->private_data = pp; - ata_port_dbg(ap, "CHBA = 0x%lx, cmdentry_phys = 0x%lx\n", - (unsigned long)pp->cmdslot_paddr, - (unsigned long)pp->cmdentry_paddr); + VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x\n", + pp->cmdslot_paddr, pp->cmdentry_paddr); /* Now, update the CHBA register in host controller cmd register set */ iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA); @@ -747,9 +761,9 @@ static int sata_fsl_port_start(struct ata_port *ap) temp = ioread32(hcr_base + HCONTROL); iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL); - ata_port_dbg(ap, "HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - ata_port_dbg(ap, "HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - ata_port_dbg(ap, "CHBA = 0x%x\n", ioread32(hcr_base + CHBA)); + VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); + VPRINTK("CHBA = 0x%x\n", ioread32(hcr_base + CHBA)); return 0; } @@ -789,15 +803,16 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap) temp = ioread32(hcr_base + SIGNATURE); - ata_port_dbg(ap, "HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - ata_port_dbg(ap, "HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); + VPRINTK("raw sig = 0x%x\n", temp); + VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); tf.lbah = (temp >> 24) & 0xff; tf.lbam = (temp >> 16) & 0xff; tf.lbal = (temp >> 8) & 0xff; tf.nsect = temp & 0xff; - return ata_port_classify(ap, &tf); + return ata_dev_classify(&tf); } static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, @@ -810,6 +825,8 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, int i = 0; unsigned long start_jiffies; + DPRINTK("in xx_hardreset\n"); + try_offline_again: /* * Force host controller to go off-line, aborting current operations @@ -835,10 +852,9 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, goto try_offline_again; } - ata_port_dbg(ap, "hardreset, controller off-lined\n" - "HStatus = 0x%x HControl = 0x%x\n", - ioread32(hcr_base + HSTATUS), - ioread32(hcr_base + HCONTROL)); + DPRINTK("hardreset, controller off-lined\n"); + VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); /* * PHY reset should remain asserted for atleast 1ms @@ -866,10 +882,9 @@ static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, goto err; } - ata_port_dbg(ap, "controller off-lined & on-lined\n" - "HStatus = 0x%x HControl = 0x%x\n", - ioread32(hcr_base + HSTATUS), - ioread32(hcr_base + HCONTROL)); + DPRINTK("hardreset, controller off-lined & on-lined\n"); + VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); /* * First, wait for the PHYRDY change to occur before waiting for @@ -926,7 +941,10 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, u8 *cfis; u32 Serror; + DPRINTK("in xx_softreset\n"); + if (ata_link_offline(link)) { + DPRINTK("PHY reports no device\n"); *class = ATA_DEV_NONE; return 0; } @@ -939,17 +957,19 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, * reached here, we can send a command to the target device */ + DPRINTK("Sending SRST/device reset\n"); + ata_tf_init(link->device, &tf); cfis = (u8 *) &pp->cmdentry->cfis; /* device reset/SRST is a control register update FIS, uses tag0 */ - sata_fsl_setup_cmd_hdr_entry(ap, pp, 0, + sata_fsl_setup_cmd_hdr_entry(pp, 0, SRST_CMD | CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ ata_tf_to_fis(&tf, pmp, 0, cfis); - ata_port_dbg(ap, "Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", + DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", cfis[0], cfis[1], cfis[2], cfis[3]); /* @@ -957,7 +977,7 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, * other commands are active on the controller/device */ - ata_port_dbg(ap, "CQ = 0x%x, CA = 0x%x, CC = 0x%x\n", + DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x\n", ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CC + hcr_base)); @@ -970,16 +990,15 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, if (temp & 0x1) { ata_port_warn(ap, "ATA_SRST issue failed\n"); - ata_port_dbg(ap, "Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n", + DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n", ioread32(CQ + hcr_base), ioread32(CA + hcr_base), ioread32(CC + hcr_base)); sata_fsl_scr_read(&ap->link, SCR_ERROR, &Serror); - ata_port_dbg(ap, "HStatus = 0x%x HControl = 0x%x Serror = 0x%x\n", - ioread32(hcr_base + HSTATUS), - ioread32(hcr_base + HCONTROL), - Serror); + DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); + DPRINTK("Serror = 0x%x\n", Serror); goto err; } @@ -993,9 +1012,8 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, * using ATA signature D2H register FIS to the host controller. */ - sata_fsl_setup_cmd_hdr_entry(ap, pp, 0, - CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, - 0, 0, 5); + sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_RES | CMD_DESC_SNOOP_ENABLE, + 0, 0, 5); tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ ata_tf_to_fis(&tf, pmp, 0, cfis); @@ -1012,6 +1030,8 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, */ iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */ + DPRINTK("SATA FSL : Now checking device signature\n"); + *class = ATA_DEV_NONE; /* Verify if SStatus indicates device presence */ @@ -1025,8 +1045,9 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, *class = sata_fsl_dev_classify(ap); - ata_port_dbg(ap, "ccreg = 0x%x\n", ioread32(hcr_base + CC)); - ata_port_dbg(ap, "cereg = 0x%x\n", ioread32(hcr_base + CE)); + DPRINTK("class = %d\n", *class); + VPRINTK("ccreg = 0x%x\n", ioread32(hcr_base + CC)); + VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); } return 0; @@ -1037,7 +1058,10 @@ static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, static void sata_fsl_error_handler(struct ata_port *ap) { + + DPRINTK("in xx_error_handler\n"); sata_pmp_error_handler(ap); + } static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) @@ -1078,7 +1102,7 @@ static void sata_fsl_error_intr(struct ata_port *ap) if (unlikely(SError & 0xFFFF0000)) sata_fsl_scr_write(&ap->link, SCR_ERROR, SError); - ata_port_dbg(ap, "hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", + DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", hstatus, cereg, ioread32(hcr_base + DE), SError); /* handle fatal errors */ @@ -1095,7 +1119,7 @@ static void sata_fsl_error_intr(struct ata_port *ap) /* Handle PHYRDY change notification */ if (hstatus & INT_ON_PHYRDY_CHG) { - ata_port_dbg(ap, "PHYRDY change indication\n"); + DPRINTK("SATA FSL: PHYRDY change indication\n"); /* Setup a soft-reset EH action */ ata_ehi_hotplugged(ehi); @@ -1116,7 +1140,7 @@ static void sata_fsl_error_intr(struct ata_port *ap) */ abort = 1; - ata_port_dbg(ap, "single device error, CE=0x%x, DE=0x%x\n", + DPRINTK("single device error, CE=0x%x, DE=0x%x\n", ioread32(hcr_base + CE), ioread32(hcr_base + DE)); /* find out the offending link and qc */ @@ -1221,18 +1245,18 @@ static void sata_fsl_host_intr(struct ata_port *ap) } if (unlikely(SError & 0xFFFF0000)) { - ata_port_dbg(ap, "serror @host_intr : 0x%x\n", SError); + DPRINTK("serror @host_intr : 0x%x\n", SError); sata_fsl_error_intr(ap); } if (unlikely(hstatus & status_mask)) { - ata_port_dbg(ap, "error interrupt!!\n"); + DPRINTK("error interrupt!!\n"); sata_fsl_error_intr(ap); return; } - ata_port_dbg(ap, "Status of all queues :\n"); - ata_port_dbg(ap, "done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%llx\n", + VPRINTK("Status of all queues :\n"); + VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%llx\n", done_mask, ioread32(hcr_base + CA), ioread32(hcr_base + CE), @@ -1244,13 +1268,15 @@ static void sata_fsl_host_intr(struct ata_port *ap) /* clear CC bit, this will also complete the interrupt */ iowrite32(done_mask, hcr_base + CC); - ata_port_dbg(ap, "Status of all queues: done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n", + DPRINTK("Status of all queues :\n"); + DPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x\n", done_mask, ioread32(hcr_base + CA), ioread32(hcr_base + CE)); for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { if (done_mask & (1 << i)) - ata_port_dbg(ap, "completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", + DPRINTK + ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", i, ioread32(hcr_base + CC), ioread32(hcr_base + CA)); } @@ -1261,7 +1287,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) iowrite32(1, hcr_base + CC); qc = ata_qc_from_tag(ap, ATA_TAG_INTERNAL); - ata_port_dbg(ap, "completing non-ncq cmd, CC=0x%x\n", + DPRINTK("completing non-ncq cmd, CC=0x%x\n", ioread32(hcr_base + CC)); if (qc) { @@ -1269,7 +1295,7 @@ static void sata_fsl_host_intr(struct ata_port *ap) } } else { /* Spurious Interrupt!! */ - ata_port_dbg(ap, "spurious interrupt!!, CC = 0x%x\n", + DPRINTK("spurious interrupt!!, CC = 0x%x\n", ioread32(hcr_base + CC)); iowrite32(done_mask, hcr_base + CC); return; @@ -1289,6 +1315,8 @@ static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance) interrupt_enables = ioread32(hcr_base + HSTATUS); interrupt_enables &= 0x3F; + DPRINTK("interrupt status 0x%x\n", interrupt_enables); + if (!interrupt_enables) return IRQ_NONE; @@ -1341,7 +1369,7 @@ static int sata_fsl_init_controller(struct ata_host *host) iowrite32((temp & ~0x3F), hcr_base + HCONTROL); /* Disable interrupt coalescing control(icc), for the moment */ - dev_dbg(host->dev, "icc = 0x%x\n", ioread32(hcr_base + ICC)); + DPRINTK("icc = 0x%x\n", ioread32(hcr_base + ICC)); iowrite32(0x01000000, hcr_base + ICC); /* clear error registers, SError is cleared by libATA */ @@ -1360,8 +1388,8 @@ static int sata_fsl_init_controller(struct ata_host *host) * callback, that should also initiate the OOB, COMINIT sequence */ - dev_dbg(host->dev, "HStatus = 0x%x HControl = 0x%x\n", - ioread32(hcr_base + HSTATUS), ioread32(hcr_base + HCONTROL)); + DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); + DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); return 0; } @@ -1378,7 +1406,8 @@ static void sata_fsl_host_stop(struct ata_host *host) * scsi mid-layer and libata interface structures */ static struct scsi_host_template sata_fsl_sht = { - ATA_NCQ_SHT_QD("sata_fsl", SATA_FSL_QUEUE_DEPTH), + ATA_NCQ_SHT("sata_fsl"), + .can_queue = SATA_FSL_QUEUE_DEPTH, .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, .dma_boundary = ATA_DMA_BOUNDARY, }; @@ -1449,8 +1478,9 @@ static int sata_fsl_probe(struct platform_device *ofdev) iowrite32(temp | TRANSCFG_RX_WATER_MARK, csr_base + TRANSCFG); } - dev_dbg(&ofdev->dev, "@reset i/o = 0x%x\n", - ioread32(csr_base + TRANSCFG)); + DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG)); + DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc)); + DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE); host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL); if (!host_priv) diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 440a63de20..f793564f3d 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -253,12 +253,12 @@ static int gemini_sata_bridge_init(struct sata_gemini *sg) ret = clk_prepare_enable(sg->sata0_pclk); if (ret) { - dev_err(dev, "failed to enable SATA0 PCLK\n"); + pr_err("failed to enable SATA0 PCLK\n"); return ret; } ret = clk_prepare_enable(sg->sata1_pclk); if (ret) { - dev_err(dev, "failed to enable SATA1 PCLK\n"); + pr_err("failed to enable SATA1 PCLK\n"); clk_disable_unprepare(sg->sata0_pclk); return ret; } diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index b29d3f1d64..8440203e83 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -469,8 +469,10 @@ static int ahci_highbank_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + dev_err(dev, "no irq\n"); return irq; + } if (!irq) return -EINVAL; diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 781901151d..e517bd8822 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -488,6 +488,8 @@ static enum ata_completion_errors inic_qc_prep(struct ata_queued_cmd *qc) bool is_data = ata_is_data(qc->tf.protocol); unsigned int cdb_len = 0; + VPRINTK("ENTER\n"); + if (is_atapi) cdb_len = qc->dev->cdb_len; @@ -655,7 +657,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class, } inic_tf_read(ap, &tf); - *class = ata_port_classify(ap, &tf); + *class = ata_dev_classify(&tf); } return 0; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 53446b9977..c53633d47b 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -579,7 +579,7 @@ struct mv_hw_ops { void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio); void (*read_preamp)(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); - int (*reset_hc)(struct ata_host *host, void __iomem *mmio, + int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc); void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); void (*reset_bus)(struct ata_host *host, void __iomem *mmio); @@ -606,7 +606,7 @@ static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv5_reset_hc(struct ata_host *host, void __iomem *mmio, +static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc); static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv5_reset_bus(struct ata_host *host, void __iomem *mmio); @@ -616,14 +616,14 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, +static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc); static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv_soc_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); static void mv_soc_read_preamp(struct mv_host_priv *hpriv, int idx, void __iomem *mmio); -static int mv_soc_reset_hc(struct ata_host *host, +static int mv_soc_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc); static void mv_soc_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); @@ -670,7 +670,7 @@ static struct scsi_host_template mv6_sht = { .can_queue = MV_MAX_Q_DEPTH - 1, .sg_tablesize = MV_MAX_SG_CT / 2, .dma_boundary = MV_DMA_BOUNDARY, - .sdev_groups = ata_ncq_sdev_groups, + .sdev_attrs = ata_ncq_sdev_attrs, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, .slave_configure = ata_scsi_slave_config @@ -1248,74 +1248,81 @@ static int mv_stop_edma(struct ata_port *ap) return err; } -static void mv_dump_mem(struct device *dev, void __iomem *start, unsigned bytes) +#ifdef ATA_DEBUG +static void mv_dump_mem(void __iomem *start, unsigned bytes) { - int b, w, o; - unsigned char linebuf[38]; - + int b, w; for (b = 0; b < bytes; ) { - for (w = 0, o = 0; b < bytes && w < 4; w++) { - o += snprintf(linebuf + o, sizeof(linebuf) - o, - "%08x ", readl(start + b)); + DPRINTK("%p: ", start + b); + for (w = 0; b < bytes && w < 4; w++) { + printk("%08x ", readl(start + b)); b += sizeof(u32); } - dev_dbg(dev, "%s: %p: %s\n", - __func__, start + b, linebuf); + printk("\n"); } } - +#endif +#if defined(ATA_DEBUG) || defined(CONFIG_PCI) static void mv_dump_pci_cfg(struct pci_dev *pdev, unsigned bytes) { - int b, w, o; - u32 dw = 0; - unsigned char linebuf[38]; - +#ifdef ATA_DEBUG + int b, w; + u32 dw; for (b = 0; b < bytes; ) { - for (w = 0, o = 0; b < bytes && w < 4; w++) { + DPRINTK("%02x: ", b); + for (w = 0; b < bytes && w < 4; w++) { (void) pci_read_config_dword(pdev, b, &dw); - o += snprintf(linebuf + o, sizeof(linebuf) - o, - "%08x ", dw); + printk("%08x ", dw); b += sizeof(u32); } - dev_dbg(&pdev->dev, "%s: %02x: %s\n", - __func__, b, linebuf); + printk("\n"); } +#endif } - -static void mv_dump_all_regs(void __iomem *mmio_base, +#endif +static void mv_dump_all_regs(void __iomem *mmio_base, int port, struct pci_dev *pdev) { - void __iomem *hc_base; +#ifdef ATA_DEBUG + void __iomem *hc_base = mv_hc_base(mmio_base, + port >> MV_PORT_HC_SHIFT); void __iomem *port_base; int start_port, num_ports, p, start_hc, num_hcs, hc; - start_hc = start_port = 0; - num_ports = 8; /* should be benign for 4 port devs */ - num_hcs = 2; - dev_dbg(&pdev->dev, - "%s: All registers for port(s) %u-%u:\n", __func__, - start_port, num_ports > 1 ? num_ports - 1 : start_port); + if (0 > port) { + start_hc = start_port = 0; + num_ports = 8; /* shld be benign for 4 port devs */ + num_hcs = 2; + } else { + start_hc = port >> MV_PORT_HC_SHIFT; + start_port = port; + num_ports = num_hcs = 1; + } + DPRINTK("All registers for port(s) %u-%u:\n", start_port, + num_ports > 1 ? num_ports - 1 : start_port); - dev_dbg(&pdev->dev, "%s: PCI config space regs:\n", __func__); - mv_dump_pci_cfg(pdev, 0x68); - - dev_dbg(&pdev->dev, "%s: PCI regs:\n", __func__); - mv_dump_mem(&pdev->dev, mmio_base+0xc00, 0x3c); - mv_dump_mem(&pdev->dev, mmio_base+0xd00, 0x34); - mv_dump_mem(&pdev->dev, mmio_base+0xf00, 0x4); - mv_dump_mem(&pdev->dev, mmio_base+0x1d00, 0x6c); + if (NULL != pdev) { + DPRINTK("PCI config space regs:\n"); + mv_dump_pci_cfg(pdev, 0x68); + } + DPRINTK("PCI regs:\n"); + mv_dump_mem(mmio_base+0xc00, 0x3c); + mv_dump_mem(mmio_base+0xd00, 0x34); + mv_dump_mem(mmio_base+0xf00, 0x4); + mv_dump_mem(mmio_base+0x1d00, 0x6c); for (hc = start_hc; hc < start_hc + num_hcs; hc++) { hc_base = mv_hc_base(mmio_base, hc); - dev_dbg(&pdev->dev, "%s: HC regs (HC %i):\n", __func__, hc); - mv_dump_mem(&pdev->dev, hc_base, 0x1c); + DPRINTK("HC regs (HC %i):\n", hc); + mv_dump_mem(hc_base, 0x1c); } for (p = start_port; p < start_port + num_ports; p++) { port_base = mv_port_base(mmio_base, p); - dev_dbg(&pdev->dev, "%s: EDMA regs (port %i):\n", __func__, p); - mv_dump_mem(&pdev->dev, port_base, 0x54); - dev_dbg(&pdev->dev, "%s: SATA regs (port %i):\n", __func__, p); - mv_dump_mem(&pdev->dev, port_base+0x300, 0x60); + DPRINTK("EDMA regs (port %i):\n", p); + mv_dump_mem(port_base, 0x54); + DPRINTK("SATA regs (port %i):\n", p); + mv_dump_mem(port_base+0x300, 0x60); } +#endif } static unsigned int mv_scr_offset(unsigned int sc_reg_in) @@ -2955,8 +2962,8 @@ static int mv_pci_error(struct ata_host *host, void __iomem *mmio) dev_err(host->dev, "PCI ERROR; PCI IRQ cause=0x%08x\n", err_cause); - dev_dbg(host->dev, "%s: All regs @ PCI error\n", __func__); - mv_dump_all_regs(mmio, to_pci_dev(host->dev)); + DPRINTK("All regs @ PCI error\n"); + mv_dump_all_regs(mmio, -1, to_pci_dev(host->dev)); writelfl(0, mmio + hpriv->irq_cause_offset); @@ -3194,10 +3201,9 @@ static void mv5_reset_one_hc(struct mv_host_priv *hpriv, void __iomem *mmio, } #undef ZERO -static int mv5_reset_hc(struct ata_host *host, void __iomem *mmio, +static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc) { - struct mv_host_priv *hpriv = host->private_data; unsigned int hc, port; for (hc = 0; hc < n_hc; hc++) { @@ -3256,7 +3262,7 @@ static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) * LOCKING: * Inherited from caller. */ -static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, +static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc) { void __iomem *reg = mmio + PCI_MAIN_CMD_STS; @@ -3276,7 +3282,7 @@ static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, break; } if (!(PCI_MASTER_EMPTY & t)) { - dev_err(host->dev, "PCI master won't flush\n"); + printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); rc = 1; goto done; } @@ -3290,7 +3296,7 @@ static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, } while (!(GLOB_SFT_RST & t) && (i-- > 0)); if (!(GLOB_SFT_RST & t)) { - dev_err(host->dev, "can't set global reset\n"); + printk(KERN_ERR DRV_NAME ": can't set global reset\n"); rc = 1; goto done; } @@ -3304,7 +3310,7 @@ static int mv6_reset_hc(struct ata_host *host, void __iomem *mmio, } while ((GLOB_SFT_RST & t) && (i-- > 0)); if (GLOB_SFT_RST & t) { - dev_err(host->dev, "can't clear global reset\n"); + printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); rc = 1; } done: @@ -3473,10 +3479,9 @@ static void mv_soc_reset_one_hc(struct mv_host_priv *hpriv, #undef ZERO -static int mv_soc_reset_hc(struct ata_host *host, +static int mv_soc_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, unsigned int n_hc) { - struct mv_host_priv *hpriv = host->private_data; unsigned int port; for (port = 0; port < hpriv->n_ports; port++) @@ -3718,6 +3723,11 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) /* unmask all non-transient EDMA error interrupts */ writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK); + + VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", + readl(port_mmio + EDMA_CFG), + readl(port_mmio + EDMA_ERR_IRQ_CAUSE), + readl(port_mmio + EDMA_ERR_IRQ_MASK)); } static unsigned int mv_in_pcix_mode(struct ata_host *host) @@ -3849,11 +3859,11 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) * * Warn the user, lest they think we're just buggy. */ - dev_warn(&pdev->dev, "Highpoint RocketRAID" + printk(KERN_WARNING DRV_NAME ": Highpoint RocketRAID" " BIOS CORRUPTS DATA on all attached drives," " regardless of if/how they are configured." " BEWARE!\n"); - dev_warn(&pdev->dev, "For data safety, do not" + printk(KERN_WARNING DRV_NAME ": For data safety, do not" " use sectors 8-9 on \"Legacy\" drives," " and avoid the final two gigabytes on" " all RocketRAID BIOS initialized drives.\n"); @@ -3944,7 +3954,7 @@ static int mv_init_host(struct ata_host *host) if (hpriv->ops->read_preamp) hpriv->ops->read_preamp(hpriv, port, mmio); - rc = hpriv->ops->reset_hc(host, mmio, n_hc); + rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); if (rc) goto done; @@ -3962,7 +3972,7 @@ static int mv_init_host(struct ata_host *host) for (hc = 0; hc < n_hc; hc++) { void __iomem *hc_mmio = mv_hc_base(mmio, hc); - dev_dbg(host->dev, "HC%i: HC config=0x%08x HC IRQ cause " + VPRINTK("HC%i: HC config=0x%08x HC IRQ cause " "(before clear)=0x%08x\n", hc, readl(hc_mmio + HC_CFG), readl(hc_mmio + HC_IRQ_CAUSE)); @@ -4260,7 +4270,7 @@ static int mv_platform_resume(struct platform_device *pdev) /* initialize adapter */ ret = mv_init_host(host); if (ret) { - dev_err(&pdev->dev, "Error during HW init\n"); + printk(KERN_ERR DRV_NAME ": Error during HW init\n"); return ret; } ata_host_resume(host); diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 7f14d0d310..c385d18ce8 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -31,7 +31,6 @@ #include #include #include -#include #define DRV_NAME "sata_nv" #define DRV_VERSION "3.5" @@ -381,7 +380,7 @@ static struct scsi_host_template nv_adma_sht = { .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN, .dma_boundary = NV_ADMA_DMA_BOUNDARY, .slave_configure = nv_adma_slave_config, - .sdev_groups = ata_ncq_sdev_groups, + .sdev_attrs = ata_ncq_sdev_attrs, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; @@ -392,7 +391,7 @@ static struct scsi_host_template nv_swncq_sht = { .sg_tablesize = LIBATA_MAX_PRD, .dma_boundary = ATA_DMA_BOUNDARY, .slave_configure = nv_swncq_slave_config, - .sdev_groups = ata_ncq_sdev_groups, + .sdev_attrs = ata_ncq_sdev_attrs, .change_queue_depth = ata_scsi_change_queue_depth, .tag_alloc_policy = BLK_TAG_ALLOC_RR, }; @@ -809,7 +808,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) struct nv_adma_port_priv *pp = ap->private_data; u8 flags = pp->cpb[cpb_num].resp_flags; - ata_port_dbg(ap, "CPB %d, flags=0x%x\n", cpb_num, flags); + VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags); if (unlikely((force_err || flags & (NV_CPB_RESP_ATA_ERR | @@ -1101,6 +1100,8 @@ static int nv_adma_port_start(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(dev); u16 tmp; + VPRINTK("ENTER\n"); + /* * Ensure DMA mask is set to 32-bit before allocating legacy PRD and * pad buffers. @@ -1189,6 +1190,7 @@ static void nv_adma_port_stop(struct ata_port *ap) struct nv_adma_port_priv *pp = ap->private_data; void __iomem *mmio = pp->ctl_block; + VPRINTK("ENTER\n"); writew(0, mmio + NV_ADMA_CTL); } @@ -1250,6 +1252,8 @@ static void nv_adma_setup_port(struct ata_port *ap) void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR]; struct ata_ioports *ioport = &ap->ioaddr; + VPRINTK("ENTER\n"); + mmio += NV_ADMA_PORT + ap->port_no * NV_ADMA_PORT_SIZE; ioport->cmd_addr = mmio; @@ -1273,6 +1277,8 @@ static int nv_adma_host_init(struct ata_host *host) unsigned int i; u32 tmp32; + VPRINTK("ENTER\n"); + /* enable ADMA on the ports */ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32); tmp32 |= NV_MCP_SATA_CFG_20_PORT0_EN | @@ -1314,6 +1320,8 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb) struct scatterlist *sg; unsigned int si; + VPRINTK("ENTER\n"); + for_each_sg(qc->sg, sg, qc->n_elem, si) { aprd = (si < 5) ? &cpb->aprd[si] : &pp->aprd[NV_ADMA_SGTBL_LEN * qc->hw_tag + (si-5)]; @@ -1370,6 +1378,8 @@ static enum ata_completion_errors nv_adma_qc_prep(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_NCQ) ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA; + VPRINTK("qc->flags = 0x%lx\n", qc->flags); + nv_adma_tf_to_cpb(&qc->tf, cpb->tf); if (qc->flags & ATA_QCFLAG_DMAMAP) { @@ -1394,6 +1404,8 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) void __iomem *mmio = pp->ctl_block; int curr_ncq = (qc->tf.protocol == ATA_PROT_NCQ); + VPRINTK("ENTER\n"); + /* We can't handle result taskfile with NCQ commands, since retrieving the taskfile switches us out of ADMA mode and would abort existing commands. */ @@ -1405,6 +1417,7 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) if (nv_adma_use_reg_mode(qc)) { /* use ATA register mode */ + VPRINTK("using ATA register mode: 0x%lx\n", qc->flags); BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) && (qc->flags & ATA_QCFLAG_DMAMAP)); nv_adma_register_mode(qc->ap); @@ -1425,6 +1438,8 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) writew(qc->hw_tag, mmio + NV_ADMA_APPEND); + DPRINTK("Issued tag %u\n", qc->hw_tag); + return 0; } @@ -1856,12 +1871,12 @@ static void nv_swncq_host_init(struct ata_host *host) /* enable swncq */ tmp = readl(mmio + NV_CTL_MCP55); - dev_dbg(&pdev->dev, "HOST_CTL:0x%X\n", tmp); + VPRINTK("HOST_CTL:0x%X\n", tmp); writel(tmp | NV_CTL_PRI_SWNCQ | NV_CTL_SEC_SWNCQ, mmio + NV_CTL_MCP55); /* enable irq intr */ tmp = readl(mmio + NV_INT_ENABLE_MCP55); - dev_dbg(&pdev->dev, "HOST_ENABLE:0x%X\n", tmp); + VPRINTK("HOST_ENABLE:0x%X\n", tmp); writel(tmp | 0x00fd00fd, mmio + NV_INT_ENABLE_MCP55); /* clear port irq */ @@ -2002,17 +2017,19 @@ static unsigned int nv_swncq_issue_atacmd(struct ata_port *ap, if (qc == NULL) return 0; + DPRINTK("Enter\n"); + writel((1 << qc->hw_tag), pp->sactive_block); pp->last_issue_tag = qc->hw_tag; pp->dhfis_bits &= ~(1 << qc->hw_tag); pp->dmafis_bits &= ~(1 << qc->hw_tag); pp->qc_active |= (0x1 << qc->hw_tag); - trace_ata_tf_load(ap, &qc->tf); ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */ - trace_ata_exec_command(ap, &qc->tf, qc->hw_tag); ap->ops->sff_exec_command(ap, &qc->tf); + DPRINTK("Issued tag %u\n", qc->hw_tag); + return 0; } @@ -2024,6 +2041,8 @@ static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc) if (qc->tf.protocol != ATA_PROT_NCQ) return ata_bmdma_qc_issue(qc); + DPRINTK("Enter\n"); + if (!pp->qc_active) nv_swncq_issue_atacmd(ap, qc); else @@ -2068,7 +2087,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap) u8 lack_dhfis = 0; host_stat = ap->ops->bmdma_status(ap); - trace_ata_bmdma_status(ap, host_stat); if (unlikely(host_stat & ATA_DMA_ERR)) { /* error when transferring data to/from memory */ ata_ehi_clear_desc(ehi); @@ -2091,7 +2109,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); if (!ap->qc_active) { - ata_port_dbg(ap, "over\n"); + DPRINTK("over\n"); nv_swncq_pp_reinit(ap); return 0; } @@ -2106,12 +2124,12 @@ static int nv_swncq_sdbfis(struct ata_port *ap) */ lack_dhfis = 1; - ata_port_dbg(ap, "QC: qc_active 0x%llx," - "SWNCQ:qc_active 0x%X defer_bits %X " - "dhfis 0x%X dmafis 0x%X last_issue_tag %x\n", - ap->qc_active, pp->qc_active, - pp->defer_queue.defer_bits, pp->dhfis_bits, - pp->dmafis_bits, pp->last_issue_tag); + DPRINTK("id 0x%x QC: qc_active 0x%llx," + "SWNCQ:qc_active 0x%X defer_bits %X " + "dhfis 0x%X dmafis 0x%X last_issue_tag %x\n", + ap->print_id, ap->qc_active, pp->qc_active, + pp->defer_queue.defer_bits, pp->dhfis_bits, + pp->dmafis_bits, pp->last_issue_tag); nv_swncq_fis_reinit(ap); @@ -2151,7 +2169,7 @@ static void nv_swncq_dmafis(struct ata_port *ap) __ata_bmdma_stop(ap); tag = nv_swncq_tag(ap); - ata_port_dbg(ap, "dma setup tag 0x%x\n", tag); + DPRINTK("dma setup tag 0x%x\n", tag); qc = ata_qc_from_tag(ap, tag); if (unlikely(!qc)) @@ -2219,9 +2237,9 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) if (fis & NV_SWNCQ_IRQ_SDBFIS) { pp->ncq_flags |= ncq_saw_sdb; - ata_port_dbg(ap, "SWNCQ: qc_active 0x%X " + DPRINTK("id 0x%x SWNCQ: qc_active 0x%X " "dhfis 0x%X dmafis 0x%X sactive 0x%X\n", - pp->qc_active, pp->dhfis_bits, + ap->print_id, pp->qc_active, pp->dhfis_bits, pp->dmafis_bits, readl(pp->sactive_block)); if (nv_swncq_sdbfis(ap) < 0) goto irq_error; @@ -2247,7 +2265,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis) goto irq_exit; if (pp->defer_queue.defer_bits) { - ata_port_dbg(ap, "send next command\n"); + DPRINTK("send next command\n"); qc = nv_swncq_qc_from_dq(ap); nv_swncq_issue_atacmd(ap, qc); } diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index b8465fef2e..7815da8ef9 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -596,8 +596,7 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) prd[idx].addr = cpu_to_le32(addr); prd[idx].flags_len = cpu_to_le32(len & 0xffff); - ata_port_dbg(ap, "PRD[%u] = (0x%X, 0x%X)\n", - idx, addr, len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); idx++; sg_len -= len; @@ -610,16 +609,17 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc) if (len > SG_COUNT_ASIC_BUG) { u32 addr; + VPRINTK("Splitting last PRD.\n"); + addr = le32_to_cpu(prd[idx - 1].addr); prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG); - ata_port_dbg(ap, "PRD[%u] = (0x%X, 0x%X)\n", - idx - 1, addr, SG_COUNT_ASIC_BUG); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG); addr = addr + len - SG_COUNT_ASIC_BUG; len = SG_COUNT_ASIC_BUG; prd[idx].addr = cpu_to_le32(addr); prd[idx].flags_len = cpu_to_le32(len); - ata_port_dbg(ap, "PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); idx++; } @@ -632,6 +632,8 @@ static enum ata_completion_errors pdc_qc_prep(struct ata_queued_cmd *qc) struct pdc_port_priv *pp = qc->ap->private_data; unsigned int i; + VPRINTK("ENTER\n"); + switch (qc->tf.protocol) { case ATA_PROT_DMA: pdc_fill_sg(qc); @@ -920,8 +922,12 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) u32 hotplug_status; int is_sataii_tx4; - if (!host || !host->iomap[PDC_MMIO_BAR]) + VPRINTK("ENTER\n"); + + if (!host || !host->iomap[PDC_MMIO_BAR]) { + VPRINTK("QUICK EXIT\n"); return IRQ_NONE; + } host_mmio = host->iomap[PDC_MMIO_BAR]; @@ -940,18 +946,23 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) /* reading should also clear interrupts */ mask = readl(host_mmio + PDC_INT_SEQMASK); - if (mask == 0xffffffff && hotplug_status == 0) + if (mask == 0xffffffff && hotplug_status == 0) { + VPRINTK("QUICK EXIT 2\n"); goto done_irq; + } mask &= 0xffff; /* only 16 SEQIDs possible */ - if (mask == 0 && hotplug_status == 0) + if (mask == 0 && hotplug_status == 0) { + VPRINTK("QUICK EXIT 3\n"); goto done_irq; + } writel(mask, host_mmio + PDC_INT_SEQMASK); is_sataii_tx4 = pdc_is_sataii_tx4(host->ports[0]->flags); for (i = 0; i < host->n_ports; i++) { + VPRINTK("port %u\n", i); ap = host->ports[i]; /* check for a plug or unplug event */ @@ -978,6 +989,8 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance) } } + VPRINTK("EXIT\n"); + done_irq: spin_unlock(&host->lock); return IRQ_RETVAL(handled); @@ -992,6 +1005,8 @@ static void pdc_packet_start(struct ata_queued_cmd *qc) unsigned int port_no = ap->port_no; u8 seq = (u8) (port_no + 1); + VPRINTK("ENTER, ap %p\n", ap); + writel(0x00000001, host_mmio + (seq * 4)); readl(host_mmio + (seq * 4)); /* flush */ diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 8ca0810aad..ef00ab644a 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -252,6 +252,9 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) len = sg_dma_len(sg); *(__le32 *)prd = cpu_to_le32(len); prd += sizeof(u64); + + VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", si, + (unsigned long long)addr, len); } return si; @@ -265,6 +268,8 @@ static enum ata_completion_errors qs_qc_prep(struct ata_queued_cmd *qc) u64 addr; unsigned int nelem; + VPRINTK("ENTER\n"); + qs_enter_reg_mode(qc->ap); if (qc->tf.protocol != ATA_PROT_DMA) return AC_ERR_OK; @@ -299,6 +304,8 @@ static inline void qs_packet_start(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); + VPRINTK("ENTER, ap %p\n", ap); + writeb(QS_CTR0_CLER, chan + QS_CCT_CTR0); wmb(); /* flush PRDs and pkt to memory */ writel(QS_CCF_RUN_PKT, chan + QS_CCT_CFF); @@ -367,8 +374,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host) struct qs_port_priv *pp = ap->private_data; struct ata_queued_cmd *qc; - dev_dbg(host->dev, "SFF=%08x%08x: sHST=%d sDST=%02x\n", - sff1, sff0, sHST, sDST); + DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", + sff1, sff0, port_no, sHST, sDST); handled = 1; if (!pp || pp->state != qs_state_pkt) continue; @@ -428,10 +435,14 @@ static irqreturn_t qs_intr(int irq, void *dev_instance) unsigned int handled = 0; unsigned long flags; + VPRINTK("ENTER\n"); + spin_lock_irqsave(&host->lock, flags); handled = qs_intr_pkt(host) | qs_intr_mmio(host); spin_unlock_irqrestore(&host->lock, flags); + VPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); } diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 3d96b6faa3..44b0ed8f6b 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -323,6 +323,8 @@ static int sata_rcar_bus_softreset(struct ata_port *ap, unsigned long deadline) { struct ata_ioports *ioaddr = &ap->ioaddr; + DPRINTK("ata%u: bus reset via SRST\n", ap->print_id); + /* software reset. causes dev0 to be selected */ iowrite32(ap->ctl, ioaddr->ctl_addr); udelay(20); @@ -348,6 +350,7 @@ static int sata_rcar_softreset(struct ata_link *link, unsigned int *classes, devmask |= 1 << 0; /* issue bus reset */ + DPRINTK("about to softreset, devmask=%x\n", devmask); rc = sata_rcar_bus_softreset(ap, deadline); /* if link is occupied, -ENODEV too is an error */ if (rc && (rc != -ENODEV || sata_scr_valid(link))) { @@ -358,6 +361,7 @@ static int sata_rcar_softreset(struct ata_link *link, unsigned int *classes, /* determine by signature whether we have ATA or ATAPI devices */ classes[0] = ata_sff_dev_classify(&link->device[0], devmask, &err); + DPRINTK("classes[0]=%u\n", classes[0]); return 0; } @@ -379,6 +383,12 @@ static void sata_rcar_tf_load(struct ata_port *ap, iowrite32(tf->hob_lbal, ioaddr->lbal_addr); iowrite32(tf->hob_lbam, ioaddr->lbam_addr); iowrite32(tf->hob_lbah, ioaddr->lbah_addr); + VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", + tf->hob_feature, + tf->hob_nsect, + tf->hob_lbal, + tf->hob_lbam, + tf->hob_lbah); } if (is_addr) { @@ -387,10 +397,18 @@ static void sata_rcar_tf_load(struct ata_port *ap, iowrite32(tf->lbal, ioaddr->lbal_addr); iowrite32(tf->lbam, ioaddr->lbam_addr); iowrite32(tf->lbah, ioaddr->lbah_addr); + VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", + tf->feature, + tf->nsect, + tf->lbal, + tf->lbam, + tf->lbah); } - if (tf->flags & ATA_TFLAG_DEVICE) + if (tf->flags & ATA_TFLAG_DEVICE) { iowrite32(tf->device, ioaddr->device_addr); + VPRINTK("device 0x%X\n", tf->device); + } ata_wait_idle(ap); } @@ -422,6 +440,8 @@ static void sata_rcar_tf_read(struct ata_port *ap, struct ata_taskfile *tf) static void sata_rcar_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) { + DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); + iowrite32(tf->command, ap->ioaddr.command_addr); ata_sff_pause(ap); } @@ -479,6 +499,7 @@ static void sata_rcar_drain_fifo(struct ata_queued_cmd *qc) count < 65536; count += 2) ioread32(ap->ioaddr.data_addr); + /* Can become DEBUG later */ if (count) ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count); } @@ -522,6 +543,7 @@ static void sata_rcar_bmdma_fill_sg(struct ata_queued_cmd *qc) prd[si].addr = cpu_to_le32(addr); prd[si].flags_len = cpu_to_le32(sg_len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len); } /* end-of-table flag */ @@ -663,7 +685,7 @@ static void sata_rcar_serr_interrupt(struct ata_port *ap) if (!serror) return; - ata_port_dbg(ap, "SError @host_intr: 0x%x\n", serror); + DPRINTK("SError @host_intr: 0x%x\n", serror); /* first, analyze and record host port events */ ata_ehi_clear_desc(ehi); diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 3b989a5287..75321f1ceb 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -307,6 +307,7 @@ static void sil_fill_sg(struct ata_queued_cmd *qc) prd->addr = cpu_to_le32(addr); prd->flags_len = cpu_to_le32(sg_len); + VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len); last_prd = prd; prd++; diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 2fef6ce93f..06a1e27c4f 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -379,7 +379,7 @@ static struct scsi_host_template sil24_sht = { .sg_tablesize = SIL24_MAX_SGE, .dma_boundary = ATA_DMA_BOUNDARY, .tag_alloc_policy = BLK_TAG_ALLOC_FIFO, - .sdev_groups = ata_ncq_sdev_groups, + .sdev_attrs = ata_ncq_sdev_attrs, .change_queue_depth = ata_scsi_change_queue_depth, .slave_configure = ata_scsi_slave_config }; @@ -656,6 +656,8 @@ static int sil24_softreset(struct ata_link *link, unsigned int *class, const char *reason; int rc; + DPRINTK("ENTER\n"); + /* put the port into known state */ if (sil24_init_port(ap)) { reason = "port not ready"; @@ -678,8 +680,9 @@ static int sil24_softreset(struct ata_link *link, unsigned int *class, } sil24_read_tf(ap, 0, &tf); - *class = ata_port_classify(ap, &tf); + *class = ata_dev_classify(&tf); + DPRINTK("EXIT, class=%u\n", *class); return 0; err: diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index 6ceec59cb2..4c01190a5e 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -78,9 +78,6 @@ #define DRV_NAME "sata_sx4" #define DRV_VERSION "0.12" -static int dimm_test; -module_param(dimm_test, int, 0644); -MODULE_PARM_DESC(dimm_test, "Enable DIMM test during startup (1 = enabled)"); enum { PDC_MMIO_BAR = 3, @@ -214,8 +211,10 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device, u32 subaddr, u32 *pdata); static int pdc20621_prog_dimm0(struct ata_host *host); static unsigned int pdc20621_prog_dimm_global(struct ata_host *host); +#ifdef ATA_VERBOSE_DEBUG static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, u32 offset, u32 size); +#endif static void pdc20621_put_to_dimm(struct ata_host *host, void *psource, u32 offset, u32 size); static void pdc20621_irq_clear(struct ata_port *ap); @@ -309,9 +308,15 @@ static inline void pdc20621_ata_sg(u8 *buf, unsigned int portno, /* output ATA packet S/G table */ addr = PDC_20621_DIMM_BASE + PDC_20621_DIMM_DATA + (PDC_DIMM_DATA_STEP * portno); - + VPRINTK("ATA sg addr 0x%x, %d\n", addr, addr); buf32[dw] = cpu_to_le32(addr); buf32[dw + 1] = cpu_to_le32(total_len | ATA_PRD_EOT); + + VPRINTK("ATA PSG @ %x == (0x%x, 0x%x)\n", + PDC_20621_DIMM_BASE + + (PDC_DIMM_WINDOW_STEP * portno) + + PDC_DIMM_APKT_PRD, + buf32[dw], buf32[dw + 1]); } static inline void pdc20621_host_sg(u8 *buf, unsigned int portno, @@ -327,6 +332,12 @@ static inline void pdc20621_host_sg(u8 *buf, unsigned int portno, buf32[dw] = cpu_to_le32(addr); buf32[dw + 1] = cpu_to_le32(total_len | ATA_PRD_EOT); + + VPRINTK("HOST PSG @ %x == (0x%x, 0x%x)\n", + PDC_20621_DIMM_BASE + + (PDC_DIMM_WINDOW_STEP * portno) + + PDC_DIMM_HPKT_PRD, + buf32[dw], buf32[dw + 1]); } static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf, @@ -340,6 +351,7 @@ static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf, unsigned int dimm_sg = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * portno) + PDC_DIMM_APKT_PRD; + VPRINTK("ENTER, dimm_sg == 0x%x, %d\n", dimm_sg, dimm_sg); i = PDC_DIMM_ATA_PKT; @@ -394,6 +406,8 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, unsigned int dimm_sg = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * portno) + PDC_DIMM_HPKT_PRD; + VPRINTK("ENTER, dimm_sg == 0x%x, %d\n", dimm_sg, dimm_sg); + VPRINTK("host_sg == 0x%x, %d\n", host_sg, host_sg); dw = PDC_DIMM_HOST_PKT >> 2; @@ -410,6 +424,14 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, buf32[dw + 1] = cpu_to_le32(host_sg); buf32[dw + 2] = cpu_to_le32(dimm_sg); buf32[dw + 3] = 0; + + VPRINTK("HOST PKT @ %x == (0x%x 0x%x 0x%x 0x%x)\n", + PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * portno) + + PDC_DIMM_HOST_PKT, + buf32[dw + 0], + buf32[dw + 1], + buf32[dw + 2], + buf32[dw + 3]); } static void pdc20621_dma_prep(struct ata_queued_cmd *qc) @@ -425,6 +447,8 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); + VPRINTK("ata%u: ENTER\n", ap->print_id); + /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -468,8 +492,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) readl(dimm_mmio); /* MMIO PCI posting flush */ - ata_port_dbg(ap, "ata pkt buf ofs %u, prd size %u, mmio copied\n", - i, sgt_len); + VPRINTK("ata pkt buf ofs %u, prd size %u, mmio copied\n", i, sgt_len); } static void pdc20621_nodata_prep(struct ata_queued_cmd *qc) @@ -481,6 +504,8 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc) unsigned int portno = ap->port_no; unsigned int i; + VPRINTK("ata%u: ENTER\n", ap->print_id); + /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; @@ -502,7 +527,7 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc) readl(dimm_mmio); /* MMIO PCI posting flush */ - ata_port_dbg(ap, "ata pkt buf ofs %u, mmio copied\n", i); + VPRINTK("ata pkt buf ofs %u, mmio copied\n", i); } static enum ata_completion_errors pdc20621_qc_prep(struct ata_queued_cmd *qc) @@ -576,6 +601,7 @@ static void pdc20621_pop_hdma(struct ata_queued_cmd *qc) pp->hdma_cons++; } +#ifdef ATA_VERBOSE_DEBUG static void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; @@ -585,10 +611,14 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc) dimm_mmio += (port_no * PDC_DIMM_WINDOW_STEP); dimm_mmio += PDC_DIMM_HOST_PKT; - ata_port_dbg(ap, "HDMA 0x%08X 0x%08X 0x%08X 0x%08X\n", - readl(dimm_mmio), readl(dimm_mmio + 4), - readl(dimm_mmio + 8), readl(dimm_mmio + 12)); + printk(KERN_ERR "HDMA[0] == 0x%08X\n", readl(dimm_mmio)); + printk(KERN_ERR "HDMA[1] == 0x%08X\n", readl(dimm_mmio + 4)); + printk(KERN_ERR "HDMA[2] == 0x%08X\n", readl(dimm_mmio + 8)); + printk(KERN_ERR "HDMA[3] == 0x%08X\n", readl(dimm_mmio + 12)); } +#else +static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { } +#endif /* ATA_VERBOSE_DEBUG */ static void pdc20621_packet_start(struct ata_queued_cmd *qc) { @@ -603,6 +633,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) /* hard-code chip #0 */ mmio += PDC_CHIP0_OFS; + VPRINTK("ata%u: ENTER\n", ap->print_id); + wmb(); /* flush PRD, pkt writes */ port_ofs = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * port_no); @@ -613,7 +645,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) pdc20621_dump_hdma(qc); pdc20621_push_hdma(qc, seq, port_ofs + PDC_DIMM_HOST_PKT); - ata_port_dbg(ap, "queued ofs 0x%x (%u), seq %u\n", + VPRINTK("queued ofs 0x%x (%u), seq %u\n", port_ofs + PDC_DIMM_HOST_PKT, port_ofs + PDC_DIMM_HOST_PKT, seq); @@ -624,7 +656,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc) writel(port_ofs + PDC_DIMM_ATA_PKT, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); - ata_port_dbg(ap, "submitted ofs 0x%x (%u), seq %u\n", + VPRINTK("submitted ofs 0x%x (%u), seq %u\n", port_ofs + PDC_DIMM_ATA_PKT, port_ofs + PDC_DIMM_ATA_PKT, seq); @@ -664,12 +696,14 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, u8 status; unsigned int handled = 0; + VPRINTK("ENTER\n"); + if ((qc->tf.protocol == ATA_PROT_DMA) && /* read */ (!(qc->tf.flags & ATA_TFLAG_WRITE))) { /* step two - DMA from DIMM to host */ if (doing_hdma) { - ata_port_dbg(ap, "read hdma, 0x%x 0x%x\n", + VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); @@ -680,7 +714,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, /* step one - exec ATA command */ else { u8 seq = (u8) (port_no + 1 + 4); - ata_port_dbg(ap, "read ata, 0x%x 0x%x\n", + VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit hdma pkt */ @@ -695,7 +729,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, /* step one - DMA from host to DIMM */ if (doing_hdma) { u8 seq = (u8) (port_no + 1); - ata_port_dbg(ap, "write hdma, 0x%x 0x%x\n", + VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* submit ata pkt */ @@ -708,7 +742,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, /* step two - execute ATA command */ else { - ata_port_dbg(ap, "write ata, 0x%x 0x%x\n", + VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->print_id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ qc->err_mask |= ac_err_mask(ata_wait_idle(ap)); @@ -721,7 +755,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap, } else if (qc->tf.protocol == ATA_PROT_NODATA) { status = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - ata_port_dbg(ap, "BUS_NODATA (drv_stat 0x%X)\n", status); + DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); qc->err_mask |= ac_err_mask(status); ata_qc_complete(qc); handled = 1; @@ -747,21 +781,29 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) unsigned int handled = 0; void __iomem *mmio_base; - if (!host || !host->iomap[PDC_MMIO_BAR]) + VPRINTK("ENTER\n"); + + if (!host || !host->iomap[PDC_MMIO_BAR]) { + VPRINTK("QUICK EXIT\n"); return IRQ_NONE; + } mmio_base = host->iomap[PDC_MMIO_BAR]; /* reading should also clear interrupts */ mmio_base += PDC_CHIP0_OFS; mask = readl(mmio_base + PDC_20621_SEQMASK); + VPRINTK("mask == 0x%x\n", mask); - if (mask == 0xffffffff) + if (mask == 0xffffffff) { + VPRINTK("QUICK EXIT 2\n"); return IRQ_NONE; - + } mask &= 0xffff; /* only 16 tags possible */ - if (!mask) + if (!mask) { + VPRINTK("QUICK EXIT 3\n"); return IRQ_NONE; + } spin_lock(&host->lock); @@ -774,8 +816,7 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) else ap = host->ports[port_no]; tmp = mask & (1 << i); - if (ap) - ata_port_dbg(ap, "seq %u, tmp %x\n", i, tmp); + VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); if (tmp && ap) { struct ata_queued_cmd *qc; @@ -788,6 +829,10 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance) spin_unlock(&host->lock); + VPRINTK("mask == 0x%x\n", mask); + + VPRINTK("EXIT\n"); + return IRQ_RETVAL(handled); } @@ -934,6 +979,7 @@ static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base) } +#ifdef ATA_VERBOSE_DEBUG static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, u32 offset, u32 size) { @@ -983,6 +1029,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource, memcpy_fromio(psource, dimm_mmio, size / 4); } } +#endif static void pdc20621_put_to_dimm(struct ata_host *host, void *psource, @@ -1179,16 +1226,15 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host) /* Turn on for ECC */ if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE, &spd0)) { - dev_err(host->dev, - "Failed in i2c read: device=%#x, subaddr=%#x\n", - PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE); + pr_err("Failed in i2c read: device=%#x, subaddr=%#x\n", + PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE); return 1; } if (spd0 == 0x02) { data |= (0x01 << 16); writel(data, mmio + PDC_SDRAM_CONTROL); readl(mmio + PDC_SDRAM_CONTROL); - dev_err(host->dev, "Local DIMM ECC Enabled\n"); + printk(KERN_ERR "Local DIMM ECC Enabled\n"); } /* DIMM Initialization Select/Enable (bit 18/19) */ @@ -1228,7 +1274,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) /* Initialize Time Period Register */ writel(0xffffffff, mmio + PDC_TIME_PERIOD); time_period = readl(mmio + PDC_TIME_PERIOD); - dev_dbg(host->dev, "Time Period Register (0x40): 0x%x\n", time_period); + VPRINTK("Time Period Register (0x40): 0x%x\n", time_period); /* Enable timer */ writel(PDC_TIMER_DEFAULT, mmio + PDC_TIME_CONTROL); @@ -1243,7 +1289,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) */ tcount = readl(mmio + PDC_TIME_COUNTER); - dev_dbg(host->dev, "Time Counter Register (0x44): 0x%x\n", tcount); + VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount); /* If SX4 is on PCI-X bus, after 3 seconds, the timer counter @@ -1251,19 +1297,17 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) */ if (tcount >= PCI_X_TCOUNT) { ticks = (time_period - tcount); - dev_dbg(host->dev, "Num counters 0x%x (%d)\n", ticks, ticks); + VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks); clock = (ticks / 300000); - dev_dbg(host->dev, "10 * Internal clk = 0x%x (%d)\n", - clock, clock); + VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock); clock = (clock * 33); - dev_dbg(host->dev, "10 * Internal clk * 33 = 0x%x (%d)\n", - clock, clock); + VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock); /* PLL F Param (bit 22:16) */ fparam = (1400000 / clock) - 2; - dev_dbg(host->dev, "PLL F Param: 0x%x (%d)\n", fparam, fparam); + VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam); /* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */ pci_status = (0x8a001824 | (fparam << 16)); @@ -1271,7 +1315,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) pci_status = PCI_PLL_INIT; /* Initialize PLL. */ - dev_dbg(host->dev, "pci_status: 0x%x\n", pci_status); + VPRINTK("pci_status: 0x%x\n", pci_status); writel(pci_status, mmio + PDC_CTL_STATUS); readl(mmio + PDC_CTL_STATUS); @@ -1280,23 +1324,23 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) and program the DIMM Module Controller. */ if (!(speed = pdc20621_detect_dimm(host))) { - dev_err(host->dev, "Detect Local DIMM Fail\n"); + printk(KERN_ERR "Detect Local DIMM Fail\n"); return 1; /* DIMM error */ } - dev_dbg(host->dev, "Local DIMM Speed = %d\n", speed); + VPRINTK("Local DIMM Speed = %d\n", speed); /* Programming DIMM0 Module Control Register (index_CID0:80h) */ size = pdc20621_prog_dimm0(host); - dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size); + VPRINTK("Local DIMM Size = %dMB\n", size); /* Programming DIMM Module Global Control Register (index_CID0:88h) */ if (pdc20621_prog_dimm_global(host)) { - dev_err(host->dev, - "Programming DIMM Module Global Control Register Fail\n"); + printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); return 1; } - if (dimm_test) { +#ifdef ATA_VERBOSE_DEBUG + { u8 test_parttern1[40] = {0x55,0xAA,'P','r','o','m','i','s','e',' ', 'N','o','t',' ','Y','e','t',' ', @@ -1310,33 +1354,31 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) pdc20621_put_to_dimm(host, test_parttern1, 0x10040, 40); pdc20621_get_from_dimm(host, test_parttern2, 0x40, 40); - dev_info(host->dev, "DIMM test pattern 1: %x, %x, %s\n", test_parttern2[0], + printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], test_parttern2[1], &(test_parttern2[2])); pdc20621_get_from_dimm(host, test_parttern2, 0x10040, 40); - dev_info(host->dev, "DIMM test pattern 2: %x, %x, %s\n", - test_parttern2[0], - test_parttern2[1], &(test_parttern2[2])); + printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], + test_parttern2[1], &(test_parttern2[2])); pdc20621_put_to_dimm(host, test_parttern1, 0x40, 40); pdc20621_get_from_dimm(host, test_parttern2, 0x40, 40); - dev_info(host->dev, "DIMM test pattern 3: %x, %x, %s\n", - test_parttern2[0], - test_parttern2[1], &(test_parttern2[2])); + printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], + test_parttern2[1], &(test_parttern2[2])); } +#endif /* ECC initiliazation. */ if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE, &spd0)) { - dev_err(host->dev, - "Failed in i2c read: device=%#x, subaddr=%#x\n", + pr_err("Failed in i2c read: device=%#x, subaddr=%#x\n", PDC_DIMM0_SPD_DEV_ADDRESS, PDC_DIMM_SPD_TYPE); return 1; } if (spd0 == 0x02) { void *buf; - dev_dbg(host->dev, "Start ECC initialization\n"); + VPRINTK("Start ECC initialization\n"); addr = 0; length = size * 1024 * 1024; buf = kzalloc(ECC_ERASE_BUF_SZ, GFP_KERNEL); @@ -1348,7 +1390,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) addr += ECC_ERASE_BUF_SZ; } kfree(buf); - dev_dbg(host->dev, "Finish ECC initialization\n"); + VPRINTK("Finish ECC initialization\n"); } return 0; } diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 3e726ee91f..bc8e8d9f17 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -178,6 +178,7 @@ static void ia_hack_tcq(IADEV *dev) { static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) { u_short desc_num, i; + struct sk_buff *skb; struct ia_vcc *iavcc_r = NULL; unsigned long delta; static unsigned long timer = 0; @@ -201,7 +202,8 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) { else dev->ffL.tcq_rd -= 2; *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1; - if (!dev->desc_tbl[i].txskb || !(iavcc_r = dev->desc_tbl[i].iavcc)) + if (!(skb = dev->desc_tbl[i].txskb) || + !(iavcc_r = dev->desc_tbl[i].iavcc)) printk("Fatal err, desc table vcc or skb is NULL\n"); else iavcc_r->vc_desc_cnt--; diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index 64012cda4d..1509cb7470 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -25,12 +25,6 @@ config CHARLCD This is some character LCD core interface that multiple drivers can use. -config LINEDISP - tristate "Character line display core support" if COMPILE_TEST - help - This is the core support for single-line character displays, to be - selected by drivers that use it. - config HD44780_COMMON tristate "Common functions for HD44780 (and compatibles) LCD displays" if COMPILE_TEST select CHARLCD @@ -161,7 +155,6 @@ config IMG_ASCII_LCD depends on HAS_IOMEM default y if MIPS_MALTA select MFD_SYSCON - select LINEDISP help Enable this to support the simple ASCII LCD displays found on development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3 @@ -169,16 +162,13 @@ config IMG_ASCII_LCD config HT16K33 tristate "Holtek Ht16K33 LED controller with keyscan" - depends on FB && I2C && INPUT + depends on FB && OF && I2C && INPUT select FB_SYS_FOPS select FB_SYS_FILLRECT select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT select INPUT_MATRIXKMAP select FB_BACKLIGHT - select NEW_LEDS - select LEDS_CLASS - select LINEDISP help Say yes here to add support for Holtek HT16K33, RAM mapping 16*8 LED controller driver with keyscan. diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index 6968ed4d3f..307771027c 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -13,4 +13,3 @@ obj-$(CONFIG_HD44780) += hd44780.o obj-$(CONFIG_HT16K33) += ht16k33.o obj-$(CONFIG_PARPORT_PANEL) += panel.o obj-$(CONFIG_LCD2S) += lcd2s.o -obj-$(CONFIG_LINEDISP) += line-display.o diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index 0df474506f..d66821adf4 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c @@ -12,10 +12,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #define CFAG12864BFB_NAME "cfag12864bfb" @@ -38,8 +41,8 @@ static const struct fb_var_screeninfo cfag12864bfb_var = { .yres_virtual = CFAG12864B_HEIGHT, .bits_per_pixel = 1, .red = { 0, 1, 0 }, - .green = { 0, 1, 0 }, - .blue = { 0, 1, 0 }, + .green = { 0, 1, 0 }, + .blue = { 0, 1, 0 }, .left_margin = 0, .right_margin = 0, .upper_margin = 0, @@ -67,7 +70,7 @@ static const struct fb_ops cfag12864bfb_ops = { static int cfag12864bfb_probe(struct platform_device *device) { int ret = -EINVAL; - struct fb_info *info = framebuffer_alloc(0, &device->dev); + struct fb_info *info = framebuffer_alloc(0, &device->dev); if (!info) goto none; diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index 6d309e4971..6c010d4efa 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -37,7 +37,7 @@ struct charlcd_priv { bool must_clear; /* contains the LCD config state */ - unsigned long flags; + unsigned long int flags; /* Current escape sequence and it's length or -1 if outside */ struct { diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 4fab3b2c70..ed58083499 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -5,39 +5,27 @@ * Author: Robin van der Gracht * * Copyright: (C) 2016 Protonic Holland. - * Copyright (C) 2021 Glider bv */ #include #include #include #include -#include +#include #include +#include #include #include #include -#include #include #include -#include -#include - -#include - -#include "line-display.h" - /* Registers */ #define REG_SYSTEM_SETUP 0x20 #define REG_SYSTEM_SETUP_OSC_ON BIT(0) #define REG_DISPLAY_SETUP 0x80 #define REG_DISPLAY_SETUP_ON BIT(0) -#define REG_DISPLAY_SETUP_BLINK_OFF (0 << 1) -#define REG_DISPLAY_SETUP_BLINK_2HZ (1 << 1) -#define REG_DISPLAY_SETUP_BLINK_1HZ (2 << 1) -#define REG_DISPLAY_SETUP_BLINK_0HZ5 (3 << 1) #define REG_ROWINT_SET 0xA0 #define REG_ROWINT_SET_INT_EN BIT(0) @@ -59,12 +47,6 @@ #define BYTES_PER_ROW (HT16K33_MATRIX_LED_MAX_ROWS / 8) #define HT16K33_FB_SIZE (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW) -enum display_type { - DISP_MATRIX = 0, - DISP_QUAD_7SEG, - DISP_QUAD_14SEG, -}; - struct ht16k33_keypad { struct i2c_client *client; struct input_dev *dev; @@ -83,29 +65,13 @@ struct ht16k33_fbdev { uint32_t refresh_rate; uint8_t *buffer; uint8_t *cache; -}; - -struct ht16k33_seg { - struct linedisp linedisp; - union { - struct seg7_conversion_map seg7; - struct seg14_conversion_map seg14; - } map; - unsigned int map_size; - char curr[4]; + struct delayed_work work; }; struct ht16k33_priv { struct i2c_client *client; - struct delayed_work work; - struct led_classdev led; struct ht16k33_keypad keypad; - union { - struct ht16k33_fbdev fbdev; - struct ht16k33_seg seg; - }; - enum display_type type; - uint8_t blink; + struct ht16k33_fbdev fbdev; }; static const struct fb_fix_screeninfo ht16k33_fb_fix = { @@ -135,36 +101,9 @@ static const struct fb_var_screeninfo ht16k33_fb_var = { .vmode = FB_VMODE_NONINTERLACED, }; -static const SEG7_DEFAULT_MAP(initial_map_seg7); -static const SEG14_DEFAULT_MAP(initial_map_seg14); - -static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ht16k33_priv *priv = dev_get_drvdata(dev); - - memcpy(buf, &priv->seg.map, priv->seg.map_size); - return priv->seg.map_size; -} - -static ssize_t map_seg_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t cnt) -{ - struct ht16k33_priv *priv = dev_get_drvdata(dev); - - if (cnt != priv->seg.map_size) - return -EINVAL; - - memcpy(&priv->seg.map, buf, cnt); - return cnt; -} - -static DEVICE_ATTR(map_seg7, 0644, map_seg_show, map_seg_store); -static DEVICE_ATTR(map_seg14, 0644, map_seg_show, map_seg_store); - static int ht16k33_display_on(struct ht16k33_priv *priv) { - uint8_t data = REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON | priv->blink; + uint8_t data = REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON; return i2c_smbus_write_byte(priv->client, data); } @@ -174,72 +113,11 @@ static int ht16k33_display_off(struct ht16k33_priv *priv) return i2c_smbus_write_byte(priv->client, REG_DISPLAY_SETUP); } -static int ht16k33_brightness_set(struct ht16k33_priv *priv, - unsigned int brightness) -{ - int err; - - if (brightness == 0) { - priv->blink = REG_DISPLAY_SETUP_BLINK_OFF; - return ht16k33_display_off(priv); - } - - err = ht16k33_display_on(priv); - if (err) - return err; - - return i2c_smbus_write_byte(priv->client, - REG_BRIGHTNESS | (brightness - 1)); -} - -static int ht16k33_brightness_set_blocking(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - struct ht16k33_priv *priv = container_of(led_cdev, struct ht16k33_priv, - led); - - return ht16k33_brightness_set(priv, brightness); -} - -static int ht16k33_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, unsigned long *delay_off) -{ - struct ht16k33_priv *priv = container_of(led_cdev, struct ht16k33_priv, - led); - unsigned int delay; - uint8_t blink; - int err; - - if (!*delay_on && !*delay_off) { - blink = REG_DISPLAY_SETUP_BLINK_1HZ; - delay = 1000; - } else if (*delay_on <= 750) { - blink = REG_DISPLAY_SETUP_BLINK_2HZ; - delay = 500; - } else if (*delay_on <= 1500) { - blink = REG_DISPLAY_SETUP_BLINK_1HZ; - delay = 1000; - } else { - blink = REG_DISPLAY_SETUP_BLINK_0HZ5; - delay = 2000; - } - - err = i2c_smbus_write_byte(priv->client, - REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON | - blink); - if (err) - return err; - - priv->blink = blink; - *delay_on = *delay_off = delay; - return 0; -} - static void ht16k33_fb_queue(struct ht16k33_priv *priv) { struct ht16k33_fbdev *fbdev = &priv->fbdev; - schedule_delayed_work(&priv->work, HZ / fbdev->refresh_rate); + schedule_delayed_work(&fbdev->work, HZ / fbdev->refresh_rate); } /* @@ -247,9 +125,10 @@ static void ht16k33_fb_queue(struct ht16k33_priv *priv) */ static void ht16k33_fb_update(struct work_struct *work) { - struct ht16k33_priv *priv = container_of(work, struct ht16k33_priv, - work.work); - struct ht16k33_fbdev *fbdev = &priv->fbdev; + struct ht16k33_fbdev *fbdev = + container_of(work, struct ht16k33_fbdev, work.work); + struct ht16k33_priv *priv = + container_of(fbdev, struct ht16k33_priv, fbdev); uint8_t *p1, *p2; int len, pos = 0, first = -1; @@ -289,9 +168,9 @@ static void ht16k33_fb_update(struct work_struct *work) static int ht16k33_initialize(struct ht16k33_priv *priv) { - uint8_t data[HT16K33_FB_SIZE]; uint8_t byte; int err; + uint8_t data[HT16K33_MATRIX_LED_MAX_COLS * 2]; /* Clear RAM (8 * 16 bits) */ memset(data, 0, sizeof(data)); @@ -319,10 +198,13 @@ static int ht16k33_bl_update_status(struct backlight_device *bl) if (bl->props.power != FB_BLANK_UNBLANK || bl->props.fb_blank != FB_BLANK_UNBLANK || - bl->props.state & BL_CORE_FBBLANK) - brightness = 0; + bl->props.state & BL_CORE_FBBLANK || brightness == 0) { + return ht16k33_display_off(priv); + } - return ht16k33_brightness_set(priv, brightness); + ht16k33_display_on(priv); + return i2c_smbus_write_byte(priv->client, + REG_BRIGHTNESS | (brightness - 1)); } static int ht16k33_bl_check_fb(struct backlight_device *bl, struct fb_info *fi) @@ -441,82 +323,10 @@ static void ht16k33_keypad_stop(struct input_dev *dev) disable_irq(keypad->client->irq); } -static void ht16k33_linedisp_update(struct linedisp *linedisp) -{ - struct ht16k33_priv *priv = container_of(linedisp, struct ht16k33_priv, - seg.linedisp); - - schedule_delayed_work(&priv->work, 0); -} - -static void ht16k33_seg7_update(struct work_struct *work) -{ - struct ht16k33_priv *priv = container_of(work, struct ht16k33_priv, - work.work); - struct ht16k33_seg *seg = &priv->seg; - char *s = seg->curr; - uint8_t buf[9]; - - buf[0] = map_to_seg7(&seg->map.seg7, *s++); - buf[1] = 0; - buf[2] = map_to_seg7(&seg->map.seg7, *s++); - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - buf[6] = map_to_seg7(&seg->map.seg7, *s++); - buf[7] = 0; - buf[8] = map_to_seg7(&seg->map.seg7, *s++); - - i2c_smbus_write_i2c_block_data(priv->client, 0, ARRAY_SIZE(buf), buf); -} - -static void ht16k33_seg14_update(struct work_struct *work) -{ - struct ht16k33_priv *priv = container_of(work, struct ht16k33_priv, - work.work); - struct ht16k33_seg *seg = &priv->seg; - char *s = seg->curr; - uint8_t buf[8]; - - put_unaligned_le16(map_to_seg14(&seg->map.seg14, *s++), buf); - put_unaligned_le16(map_to_seg14(&seg->map.seg14, *s++), buf + 2); - put_unaligned_le16(map_to_seg14(&seg->map.seg14, *s++), buf + 4); - put_unaligned_le16(map_to_seg14(&seg->map.seg14, *s++), buf + 6); - - i2c_smbus_write_i2c_block_data(priv->client, 0, ARRAY_SIZE(buf), buf); -} - -static int ht16k33_led_probe(struct device *dev, struct led_classdev *led, - unsigned int brightness) -{ - struct led_init_data init_data = {}; - int err; - - /* The LED is optional */ - init_data.fwnode = device_get_named_child_node(dev, "led"); - if (!init_data.fwnode) - return 0; - - init_data.devicename = "auxdisplay"; - init_data.devname_mandatory = true; - - led->brightness_set_blocking = ht16k33_brightness_set_blocking; - led->blink_set = ht16k33_blink_set; - led->flags = LED_CORE_SUSPENDRESUME; - led->brightness = brightness; - led->max_brightness = MAX_BRIGHTNESS; - - err = devm_led_classdev_register_ext(dev, led, &init_data); - if (err) - dev_err(dev, "Failed to register LED\n"); - - return err; -} - static int ht16k33_keypad_probe(struct i2c_client *client, struct ht16k33_keypad *keypad) { - struct device *dev = &client->dev; + struct device_node *node = client->dev.of_node; u32 rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS; u32 cols = HT16K33_MATRIX_KEYPAD_MAX_COLS; int err; @@ -524,7 +334,7 @@ static int ht16k33_keypad_probe(struct i2c_client *client, keypad->client = client; init_waitqueue_head(&keypad->wait); - keypad->dev = devm_input_allocate_device(dev); + keypad->dev = devm_input_allocate_device(&client->dev); if (!keypad->dev) return -ENOMEM; @@ -535,23 +345,23 @@ static int ht16k33_keypad_probe(struct i2c_client *client, keypad->dev->open = ht16k33_keypad_start; keypad->dev->close = ht16k33_keypad_stop; - if (!device_property_read_bool(dev, "linux,no-autorepeat")) + if (!of_get_property(node, "linux,no-autorepeat", NULL)) __set_bit(EV_REP, keypad->dev->evbit); - err = device_property_read_u32(dev, "debounce-delay-ms", - &keypad->debounce_ms); + err = of_property_read_u32(node, "debounce-delay-ms", + &keypad->debounce_ms); if (err) { - dev_err(dev, "key debounce delay not specified\n"); + dev_err(&client->dev, "key debounce delay not specified\n"); return err; } - err = matrix_keypad_parse_properties(dev, &rows, &cols); + err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols); if (err) return err; if (rows > HT16K33_MATRIX_KEYPAD_MAX_ROWS || cols > HT16K33_MATRIX_KEYPAD_MAX_COLS) { - dev_err(dev, "%u rows or %u cols out of range in DT\n", rows, - cols); + dev_err(&client->dev, "%u rows or %u cols out of range in DT\n", + rows, cols); return -ERANGE; } @@ -562,83 +372,111 @@ static int ht16k33_keypad_probe(struct i2c_client *client, err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, keypad->dev); if (err) { - dev_err(dev, "failed to build keymap\n"); + dev_err(&client->dev, "failed to build keymap\n"); return err; } - err = devm_request_threaded_irq(dev, client->irq, NULL, - ht16k33_keypad_irq_thread, + err = devm_request_threaded_irq(&client->dev, client->irq, + NULL, ht16k33_keypad_irq_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, DRIVER_NAME, keypad); if (err) { - dev_err(dev, "irq request failed %d, error %d\n", client->irq, - err); + dev_err(&client->dev, "irq request failed %d, error %d\n", + client->irq, err); return err; } ht16k33_keypad_stop(keypad->dev); - return input_register_device(keypad->dev); + err = input_register_device(keypad->dev); + if (err) + return err; + + return 0; } -static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv, - uint32_t brightness) +static int ht16k33_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct ht16k33_fbdev *fbdev = &priv->fbdev; - struct backlight_device *bl = NULL; int err; + uint32_t dft_brightness; + struct backlight_device *bl; + struct backlight_properties bl_props; + struct ht16k33_priv *priv; + struct ht16k33_fbdev *fbdev; + struct device_node *node = client->dev.of_node; - if (priv->led.dev) { - err = ht16k33_brightness_set(priv, brightness); - if (err) - return err; - } else { - /* backwards compatibility with DT lacking an led subnode */ - struct backlight_properties bl_props; - - memset(&bl_props, 0, sizeof(struct backlight_properties)); - bl_props.type = BACKLIGHT_RAW; - bl_props.max_brightness = MAX_BRIGHTNESS; - - bl = devm_backlight_device_register(dev, DRIVER_NAME"-bl", dev, - priv, &ht16k33_bl_ops, - &bl_props); - if (IS_ERR(bl)) { - dev_err(dev, "failed to register backlight\n"); - return PTR_ERR(bl); - } - - bl->props.brightness = brightness; - ht16k33_bl_update_status(bl); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "i2c_check_functionality error\n"); + return -EIO; } + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->client = client; + i2c_set_clientdata(client, priv); + fbdev = &priv->fbdev; + + err = ht16k33_initialize(priv); + if (err) + return err; + + /* Backlight */ + memset(&bl_props, 0, sizeof(struct backlight_properties)); + bl_props.type = BACKLIGHT_RAW; + bl_props.max_brightness = MAX_BRIGHTNESS; + + bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", + &client->dev, priv, + &ht16k33_bl_ops, &bl_props); + if (IS_ERR(bl)) { + dev_err(&client->dev, "failed to register backlight\n"); + return PTR_ERR(bl); + } + + err = of_property_read_u32(node, "default-brightness-level", + &dft_brightness); + if (err) { + dft_brightness = MAX_BRIGHTNESS; + } else if (dft_brightness > MAX_BRIGHTNESS) { + dev_warn(&client->dev, + "invalid default brightness level: %u, using %u\n", + dft_brightness, MAX_BRIGHTNESS); + dft_brightness = MAX_BRIGHTNESS; + } + + bl->props.brightness = dft_brightness; + ht16k33_bl_update_status(bl); + /* Framebuffer (2 bytes per column) */ BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE); fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL); if (!fbdev->buffer) return -ENOMEM; - fbdev->cache = devm_kmalloc(dev, HT16K33_FB_SIZE, GFP_KERNEL); + fbdev->cache = devm_kmalloc(&client->dev, HT16K33_FB_SIZE, GFP_KERNEL); if (!fbdev->cache) { err = -ENOMEM; goto err_fbdev_buffer; } - fbdev->info = framebuffer_alloc(0, dev); + fbdev->info = framebuffer_alloc(0, &client->dev); if (!fbdev->info) { err = -ENOMEM; goto err_fbdev_buffer; } - err = device_property_read_u32(dev, "refresh-rate-hz", - &fbdev->refresh_rate); + err = of_property_read_u32(node, "refresh-rate-hz", + &fbdev->refresh_rate); if (err) { - dev_err(dev, "refresh rate not specified\n"); + dev_err(&client->dev, "refresh rate not specified\n"); goto err_fbdev_info; } fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS); - INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update); + INIT_DELAYED_WORK(&fbdev->work, ht16k33_fb_update); fbdev->info->fbops = &ht16k33_fb_ops; fbdev->info->screen_base = (char __iomem *) fbdev->buffer; fbdev->info->screen_size = HT16K33_FB_SIZE; @@ -653,9 +491,18 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv, if (err) goto err_fbdev_info; + /* Keypad */ + if (client->irq > 0) { + err = ht16k33_keypad_probe(client, &priv->keypad); + if (err) + goto err_fbdev_unregister; + } + ht16k33_fb_queue(priv); return 0; +err_fbdev_unregister: + unregister_framebuffer(fbdev->info); err_fbdev_info: framebuffer_release(fbdev->info); err_fbdev_buffer: @@ -664,138 +511,15 @@ static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv, return err; } -static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv, - uint32_t brightness) -{ - struct ht16k33_seg *seg = &priv->seg; - int err; - - err = ht16k33_brightness_set(priv, brightness); - if (err) - return err; - - switch (priv->type) { - case DISP_MATRIX: - /* not handled here */ - err = -EINVAL; - break; - - case DISP_QUAD_7SEG: - INIT_DELAYED_WORK(&priv->work, ht16k33_seg7_update); - seg->map.seg7 = initial_map_seg7; - seg->map_size = sizeof(seg->map.seg7); - err = device_create_file(dev, &dev_attr_map_seg7); - break; - - case DISP_QUAD_14SEG: - INIT_DELAYED_WORK(&priv->work, ht16k33_seg14_update); - seg->map.seg14 = initial_map_seg14; - seg->map_size = sizeof(seg->map.seg14); - err = device_create_file(dev, &dev_attr_map_seg14); - break; - } - if (err) - return err; - - err = linedisp_register(&seg->linedisp, dev, 4, seg->curr, - ht16k33_linedisp_update); - if (err) - goto err_remove_map_file; - - return 0; - -err_remove_map_file: - device_remove_file(dev, &dev_attr_map_seg7); - device_remove_file(dev, &dev_attr_map_seg14); - return err; -} - -static int ht16k33_probe(struct i2c_client *client) -{ - struct device *dev = &client->dev; - const struct of_device_id *id; - struct ht16k33_priv *priv; - uint32_t dft_brightness; - int err; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(dev, "i2c_check_functionality error\n"); - return -EIO; - } - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->client = client; - id = i2c_of_match_device(dev->driver->of_match_table, client); - if (id) - priv->type = (uintptr_t)id->data; - i2c_set_clientdata(client, priv); - - err = ht16k33_initialize(priv); - if (err) - return err; - - err = device_property_read_u32(dev, "default-brightness-level", - &dft_brightness); - if (err) { - dft_brightness = MAX_BRIGHTNESS; - } else if (dft_brightness > MAX_BRIGHTNESS) { - dev_warn(dev, - "invalid default brightness level: %u, using %u\n", - dft_brightness, MAX_BRIGHTNESS); - dft_brightness = MAX_BRIGHTNESS; - } - - /* LED */ - err = ht16k33_led_probe(dev, &priv->led, dft_brightness); - if (err) - return err; - - /* Keypad */ - if (client->irq > 0) { - err = ht16k33_keypad_probe(client, &priv->keypad); - if (err) - return err; - } - - switch (priv->type) { - case DISP_MATRIX: - /* Frame Buffer Display */ - err = ht16k33_fbdev_probe(dev, priv, dft_brightness); - break; - - case DISP_QUAD_7SEG: - case DISP_QUAD_14SEG: - /* Segment Display */ - err = ht16k33_seg_probe(dev, priv, dft_brightness); - break; - } - return err; -} - static int ht16k33_remove(struct i2c_client *client) { struct ht16k33_priv *priv = i2c_get_clientdata(client); struct ht16k33_fbdev *fbdev = &priv->fbdev; - cancel_delayed_work_sync(&priv->work); - - switch (priv->type) { - case DISP_MATRIX: - unregister_framebuffer(fbdev->info); - framebuffer_release(fbdev->info); - free_page((unsigned long)fbdev->buffer); - break; - - case DISP_QUAD_7SEG: - case DISP_QUAD_14SEG: - linedisp_unregister(&priv->seg.linedisp); - device_remove_file(&client->dev, &dev_attr_map_seg7); - device_remove_file(&client->dev, &dev_attr_map_seg14); - break; - } + cancel_delayed_work_sync(&fbdev->work); + unregister_framebuffer(fbdev->info); + framebuffer_release(fbdev->info); + free_page((unsigned long) fbdev->buffer); return 0; } @@ -807,26 +531,17 @@ static const struct i2c_device_id ht16k33_i2c_match[] = { MODULE_DEVICE_TABLE(i2c, ht16k33_i2c_match); static const struct of_device_id ht16k33_of_match[] = { - { - /* 0.56" 4-Digit 7-Segment FeatherWing Display (Red) */ - .compatible = "adafruit,3108", .data = (void *)DISP_QUAD_7SEG, - }, { - /* 0.54" Quad Alphanumeric FeatherWing Display (Red) */ - .compatible = "adafruit,3130", .data = (void *)DISP_QUAD_14SEG, - }, { - /* Generic, assumed Dot-Matrix Display */ - .compatible = "holtek,ht16k33", .data = (void *)DISP_MATRIX, - }, + { .compatible = "holtek,ht16k33", }, { } }; MODULE_DEVICE_TABLE(of, ht16k33_of_match); static struct i2c_driver ht16k33_driver = { - .probe_new = ht16k33_probe, + .probe = ht16k33_probe, .remove = ht16k33_remove, .driver = { .name = DRIVER_NAME, - .of_match_table = ht16k33_of_match, + .of_match_table = of_match_ptr(ht16k33_of_match), }, .id_table = ht16k33_i2c_match, }; diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c index fa23e415f2..e33ce0151c 100644 --- a/drivers/auxdisplay/img-ascii-lcd.c +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -4,6 +4,7 @@ * Author: Paul Burton */ +#include #include #include #include @@ -13,8 +14,7 @@ #include #include #include - -#include "line-display.h" +#include struct img_ascii_lcd_ctx; @@ -27,26 +27,36 @@ struct img_ascii_lcd_ctx; struct img_ascii_lcd_config { unsigned int num_chars; bool external_regmap; - void (*update)(struct linedisp *linedisp); + void (*update)(struct img_ascii_lcd_ctx *ctx); }; /** * struct img_ascii_lcd_ctx - Private data structure + * @pdev: the ASCII LCD platform device * @base: the base address of the LCD registers * @regmap: the regmap through which LCD registers are accessed * @offset: the offset within regmap to the start of the LCD registers * @cfg: pointer to the LCD model configuration - * @linedisp: line display structure + * @message: the full message to display or scroll on the LCD + * @message_len: the length of the @message string + * @scroll_pos: index of the first character of @message currently displayed + * @scroll_rate: scroll interval in jiffies + * @timer: timer used to implement scrolling * @curr: the string currently displayed on the LCD */ struct img_ascii_lcd_ctx { + struct platform_device *pdev; union { void __iomem *base; struct regmap *regmap; }; u32 offset; const struct img_ascii_lcd_config *cfg; - struct linedisp linedisp; + char *message; + unsigned int message_len; + unsigned int scroll_pos; + unsigned int scroll_rate; + struct timer_list timer; char curr[] __aligned(8); }; @@ -54,10 +64,8 @@ struct img_ascii_lcd_ctx { * MIPS Boston development board */ -static void boston_update(struct linedisp *linedisp) +static void boston_update(struct img_ascii_lcd_ctx *ctx) { - struct img_ascii_lcd_ctx *ctx = - container_of(linedisp, struct img_ascii_lcd_ctx, linedisp); ulong val; #if BITS_PER_LONG == 64 @@ -82,14 +90,12 @@ static struct img_ascii_lcd_config boston_config = { * MIPS Malta development board */ -static void malta_update(struct linedisp *linedisp) +static void malta_update(struct img_ascii_lcd_ctx *ctx) { - struct img_ascii_lcd_ctx *ctx = - container_of(linedisp, struct img_ascii_lcd_ctx, linedisp); unsigned int i; int err = 0; - for (i = 0; i < linedisp->num_chars; i++) { + for (i = 0; i < ctx->cfg->num_chars; i++) { err = regmap_write(ctx->regmap, ctx->offset + (i * 8), ctx->curr[i]); if (err) @@ -167,14 +173,12 @@ static int sead3_wait_lcd_idle(struct img_ascii_lcd_ctx *ctx) return 0; } -static void sead3_update(struct linedisp *linedisp) +static void sead3_update(struct img_ascii_lcd_ctx *ctx) { - struct img_ascii_lcd_ctx *ctx = - container_of(linedisp, struct img_ascii_lcd_ctx, linedisp); unsigned int i; int err = 0; - for (i = 0; i < linedisp->num_chars; i++) { + for (i = 0; i < ctx->cfg->num_chars; i++) { err = sead3_wait_lcd_idle(ctx); if (err) break; @@ -214,6 +218,140 @@ static const struct of_device_id img_ascii_lcd_matches[] = { }; MODULE_DEVICE_TABLE(of, img_ascii_lcd_matches); +/** + * img_ascii_lcd_scroll() - scroll the display by a character + * @t: really a pointer to the private data structure + * + * Scroll the current message along the LCD by one character, rearming the + * timer if required. + */ +static void img_ascii_lcd_scroll(struct timer_list *t) +{ + struct img_ascii_lcd_ctx *ctx = from_timer(ctx, t, timer); + unsigned int i, ch = ctx->scroll_pos; + unsigned int num_chars = ctx->cfg->num_chars; + + /* update the current message string */ + for (i = 0; i < num_chars;) { + /* copy as many characters from the string as possible */ + for (; i < num_chars && ch < ctx->message_len; i++, ch++) + ctx->curr[i] = ctx->message[ch]; + + /* wrap around to the start of the string */ + ch = 0; + } + + /* update the LCD */ + ctx->cfg->update(ctx); + + /* move on to the next character */ + ctx->scroll_pos++; + ctx->scroll_pos %= ctx->message_len; + + /* rearm the timer */ + if (ctx->message_len > ctx->cfg->num_chars) + mod_timer(&ctx->timer, jiffies + ctx->scroll_rate); +} + +/** + * img_ascii_lcd_display() - set the message to be displayed + * @ctx: pointer to the private data structure + * @msg: the message to display + * @count: length of msg, or -1 + * + * Display a new message @msg on the LCD. @msg can be longer than the number of + * characters the LCD can display, in which case it will begin scrolling across + * the LCD display. + * + * Return: 0 on success, -ENOMEM on memory allocation failure + */ +static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx, + const char *msg, ssize_t count) +{ + char *new_msg; + + /* stop the scroll timer */ + del_timer_sync(&ctx->timer); + + if (count == -1) + count = strlen(msg); + + /* if the string ends with a newline, trim it */ + if (msg[count - 1] == '\n') + count--; + + if (!count) { + /* clear the LCD */ + devm_kfree(&ctx->pdev->dev, ctx->message); + ctx->message = NULL; + ctx->message_len = 0; + memset(ctx->curr, ' ', ctx->cfg->num_chars); + ctx->cfg->update(ctx); + return 0; + } + + new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); + if (!new_msg) + return -ENOMEM; + + memcpy(new_msg, msg, count); + new_msg[count] = 0; + + if (ctx->message) + devm_kfree(&ctx->pdev->dev, ctx->message); + + ctx->message = new_msg; + ctx->message_len = count; + ctx->scroll_pos = 0; + + /* update the LCD */ + img_ascii_lcd_scroll(&ctx->timer); + + return 0; +} + +/** + * message_show() - read message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer to read the message into + * + * Read the current message being displayed or scrolled across the LCD display + * into @buf, for reads from sysfs. + * + * Return: the number of characters written to @buf + */ +static ssize_t message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ctx->message); +} + +/** + * message_store() - write a new message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer containing the new message + * @count: the size of the message in @buf + * + * Write a new message to display or scroll across the LCD display from sysfs. + * + * Return: the size of the message on success, else -ERRNO + */ +static ssize_t message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + int err; + + err = img_ascii_lcd_display(ctx, buf, count); + return err ?: count; +} + +static DEVICE_ATTR_RW(message); + /** * img_ascii_lcd_probe() - probe an LCD display device * @pdev: the LCD platform device @@ -227,25 +365,26 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct img_ascii_lcd_config *cfg; - struct device *dev = &pdev->dev; struct img_ascii_lcd_ctx *ctx; int err; - match = of_match_device(img_ascii_lcd_matches, dev); + match = of_match_device(img_ascii_lcd_matches, &pdev->dev); if (!match) return -ENODEV; cfg = match->data; - ctx = devm_kzalloc(dev, sizeof(*ctx) + cfg->num_chars, GFP_KERNEL); + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx) + cfg->num_chars, + GFP_KERNEL); if (!ctx) return -ENOMEM; if (cfg->external_regmap) { - ctx->regmap = syscon_node_to_regmap(dev->parent->of_node); + ctx->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node); if (IS_ERR(ctx->regmap)) return PTR_ERR(ctx->regmap); - if (of_property_read_u32(dev->of_node, "offset", &ctx->offset)) + if (of_property_read_u32(pdev->dev.of_node, "offset", + &ctx->offset)) return -EINVAL; } else { ctx->base = devm_platform_ioremap_resource(pdev, 0); @@ -253,23 +392,29 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) return PTR_ERR(ctx->base); } - err = linedisp_register(&ctx->linedisp, dev, cfg->num_chars, ctx->curr, - cfg->update); - if (err) - return err; + ctx->pdev = pdev; + ctx->cfg = cfg; + ctx->message = NULL; + ctx->scroll_pos = 0; + ctx->scroll_rate = HZ / 2; - /* for backwards compatibility */ - err = compat_only_sysfs_link_entry_to_kobj(&dev->kobj, - &ctx->linedisp.dev.kobj, - "message", NULL); - if (err) - goto err_unregister; + /* initialise a timer for scrolling the message */ + timer_setup(&ctx->timer, img_ascii_lcd_scroll, 0); platform_set_drvdata(pdev, ctx); - return 0; -err_unregister: - linedisp_unregister(&ctx->linedisp); + /* display a default message */ + err = img_ascii_lcd_display(ctx, "Linux " UTS_RELEASE " ", -1); + if (err) + goto out_del_timer; + + err = device_create_file(&pdev->dev, &dev_attr_message); + if (err) + goto out_del_timer; + + return 0; +out_del_timer: + del_timer_sync(&ctx->timer); return err; } @@ -286,8 +431,8 @@ static int img_ascii_lcd_remove(struct platform_device *pdev) { struct img_ascii_lcd_ctx *ctx = platform_get_drvdata(pdev); - sysfs_remove_link(&pdev->dev.kobj, "message"); - linedisp_unregister(&ctx->linedisp); + device_remove_file(&pdev->dev, &dev_attr_message); + del_timer_sync(&ctx->timer); return 0; } diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c index 234f9dbe6e..e871b94a19 100644 --- a/drivers/auxdisplay/ks0108.c +++ b/drivers/auxdisplay/ks0108.c @@ -15,7 +15,10 @@ #include #include #include +#include +#include #include +#include #include #define KS0108_NAME "ks0108" diff --git a/drivers/auxdisplay/lcd2s.c b/drivers/auxdisplay/lcd2s.c index 38ba08628c..2578b2d454 100644 --- a/drivers/auxdisplay/lcd2s.c +++ b/drivers/auxdisplay/lcd2s.c @@ -238,7 +238,7 @@ static int lcd2s_redefine_char(struct charlcd *lcd, char *esc) if (buf[1] > 7) return 1; - i = 0; + i = 2; shift = 0; value = 0; while (*esc && i < LCD2S_CHARACTER_SIZE + 2) { @@ -298,6 +298,10 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) return -EIO; + lcd2s = devm_kzalloc(&i2c->dev, sizeof(*lcd2s), GFP_KERNEL); + if (!lcd2s) + return -ENOMEM; + /* Test, if the display is responding */ err = lcd2s_i2c_smbus_write_byte(i2c, LCD2S_CMD_DISPLAY_OFF); if (err < 0) @@ -307,12 +311,6 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, if (!lcd) return -ENOMEM; - lcd2s = kzalloc(sizeof(struct lcd2s_data), GFP_KERNEL); - if (!lcd2s) { - err = -ENOMEM; - goto fail1; - } - lcd->drvdata = lcd2s; lcd2s->i2c = i2c; lcd2s->charlcd = lcd; @@ -321,26 +319,24 @@ static int lcd2s_i2c_probe(struct i2c_client *i2c, err = device_property_read_u32(&i2c->dev, "display-height-chars", &lcd->height); if (err) - goto fail2; + goto fail1; err = device_property_read_u32(&i2c->dev, "display-width-chars", &lcd->width); if (err) - goto fail2; + goto fail1; lcd->ops = &lcd2s_ops; err = charlcd_register(lcd2s->charlcd); if (err) - goto fail2; + goto fail1; i2c_set_clientdata(i2c, lcd2s); return 0; -fail2: - kfree(lcd2s); fail1: - kfree(lcd); + charlcd_free(lcd2s->charlcd); return err; } @@ -349,7 +345,7 @@ static int lcd2s_i2c_remove(struct i2c_client *i2c) struct lcd2s_data *lcd2s = i2c_get_clientdata(i2c); charlcd_unregister(lcd2s->charlcd); - kfree(lcd2s->charlcd); + charlcd_free(lcd2s->charlcd); return 0; } diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 6f04b831a5..ffcbe2bc46 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -62,17 +62,6 @@ config DEVTMPFS_MOUNT rescue mode with init=/bin/sh, even when the /dev directory on the rootfs is completely empty. -config DEVTMPFS_SAFE - bool "Use nosuid,noexec mount options on devtmpfs" - depends on DEVTMPFS - help - This instructs the kernel to include the MS_NOEXEC and MS_NOSUID mount - flags when mounting devtmpfs. - - Notice: If enabled, things like /dev/mem cannot be mmapped - with the PROT_EXEC flag. This can break, for example, non-KMS - video drivers. - config STANDALONE bool "Select only drivers that don't need compile-time external firmware" default y diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 02f7f1358e..ef8e44a7d2 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -13,7 +13,7 @@ obj-y += power/ obj-$(CONFIG_ISA_BUS_API) += isa.o obj-y += firmware_loader/ obj-$(CONFIG_NUMA) += node.o -obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o +obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o ifeq ($(CONFIG_SYSFS),y) obj-$(CONFIG_MODULES) += module.o endif diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c index eaa31e567d..00fb4120a5 100644 --- a/drivers/base/arch_numa.c +++ b/drivers/base/arch_numa.c @@ -154,34 +154,36 @@ static int __init pcpu_cpu_distance(unsigned int from, unsigned int to) return node_distance(early_cpu_to_node(from), early_cpu_to_node(to)); } +static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, + size_t align) +{ + int nid = early_cpu_to_node(cpu); + + return memblock_alloc_try_nid(size, align, + __pa(MAX_DMA_ADDRESS), MEMBLOCK_ALLOC_ACCESSIBLE, nid); +} + +static void __init pcpu_fc_free(void *ptr, size_t size) +{ + memblock_free_early(__pa(ptr), size); +} + void __init setup_per_cpu_areas(void) { unsigned long delta; unsigned int cpu; - int rc = -EINVAL; + int rc; - if (pcpu_chosen_fc != PCPU_FC_PAGE) { - /* - * Always reserve area for module percpu variables. That's - * what the legacy allocator did. - */ - rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE, - PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, - pcpu_cpu_distance, - early_cpu_to_node); -#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK - if (rc < 0) - pr_warn("PERCPU: %s allocator failed (%d), falling back to page size\n", - pcpu_fc_names[pcpu_chosen_fc], rc); -#endif - } - -#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK + /* + * Always reserve area for module percpu variables. That's + * what the legacy allocator did. + */ + rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE, + PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, + pcpu_cpu_distance, + pcpu_fc_alloc, pcpu_fc_free); if (rc < 0) - rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE, early_cpu_to_node); -#endif - if (rc < 0) - panic("Failed to initialize percpu areas (err=%d).", rc); + panic("Failed to initialize percpu areas."); delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; for_each_possible_cpu(cpu) @@ -262,7 +264,7 @@ void __init numa_free_distance(void) size = numa_distance_cnt * numa_distance_cnt * sizeof(numa_distance[0]); - memblock_free(numa_distance, size); + memblock_free_ptr(numa_distance, size); numa_distance_cnt = 0; numa_distance = NULL; } @@ -273,13 +275,15 @@ void __init numa_free_distance(void) static int __init numa_alloc_distance(void) { size_t size; + u64 phys; int i, j; size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]); - numa_distance = memblock_alloc(size, PAGE_SIZE); - if (WARN_ON(!numa_distance)) + phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn)); + if (WARN_ON(!phys)) return -ENOMEM; + numa_distance = __va(phys); numa_distance_cnt = nr_node_ids; /* fill with the default distances */ diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 976154140f..4340766591 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -12,17 +12,19 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data); static struct cpumask scale_freq_counters_mask; static bool scale_freq_invariant; -static DEFINE_PER_CPU(u32, freq_factor) = 1; static bool supports_scale_freq_counters(const struct cpumask *cpus) { @@ -156,49 +158,15 @@ void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity) DEFINE_PER_CPU(unsigned long, thermal_pressure); -/** - * topology_update_thermal_pressure() - Update thermal pressure for CPUs - * @cpus : The related CPUs for which capacity has been reduced - * @capped_freq : The maximum allowed frequency that CPUs can run at - * - * Update the value of thermal pressure for all @cpus in the mask. The - * cpumask should include all (online+offline) affected CPUs, to avoid - * operating on stale data when hot-plug is used for some CPUs. The - * @capped_freq reflects the currently allowed max CPUs frequency due to - * thermal capping. It might be also a boost frequency value, which is bigger - * than the internal 'freq_factor' max frequency. In such case the pressure - * value should simply be removed, since this is an indication that there is - * no thermal throttling. The @capped_freq must be provided in kHz. - */ -void topology_update_thermal_pressure(const struct cpumask *cpus, - unsigned long capped_freq) +void topology_set_thermal_pressure(const struct cpumask *cpus, + unsigned long th_pressure) { - unsigned long max_capacity, capacity, th_pressure; - u32 max_freq; int cpu; - cpu = cpumask_first(cpus); - max_capacity = arch_scale_cpu_capacity(cpu); - max_freq = per_cpu(freq_factor, cpu); - - /* Convert to MHz scale which is used in 'freq_factor' */ - capped_freq /= 1000; - - /* - * Handle properly the boost frequencies, which should simply clean - * the thermal pressure value. - */ - if (max_freq <= capped_freq) - capacity = max_capacity; - else - capacity = mult_frac(max_capacity, capped_freq, max_freq); - - th_pressure = max_capacity - capacity; - for_each_cpu(cpu, cpus) WRITE_ONCE(per_cpu(thermal_pressure, cpu), th_pressure); } -EXPORT_SYMBOL_GPL(topology_update_thermal_pressure); +EXPORT_SYMBOL_GPL(topology_set_thermal_pressure); static ssize_t cpu_capacity_show(struct device *dev, struct device_attribute *attr, @@ -252,6 +220,7 @@ static void update_topology_flags_workfn(struct work_struct *work) update_topology = 0; } +static DEFINE_PER_CPU(u32, freq_factor) = 1; static u32 *raw_capacity; static int free_raw_capacity(void) @@ -631,11 +600,6 @@ const struct cpumask *cpu_coregroup_mask(int cpu) return core_mask; } -const struct cpumask *cpu_clustergroup_mask(int cpu) -{ - return &cpu_topology[cpu].cluster_sibling; -} - void update_siblings_masks(unsigned int cpuid) { struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; @@ -653,12 +617,6 @@ void update_siblings_masks(unsigned int cpuid) if (cpuid_topo->package_id != cpu_topo->package_id) continue; - if (cpuid_topo->cluster_id == cpu_topo->cluster_id && - cpuid_topo->cluster_id != -1) { - cpumask_set_cpu(cpu, &cpuid_topo->cluster_sibling); - cpumask_set_cpu(cpuid, &cpu_topo->cluster_sibling); - } - cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); @@ -677,9 +635,6 @@ static void clear_cpu_topology(int cpu) cpumask_clear(&cpu_topo->llc_sibling); cpumask_set_cpu(cpu, &cpu_topo->llc_sibling); - cpumask_clear(&cpu_topo->cluster_sibling); - cpumask_set_cpu(cpu, &cpu_topo->cluster_sibling); - cpumask_clear(&cpu_topo->core_sibling); cpumask_set_cpu(cpu, &cpu_topo->core_sibling); cpumask_clear(&cpu_topo->thread_sibling); @@ -695,7 +650,6 @@ void __init reset_cpu_topology(void) cpu_topo->thread_id = -1; cpu_topo->core_id = -1; - cpu_topo->cluster_id = -1; cpu_topo->package_id = -1; cpu_topo->llc_id = -1; @@ -711,8 +665,6 @@ void remove_cpu_topology(unsigned int cpu) cpumask_clear_cpu(cpu, topology_core_cpumask(sibling)); for_each_cpu(sibling, topology_sibling_cpumask(cpu)) cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling)); - for_each_cpu(sibling, topology_cluster_cpumask(cpu)) - cpumask_clear_cpu(cpu, topology_cluster_cpumask(sibling)); for_each_cpu(sibling, topology_llc_cpumask(cpu)) cpumask_clear_cpu(cpu, topology_llc_cpumask(sibling)); diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index 8c5e659306..9230c9472b 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -17,147 +17,6 @@ #include #include "base.h" -/** - * DOC: PURPOSE - * - * In some subsystems, the functionality of the core device (PCI/ACPI/other) is - * too complex for a single device to be managed by a monolithic driver (e.g. - * Sound Open Firmware), multiple devices might implement a common intersection - * of functionality (e.g. NICs + RDMA), or a driver may want to export an - * interface for another subsystem to drive (e.g. SIOV Physical Function export - * Virtual Function management). A split of the functionality into child- - * devices representing sub-domains of functionality makes it possible to - * compartmentalize, layer, and distribute domain-specific concerns via a Linux - * device-driver model. - * - * An example for this kind of requirement is the audio subsystem where a - * single IP is handling multiple entities such as HDMI, Soundwire, local - * devices such as mics/speakers etc. The split for the core's functionality - * can be arbitrary or be defined by the DSP firmware topology and include - * hooks for test/debug. This allows for the audio core device to be minimal - * and focused on hardware-specific control and communication. - * - * Each auxiliary_device represents a part of its parent functionality. The - * generic behavior can be extended and specialized as needed by encapsulating - * an auxiliary_device within other domain-specific structures and the use of - * .ops callbacks. Devices on the auxiliary bus do not share any structures and - * the use of a communication channel with the parent is domain-specific. - * - * Note that ops are intended as a way to augment instance behavior within a - * class of auxiliary devices, it is not the mechanism for exporting common - * infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey - * infrastructure from the parent module to the auxiliary module(s). - */ - -/** - * DOC: USAGE - * - * The auxiliary bus is to be used when a driver and one or more kernel - * modules, who share a common header file with the driver, need a mechanism to - * connect and provide access to a shared object allocated by the - * auxiliary_device's registering driver. The registering driver for the - * auxiliary_device(s) and the kernel module(s) registering auxiliary_drivers - * can be from the same subsystem, or from multiple subsystems. - * - * The emphasis here is on a common generic interface that keeps subsystem - * customization out of the bus infrastructure. - * - * One example is a PCI network device that is RDMA-capable and exports a child - * device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI - * driver allocates and registers an auxiliary_device for each physical - * function on the NIC. The RDMA driver registers an auxiliary_driver that - * claims each of these auxiliary_devices. This conveys data/ops published by - * the parent PCI device/driver to the RDMA auxiliary_driver. - * - * Another use case is for the PCI device to be split out into multiple sub - * functions. For each sub function an auxiliary_device is created. A PCI sub - * function driver binds to such devices that creates its own one or more class - * devices. A PCI sub function auxiliary device is likely to be contained in a - * struct with additional attributes such as user defined sub function number - * and optional attributes such as resources and a link to the parent device. - * These attributes could be used by systemd/udev; and hence should be - * initialized before a driver binds to an auxiliary_device. - * - * A key requirement for utilizing the auxiliary bus is that there is no - * dependency on a physical bus, device, register accesses or regmap support. - * These individual devices split from the core cannot live on the platform bus - * as they are not physical devices that are controlled by DT/ACPI. The same - * argument applies for not using MFD in this scenario as MFD relies on - * individual function devices being physical devices. - */ - -/** - * DOC: EXAMPLE - * - * Auxiliary devices are created and registered by a subsystem-level core - * device that needs to break up its functionality into smaller fragments. One - * way to extend the scope of an auxiliary_device is to encapsulate it within a - * domain- pecific structure defined by the parent device. This structure - * contains the auxiliary_device and any associated shared data/callbacks - * needed to establish the connection with the parent. - * - * An example is: - * - * .. code-block:: c - * - * struct foo { - * struct auxiliary_device auxdev; - * void (*connect)(struct auxiliary_device *auxdev); - * void (*disconnect)(struct auxiliary_device *auxdev); - * void *data; - * }; - * - * The parent device then registers the auxiliary_device by calling - * auxiliary_device_init(), and then auxiliary_device_add(), with the pointer - * to the auxdev member of the above structure. The parent provides a name for - * the auxiliary_device that, combined with the parent's KBUILD_MODNAME, - * creates a match_name that is be used for matching and binding with a driver. - * - * Whenever an auxiliary_driver is registered, based on the match_name, the - * auxiliary_driver's probe() is invoked for the matching devices. The - * auxiliary_driver can also be encapsulated inside custom drivers that make - * the core device's functionality extensible by adding additional - * domain-specific ops as follows: - * - * .. code-block:: c - * - * struct my_ops { - * void (*send)(struct auxiliary_device *auxdev); - * void (*receive)(struct auxiliary_device *auxdev); - * }; - * - * - * struct my_driver { - * struct auxiliary_driver auxiliary_drv; - * const struct my_ops ops; - * }; - * - * An example of this type of usage is: - * - * .. code-block:: c - * - * const struct auxiliary_device_id my_auxiliary_id_table[] = { - * { .name = "foo_mod.foo_dev" }, - * { }, - * }; - * - * const struct my_ops my_custom_ops = { - * .send = my_tx, - * .receive = my_rx, - * }; - * - * const struct my_driver my_drv = { - * .auxiliary_drv = { - * .name = "myauxiliarydrv", - * .id_table = my_auxiliary_id_table, - * .probe = my_probe, - * .remove = my_remove, - * .shutdown = my_shutdown, - * }, - * .ops = my_custom_ops, - * }; - */ - static const struct auxiliary_device_id *auxiliary_match_id(const struct auxiliary_device_id *id, const struct auxiliary_device *auxdev) { @@ -258,7 +117,7 @@ static struct bus_type auxiliary_bus_type = { * auxiliary_device_init - check auxiliary_device and initialize * @auxdev: auxiliary device struct * - * This is the second step in the three-step process to register an + * This is the first step in the two-step process to register an * auxiliary_device. * * When this function returns an error code, then the device_initialize will @@ -296,7 +155,7 @@ EXPORT_SYMBOL_GPL(auxiliary_device_init); * @auxdev: auxiliary bus device to add to the bus * @modname: name of the parent device's driver module * - * This is the third step in the three-step process to register an + * This is the second step in the two-step process to register an * auxiliary_device. * * This function must be called after a successful call to @@ -343,8 +202,6 @@ EXPORT_SYMBOL_GPL(__auxiliary_device_add); * This function returns a reference to a device that is 'found' * for later use, as determined by the @match callback. * - * The reference returned should be released with put_device(). - * * The callback should return 0 if the device doesn't match and non-zero * if it does. If the callback returns non-zero, this function will * return to the caller and not iterate over any more devices. @@ -368,11 +225,6 @@ EXPORT_SYMBOL_GPL(auxiliary_find_device); * @auxdrv: auxiliary_driver structure * @owner: owning module/driver * @modname: KBUILD_MODNAME for parent driver - * - * The expectation is that users will call the "auxiliary_driver_register" - * macro so that the caller's KBUILD_MODNAME is automatically inserted for the - * modname parameter. Only if a user requires a custom name would this version - * be called directly. */ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner, const char *modname) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 97936ec49b..bdc98c5713 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -163,9 +163,9 @@ static struct kobj_type bus_ktype = { .release = bus_release, }; -static int bus_uevent_filter(struct kobject *kobj) +static int bus_uevent_filter(struct kset *kset, struct kobject *kobj) { - const struct kobj_type *ktype = get_ktype(kobj); + struct kobj_type *ktype = get_ktype(kobj); if (ktype == &bus_ktype) return 1; diff --git a/drivers/base/component.c b/drivers/base/component.c index 2d25a64165..870485cbbb 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/base/core.c b/drivers/base/core.c index 7bb957b118..8e73a34e10 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2260,9 +2260,9 @@ static struct kobj_type device_ktype = { }; -static int dev_uevent_filter(struct kobject *kobj) +static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) { - const struct kobj_type *ktype = get_ktype(kobj); + struct kobj_type *ktype = get_ktype(kobj); if (ktype == &device_ktype) { struct device *dev = kobj_to_dev(kobj); @@ -2274,7 +2274,7 @@ static int dev_uevent_filter(struct kobject *kobj) return 0; } -static const char *dev_uevent_name(struct kobject *kobj) +static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) { struct device *dev = kobj_to_dev(kobj); @@ -2285,7 +2285,8 @@ static const char *dev_uevent_name(struct kobject *kobj) return NULL; } -static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env) +static int dev_uevent(struct kset *kset, struct kobject *kobj, + struct kobj_uevent_env *env) { struct device *dev = kobj_to_dev(kobj); int retval = 0; @@ -2380,7 +2381,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, /* respect filter */ if (kset->uevent_ops && kset->uevent_ops->filter) - if (!kset->uevent_ops->filter(&dev->kobj)) + if (!kset->uevent_ops->filter(kset, &dev->kobj)) goto out; env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); @@ -2388,7 +2389,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, return -ENOMEM; /* let the kset specific function add its keys */ - retval = kset->uevent_ops->uevent(&dev->kobj, env); + retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); if (retval) goto out; @@ -2871,7 +2872,11 @@ void device_initialize(struct device *dev) spin_lock_init(&dev->devres_lock); INIT_LIST_HEAD(&dev->devres_head); device_pm_init(dev); - set_dev_node(dev, NUMA_NO_NODE); + set_dev_node(dev, -1); +#ifdef CONFIG_GENERIC_MSI_IRQ + raw_spin_lock_init(&dev->msi_lock); + INIT_LIST_HEAD(&dev->msi_list); +#endif INIT_LIST_HEAD(&dev->links.consumers); INIT_LIST_HEAD(&dev->links.suppliers); INIT_LIST_HEAD(&dev->links.defer_sync); @@ -3023,23 +3028,6 @@ static inline struct kobject *get_glue_dir(struct device *dev) return dev->kobj.parent; } -/** - * kobject_has_children - Returns whether a kobject has children. - * @kobj: the object to test - * - * This will return whether a kobject has other kobjects as children. - * - * It does NOT account for the presence of attribute files, only sub - * directories. It also assumes there is no concurrent addition or - * removal of such children, and thus relies on external locking. - */ -static inline bool kobject_has_children(struct kobject *kobj) -{ - WARN_ON_ONCE(kref_read(&kobj->kref) == 0); - - return kobj->sd && kobj->sd->dir.subdirs; -} - /* * make sure cleaning up dir as the last step, we need to make * sure .release handler of kobject is run with holding the @@ -3593,6 +3581,7 @@ void device_del(struct device *dev) device_pm_remove(dev); driver_deferred_probe_del(dev); device_platform_notify_remove(dev); + device_remove_properties(dev); device_links_purge(dev); if (dev->bus) @@ -4698,11 +4687,6 @@ define_dev_printk_level(_dev_info, KERN_INFO); * * return dev_err_probe(dev, err, ...); * - * Note that it is deemed acceptable to use this function for error - * prints during probe even if the @err is known to never be -EPROBE_DEFER. - * The benefit compared to a normal dev_err() is the standardized format - * of the error code and the fact that the error code is returned. - * * Returns @err. * */ @@ -4848,12 +4832,6 @@ int device_match_acpi_dev(struct device *dev, const void *adev) } EXPORT_SYMBOL(device_match_acpi_dev); -int device_match_acpi_handle(struct device *dev, const void *handle) -{ - return ACPI_HANDLE(dev) == handle; -} -EXPORT_SYMBOL(device_match_acpi_handle); - int device_match_any(struct device *dev, const void *unused) { return 1; diff --git a/drivers/base/dd.c b/drivers/base/dd.c index f47cab2143..6b66306932 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -577,14 +577,14 @@ static int really_probe(struct device *dev, struct device_driver *drv) if (dev->bus->dma_configure) { ret = dev->bus->dma_configure(dev); if (ret) - goto pinctrl_bind_failed; + goto probe_failed; } ret = driver_sysfs_add(dev); if (ret) { pr_err("%s: driver_sysfs_add(%s) failed\n", __func__, dev_name(dev)); - goto sysfs_failed; + goto probe_failed; } if (dev->pm_domain && dev->pm_domain->activate) { @@ -660,8 +660,6 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); probe_failed: - driver_sysfs_remove(dev); -sysfs_failed: if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); @@ -671,6 +669,7 @@ static int really_probe(struct device *dev, struct device_driver *drv) arch_teardown_dma_ops(dev); kfree(dev->dma_range_map); dev->dma_range_map = NULL; + driver_sysfs_remove(dev); dev->driver = NULL; dev_set_drvdata(dev, NULL); if (dev->pm_domain && dev->pm_domain->dismiss) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index f41063ac1a..fa13ad49d2 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -29,12 +29,6 @@ #include #include "base.h" -#ifdef CONFIG_DEVTMPFS_SAFE -#define DEVTMPFS_MFLAGS (MS_SILENT | MS_NOEXEC | MS_NOSUID) -#else -#define DEVTMPFS_MFLAGS (MS_SILENT) -#endif - static struct task_struct *thread; static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT); @@ -376,7 +370,7 @@ int __init devtmpfs_mount(void) if (!thread) return 0; - err = init_mount("devtmpfs", "dev", "devtmpfs", DEVTMPFS_MFLAGS, NULL); + err = init_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL); if (err) printk(KERN_INFO "devtmpfs: error mounting %i\n", err); else @@ -425,7 +419,7 @@ static noinline int __init devtmpfs_setup(void *p) err = ksys_unshare(CLONE_NEWNS); if (err) goto out; - err = init_mount("devtmpfs", "/", "devtmpfs", DEVTMPFS_MFLAGS, NULL); + err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); if (err) goto out; init_chdir("/.."); /* will traverse into overmounted root */ diff --git a/drivers/base/firmware_loader/builtin/Makefile b/drivers/base/firmware_loader/builtin/Makefile index 6c067dedc0..101754ad48 100644 --- a/drivers/base/firmware_loader/builtin/Makefile +++ b/drivers/base/firmware_loader/builtin/Makefile @@ -1,13 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y += main.o # Create $(fwdir) from $(CONFIG_EXTRA_FIRMWARE_DIR) -- if it doesn't have a # leading /, it's relative to $(srctree). -fwdir := $(CONFIG_EXTRA_FIRMWARE_DIR) +fwdir := $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE_DIR)) fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir)) -firmware := $(addsuffix .gen.o, $(CONFIG_EXTRA_FIRMWARE)) -obj-y += $(firmware) +obj-y := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))) @@ -36,7 +34,7 @@ $(obj)/%.gen.S: FORCE $(call filechk,fwbin) # The .o files depend on the binaries directly; the .S files don't. -$(addprefix $(obj)/, $(firmware)): $(obj)/%.gen.o: $(fwdir)/% +$(addprefix $(obj)/, $(obj-y)): $(obj)/%.gen.o: $(fwdir)/% targets := $(patsubst $(obj)/%,%, \ $(shell find $(obj) -name \*.gen.S 2>/dev/null)) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 4afb0e9312..d7d63c1aa9 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -199,16 +199,11 @@ static struct class firmware_class = { int register_sysfs_loader(void) { - int ret = class_register(&firmware_class); - - if (ret != 0) - return ret; - return register_firmware_config_sysctl(); + return class_register(&firmware_class); } void unregister_sysfs_loader(void) { - unregister_firmware_config_sysctl(); class_unregister(&firmware_class); } diff --git a/drivers/base/firmware_loader/fallback.h b/drivers/base/firmware_loader/fallback.h index 9f3055d3b4..3af7205b30 100644 --- a/drivers/base/firmware_loader/fallback.h +++ b/drivers/base/firmware_loader/fallback.h @@ -42,17 +42,6 @@ void fw_fallback_set_default_timeout(void); int register_sysfs_loader(void); void unregister_sysfs_loader(void); -#ifdef CONFIG_SYSCTL -extern int register_firmware_config_sysctl(void); -extern void unregister_firmware_config_sysctl(void); -#else -static inline int register_firmware_config_sysctl(void) -{ - return 0; -} -static inline void unregister_firmware_config_sysctl(void) { } -#endif /* CONFIG_SYSCTL */ - #else /* CONFIG_FW_LOADER_USER_HELPER */ static inline int firmware_fallback_sysfs(struct firmware *fw, const char *name, struct device *device, diff --git a/drivers/base/firmware_loader/fallback_table.c b/drivers/base/firmware_loader/fallback_table.c index e5ac098d07..46a731dede 100644 --- a/drivers/base/firmware_loader/fallback_table.c +++ b/drivers/base/firmware_loader/fallback_table.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -25,7 +24,7 @@ struct firmware_fallback_config fw_fallback_config = { EXPORT_SYMBOL_NS_GPL(fw_fallback_config, FIRMWARE_LOADER_PRIVATE); #ifdef CONFIG_SYSCTL -static struct ctl_table firmware_config_table[] = { +struct ctl_table firmware_config_table[] = { { .procname = "force_sysfs_fallback", .data = &fw_fallback_config.force_sysfs_fallback, @@ -46,24 +45,4 @@ static struct ctl_table firmware_config_table[] = { }, { } }; - -static struct ctl_table_header *firmware_config_sysct_table_header; -int register_firmware_config_sysctl(void) -{ - firmware_config_sysct_table_header = - register_sysctl("kernel/firmware_config", - firmware_config_table); - if (!firmware_config_sysct_table_header) - return -ENOMEM; - return 0; -} -EXPORT_SYMBOL_NS_GPL(register_firmware_config_sysctl, FIRMWARE_LOADER_PRIVATE); - -void unregister_firmware_config_sysctl(void) -{ - unregister_sysctl_table(firmware_config_sysct_table_header); - firmware_config_sysct_table_header = NULL; -} -EXPORT_SYMBOL_NS_GPL(unregister_firmware_config_sysctl, FIRMWARE_LOADER_PRIVATE); - -#endif /* CONFIG_SYSCTL */ +#endif diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 2889f446ad..a3014e9e2c 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -151,23 +151,6 @@ static inline void fw_state_done(struct fw_priv *fw_priv) int assign_fw(struct firmware *fw, struct device *device); -#ifdef CONFIG_FW_LOADER -bool firmware_is_builtin(const struct firmware *fw); -bool firmware_request_builtin_buf(struct firmware *fw, const char *name, - void *buf, size_t size); -#else /* module case */ -static inline bool firmware_is_builtin(const struct firmware *fw) -{ - return false; -} -static inline bool firmware_request_builtin_buf(struct firmware *fw, - const char *name, - void *buf, size_t size) -{ - return false; -} -#endif - #ifdef CONFIG_FW_LOADER_PAGED_BUF void fw_free_paged_buf(struct fw_priv *fw_priv); int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 94d1789a23..ef904b8b11 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -93,6 +93,66 @@ DEFINE_MUTEX(fw_lock); static struct firmware_cache fw_cache; +/* Builtin firmware support */ + +#ifdef CONFIG_FW_LOADER + +extern struct builtin_fw __start_builtin_fw[]; +extern struct builtin_fw __end_builtin_fw[]; + +static bool fw_copy_to_prealloc_buf(struct firmware *fw, + void *buf, size_t size) +{ + if (!buf) + return true; + if (size < fw->size) + return false; + memcpy(buf, fw->data, fw->size); + return true; +} + +static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, + void *buf, size_t size) +{ + struct builtin_fw *b_fw; + + for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { + if (strcmp(name, b_fw->name) == 0) { + fw->size = b_fw->size; + fw->data = b_fw->data; + return fw_copy_to_prealloc_buf(fw, buf, size); + } + } + + return false; +} + +static bool fw_is_builtin_firmware(const struct firmware *fw) +{ + struct builtin_fw *b_fw; + + for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) + if (fw->data == b_fw->data) + return true; + + return false; +} + +#else /* Module case - no builtin firmware support */ + +static inline bool fw_get_builtin_firmware(struct firmware *fw, + const char *name, void *buf, + size_t size) +{ + return false; +} + +static inline bool fw_is_builtin_firmware(const struct firmware *fw) +{ + return false; +} +#endif + static void fw_state_init(struct fw_priv *fw_priv) { struct fw_state *fw_st = &fw_priv->fw_st; @@ -677,7 +737,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, return -ENOMEM; } - if (firmware_request_builtin_buf(firmware, name, dbuf, size)) { + if (fw_get_builtin_firmware(firmware, name, dbuf, size)) { dev_dbg(device, "using built-in %s\n", name); return 0; /* assigned */ } @@ -992,7 +1052,7 @@ EXPORT_SYMBOL(request_partial_firmware_into_buf); void release_firmware(const struct firmware *fw) { if (fw) { - if (!firmware_is_builtin(fw)) + if (!fw_is_builtin_firmware(fw)) firmware_free_data(fw); kfree(fw); } @@ -1156,7 +1216,7 @@ static int uncache_firmware(const char *fw_name) pr_debug("%s: %s\n", __func__, fw_name); - if (firmware_request_builtin(&fw, fw_name)) + if (fw_get_builtin_firmware(&fw, fw_name, NULL, 0)) return 0; fw_priv = lookup_fw_priv(fw_name); diff --git a/drivers/base/node.c b/drivers/base/node.c index 87acc47e89..c56d34f815 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -581,9 +581,6 @@ static const struct attribute_group node_dev_group = { static const struct attribute_group *node_dev_groups[] = { &node_dev_group, -#ifdef CONFIG_HAVE_ARCH_NODE_DEV_GROUP - &arch_node_dev_group, -#endif NULL }; @@ -632,7 +629,7 @@ static void node_device_release(struct device *dev) { struct node *node = to_node(dev); -#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_HUGETLBFS) +#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS) /* * We schedule the work only when a memory section is * onlined/offlined on this node. When we come here, @@ -785,7 +782,7 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) return 0; } -#ifdef CONFIG_MEMORY_HOTPLUG +#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE static int __ref get_nid_for_pfn(unsigned long pfn) { #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT @@ -961,9 +958,10 @@ static int node_memory_callback(struct notifier_block *self, return NOTIFY_OK; } #endif /* CONFIG_HUGETLBFS */ -#endif /* CONFIG_MEMORY_HOTPLUG */ +#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ -#if !defined(CONFIG_MEMORY_HOTPLUG) || !defined(CONFIG_HUGETLBFS) +#if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \ + !defined(CONFIG_HUGETLBFS) static inline int node_memory_callback(struct notifier_block *self, unsigned long action, void *arg) { diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 296ea673d6..3d6c8f9caf 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -23,6 +23,7 @@ struct platform_msi_priv_data { struct device *dev; void *host_data; + const struct attribute_group **msi_irq_groups; msi_alloc_info_t arg; irq_write_msi_msg_t write_msg; int devid; @@ -38,9 +39,11 @@ static DEFINE_IDA(platform_msi_devid_ida); */ static irq_hw_number_t platform_msi_calc_hwirq(struct msi_desc *desc) { - u32 devid = desc->dev->msi.data->platform_data->devid; + u32 devid; - return (devid << (32 - DEV_ID_SHIFT)) | desc->msi_index; + devid = desc->platform.msi_priv_data->devid; + + return (devid << (32 - DEV_ID_SHIFT)) | desc->platform.msi_index; } static void platform_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc) @@ -83,8 +86,11 @@ static void platform_msi_update_dom_ops(struct msi_domain_info *info) static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg) { struct msi_desc *desc = irq_data_get_msi_desc(data); + struct platform_msi_priv_data *priv_data; - desc->dev->msi.data->platform_data->write_msg(desc, msg); + priv_data = desc->platform.msi_priv_data; + + priv_data->write_msg(desc, msg); } static void platform_msi_update_chip_ops(struct msi_domain_info *info) @@ -107,6 +113,62 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info) info->flags &= ~MSI_FLAG_LEVEL_CAPABLE; } +static void platform_msi_free_descs(struct device *dev, int base, int nvec) +{ + struct msi_desc *desc, *tmp; + + list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { + if (desc->platform.msi_index >= base && + desc->platform.msi_index < (base + nvec)) { + list_del(&desc->list); + free_msi_entry(desc); + } + } +} + +static int platform_msi_alloc_descs_with_irq(struct device *dev, int virq, + int nvec, + struct platform_msi_priv_data *data) + +{ + struct msi_desc *desc; + int i, base = 0; + + if (!list_empty(dev_to_msi_list(dev))) { + desc = list_last_entry(dev_to_msi_list(dev), + struct msi_desc, list); + base = desc->platform.msi_index + 1; + } + + for (i = 0; i < nvec; i++) { + desc = alloc_msi_entry(dev, 1, NULL); + if (!desc) + break; + + desc->platform.msi_priv_data = data; + desc->platform.msi_index = base + i; + desc->irq = virq ? virq + i : 0; + + list_add_tail(&desc->list, dev_to_msi_list(dev)); + } + + if (i != nvec) { + /* Clean up the mess */ + platform_msi_free_descs(dev, base, nvec); + + return -ENOMEM; + } + + return 0; +} + +static int platform_msi_alloc_descs(struct device *dev, int nvec, + struct platform_msi_priv_data *data) + +{ + return platform_msi_alloc_descs_with_irq(dev, 0, nvec, data); +} + /** * platform_msi_create_irq_domain - Create a platform MSI interrupt domain * @fwnode: Optional fwnode of the interrupt controller @@ -129,8 +191,6 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode, platform_msi_update_dom_ops(info); if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) platform_msi_update_chip_ops(info); - info->flags |= MSI_FLAG_DEV_SYSFS | MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | - MSI_FLAG_FREE_MSI_DESCS; domain = msi_create_irq_domain(fwnode, info, parent); if (domain) @@ -139,57 +199,49 @@ struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode, return domain; } -static int platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec, - irq_write_msi_msg_t write_msi_msg) +static struct platform_msi_priv_data * +platform_msi_alloc_priv_data(struct device *dev, unsigned int nvec, + irq_write_msi_msg_t write_msi_msg) { struct platform_msi_priv_data *datap; - int err; - /* * Limit the number of interrupts to 2048 per device. Should we * need to bump this up, DEV_ID_SHIFT should be adjusted * accordingly (which would impact the max number of MSI * capable devices). */ - if (!dev->msi.domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS) - return -EINVAL; + if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS) + return ERR_PTR(-EINVAL); - if (dev->msi.domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { + if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { dev_err(dev, "Incompatible msi_domain, giving up\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } - err = msi_setup_device_data(dev); - if (err) - return err; - - /* Already initialized? */ - if (dev->msi.data->platform_data) - return -EBUSY; + /* Already had a helping of MSI? Greed... */ + if (!list_empty(dev_to_msi_list(dev))) + return ERR_PTR(-EBUSY); datap = kzalloc(sizeof(*datap), GFP_KERNEL); if (!datap) - return -ENOMEM; + return ERR_PTR(-ENOMEM); datap->devid = ida_simple_get(&platform_msi_devid_ida, 0, 1 << DEV_ID_SHIFT, GFP_KERNEL); if (datap->devid < 0) { - err = datap->devid; + int err = datap->devid; kfree(datap); - return err; + return ERR_PTR(err); } datap->write_msg = write_msi_msg; datap->dev = dev; - dev->msi.data->platform_data = datap; - return 0; + + return datap; } -static void platform_msi_free_priv_data(struct device *dev) +static void platform_msi_free_priv_data(struct platform_msi_priv_data *data) { - struct platform_msi_priv_data *data = dev->msi.data->platform_data; - - dev->msi.data->platform_data = NULL; ida_simple_remove(&platform_msi_devid_ida, data->devid); kfree(data); } @@ -206,15 +258,35 @@ static void platform_msi_free_priv_data(struct device *dev) int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, irq_write_msi_msg_t write_msi_msg) { + struct platform_msi_priv_data *priv_data; int err; - err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg); - if (err) - return err; + priv_data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg); + if (IS_ERR(priv_data)) + return PTR_ERR(priv_data); - err = msi_domain_alloc_irqs(dev->msi.domain, dev, nvec); + err = platform_msi_alloc_descs(dev, nvec, priv_data); if (err) - platform_msi_free_priv_data(dev); + goto out_free_priv_data; + + err = msi_domain_alloc_irqs(dev->msi_domain, dev, nvec); + if (err) + goto out_free_desc; + + priv_data->msi_irq_groups = msi_populate_sysfs(dev); + if (IS_ERR(priv_data->msi_irq_groups)) { + err = PTR_ERR(priv_data->msi_irq_groups); + goto out_free_irqs; + } + + return 0; + +out_free_irqs: + msi_domain_free_irqs(dev->msi_domain, dev); +out_free_desc: + platform_msi_free_descs(dev, 0, nvec); +out_free_priv_data: + platform_msi_free_priv_data(priv_data); return err; } @@ -226,8 +298,16 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_alloc_irqs); */ void platform_msi_domain_free_irqs(struct device *dev) { - msi_domain_free_irqs(dev->msi.domain, dev); - platform_msi_free_priv_data(dev); + if (!list_empty(dev_to_msi_list(dev))) { + struct msi_desc *desc; + + desc = first_msi_entry(dev); + msi_destroy_sysfs(dev, desc->platform.msi_priv_data->msi_irq_groups); + platform_msi_free_priv_data(desc->platform.msi_priv_data); + } + + msi_domain_free_irqs(dev->msi_domain, dev); + platform_msi_free_descs(dev, 0, MAX_DEV_MSIS); } EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs); @@ -236,20 +316,17 @@ EXPORT_SYMBOL_GPL(platform_msi_domain_free_irqs); * a platform-msi domain * @domain: The platform-msi domain * - * Return: The private data provided when calling - * platform_msi_create_device_domain(). + * Returns the private data provided when calling + * platform_msi_create_device_domain. */ void *platform_msi_get_host_data(struct irq_domain *domain) { struct platform_msi_priv_data *data = domain->host_data; - return data->host_data; } -static struct lock_class_key platform_device_msi_lock_class; - /** - * __platform_msi_create_device_domain - Create a platform-msi device domain + * __platform_msi_create_device_domain - Create a platform-msi domain * * @dev: The device generating the MSIs * @nvec: The number of MSIs that need to be allocated @@ -258,11 +335,7 @@ static struct lock_class_key platform_device_msi_lock_class; * @ops: The hierarchy domain operations to use * @host_data: Private data associated to this domain * - * Return: An irqdomain for @nvec interrupts on success, NULL in case of error. - * - * This is for interrupt domains which stack on a platform-msi domain - * created by platform_msi_create_irq_domain(). @dev->msi.domain points to - * that platform-msi domain which is the parent for the new domain. + * Returns an irqdomain for @nvec interrupts */ struct irq_domain * __platform_msi_create_device_domain(struct device *dev, @@ -276,20 +349,12 @@ __platform_msi_create_device_domain(struct device *dev, struct irq_domain *domain; int err; - err = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg); - if (err) + data = platform_msi_alloc_priv_data(dev, nvec, write_msi_msg); + if (IS_ERR(data)) return NULL; - /* - * Use a separate lock class for the MSI descriptor mutex on - * platform MSI device domains because the descriptor mutex nests - * into the domain mutex. See alloc/free below. - */ - lockdep_set_class(&dev->msi.data->mutex, &platform_device_msi_lock_class); - - data = dev->msi.data->platform_data; data->host_data = host_data; - domain = irq_domain_create_hierarchy(dev->msi.domain, 0, + domain = irq_domain_create_hierarchy(dev->msi_domain, 0, is_tree ? 0 : nvec, dev->fwnode, ops, data); if (!domain) @@ -305,46 +370,61 @@ __platform_msi_create_device_domain(struct device *dev, free_domain: irq_domain_remove(domain); free_priv: - platform_msi_free_priv_data(dev); + platform_msi_free_priv_data(data); return NULL; } /** - * platform_msi_device_domain_free - Free interrupts associated with a platform-msi - * device domain + * platform_msi_domain_free - Free interrupts associated with a platform-msi + * domain * - * @domain: The platform-msi device domain + * @domain: The platform-msi domain * @virq: The base irq from which to perform the free operation - * @nr_irqs: How many interrupts to free from @virq + * @nvec: How many interrupts to free from @virq */ -void platform_msi_device_domain_free(struct irq_domain *domain, unsigned int virq, - unsigned int nr_irqs) +void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nvec) { struct platform_msi_priv_data *data = domain->host_data; + struct msi_desc *desc, *tmp; + for_each_msi_entry_safe(desc, tmp, data->dev) { + if (WARN_ON(!desc->irq || desc->nvec_used != 1)) + return; + if (!(desc->irq >= virq && desc->irq < (virq + nvec))) + continue; - msi_lock_descs(data->dev); - irq_domain_free_irqs_common(domain, virq, nr_irqs); - msi_free_msi_descs_range(data->dev, MSI_DESC_ALL, virq, virq + nr_irqs - 1); - msi_unlock_descs(data->dev); + irq_domain_free_irqs_common(domain, desc->irq, 1); + list_del(&desc->list); + free_msi_entry(desc); + } } /** - * platform_msi_device_domain_alloc - Allocate interrupts associated with - * a platform-msi device domain + * platform_msi_domain_alloc - Allocate interrupts associated with + * a platform-msi domain * - * @domain: The platform-msi device domain + * @domain: The platform-msi domain * @virq: The base irq from which to perform the allocate operation - * @nr_irqs: How many interrupts to allocate from @virq + * @nr_irqs: How many interrupts to free from @virq * * Return 0 on success, or an error code on failure. Must be called * with irq_domain_mutex held (which can only be done as part of a * top-level interrupt allocation). */ -int platform_msi_device_domain_alloc(struct irq_domain *domain, unsigned int virq, - unsigned int nr_irqs) +int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) { struct platform_msi_priv_data *data = domain->host_data; - struct device *dev = data->dev; + int err; - return msi_domain_populate_irqs(domain->parent, dev, virq, nr_irqs, &data->arg); + err = platform_msi_alloc_descs_with_irq(data->dev, virq, nr_irqs, data); + if (err) + return err; + + err = msi_domain_populate_irqs(domain->parent, data->dev, + virq, nr_irqs, &data->arg); + if (err) + platform_msi_domain_free(domain, virq, nr_irqs); + + return err; } diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 6cb04ac48b..652531f671 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -258,9 +258,8 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) int ret; ret = platform_get_irq_optional(dev, num); - if (ret < 0) - return dev_err_probe(&dev->dev, ret, - "IRQ index %u not found\n", num); + if (ret < 0 && ret != -EPROBE_DEFER) + dev_err(&dev->dev, "IRQ index %u not found\n", num); return ret; } @@ -763,10 +762,6 @@ EXPORT_SYMBOL_GPL(platform_device_del); /** * platform_device_register - add a platform-level device * @pdev: platform device we're adding - * - * NOTE: _Never_ directly free @pdev after calling this function, even if it - * returned an error! Always use platform_device_put() to give up the - * reference initialised in this function instead. */ int platform_device_register(struct platform_device *pdev) { @@ -1471,7 +1466,8 @@ int platform_dma_configure(struct device *dev) } static const struct dev_pm_ops platform_dev_pm_ops = { - SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) + .runtime_suspend = pm_generic_runtime_suspend, + .runtime_resume = pm_generic_runtime_resume, USE_PLATFORM_PM_SLEEP_OPS }; diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 04ea92cbd9..6bce40e250 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -748,6 +749,8 @@ void dpm_resume_noirq(pm_message_t state) resume_device_irqs(); device_wakeup_disarm_wake_irqs(); + + cpuidle_resume(); } /** @@ -1350,6 +1353,8 @@ int dpm_suspend_noirq(pm_message_t state) { int ret; + cpuidle_pause(); + device_wakeup_arm_wake_irqs(); suspend_device_irqs(); @@ -1479,7 +1484,6 @@ int dpm_suspend_late(pm_message_t state) int error = 0; trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true); - wake_up_all_idle_cpus(); mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 0eb7f02b3a..54292cdd78 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -25,10 +25,8 @@ extern u64 pm_runtime_active_time(struct device *dev); #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) -#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ - WAKE_IRQ_DEDICATED_MANAGED | \ - WAKE_IRQ_DEDICATED_REVERSE) + WAKE_IRQ_DEDICATED_MANAGED) struct wake_irq { struct device *dev; @@ -41,8 +39,7 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); extern void dev_pm_enable_wake_irq_check(struct device *dev, bool can_change_status); -extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); -extern void dev_pm_enable_wake_irq_complete(struct device *dev); +extern void dev_pm_disable_wake_irq_check(struct device *dev); #ifdef CONFIG_PM_SLEEP diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 2f3cce1721..44ae3909e6 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -666,8 +666,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) if (retval) goto fail; - dev_pm_enable_wake_irq_complete(dev); - no_callback: __update_runtime_status(dev, RPM_SUSPENDED); pm_runtime_deactivate_timer(dev); @@ -713,7 +711,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) return retval; fail: - dev_pm_disable_wake_irq_check(dev, true); + dev_pm_disable_wake_irq_check(dev); __update_runtime_status(dev, RPM_ACTIVE); dev->power.deferred_resume = false; wake_up_all(&dev->power.wait_queue); @@ -763,15 +761,13 @@ static int rpm_resume(struct device *dev, int rpmflags) trace_rpm_resume_rcuidle(dev, rpmflags); repeat: - if (dev->power.runtime_error) { + if (dev->power.runtime_error) retval = -EINVAL; - } else if (dev->power.disable_depth > 0) { - if (dev->power.runtime_status == RPM_ACTIVE && - dev->power.last_status == RPM_ACTIVE) - retval = 1; - else - retval = -EACCES; - } + else if (dev->power.disable_depth == 1 && dev->power.is_suspended + && dev->power.runtime_status == RPM_ACTIVE) + retval = 1; + else if (dev->power.disable_depth > 0) + retval = -EACCES; if (retval) goto out; @@ -898,7 +894,7 @@ static int rpm_resume(struct device *dev, int rpmflags) callback = RPM_GET_CALLBACK(dev, runtime_resume); - dev_pm_disable_wake_irq_check(dev, false); + dev_pm_disable_wake_irq_check(dev); retval = rpm_callback(callback, dev); if (retval) { __update_runtime_status(dev, RPM_SUSPENDED); @@ -1433,10 +1429,8 @@ void __pm_runtime_disable(struct device *dev, bool check_resume) /* Update time accounting before disabling PM-runtime. */ update_pm_runtime_accounting(dev); - if (!dev->power.disable_depth++) { + if (!dev->power.disable_depth++) __pm_runtime_barrier(dev); - dev->power.last_status = dev->power.runtime_status; - } out: spin_unlock_irq(&dev->power.lock); @@ -1453,23 +1447,23 @@ void pm_runtime_enable(struct device *dev) spin_lock_irqsave(&dev->power.lock, flags); - if (!dev->power.disable_depth) { + if (dev->power.disable_depth > 0) { + dev->power.disable_depth--; + + /* About to enable runtime pm, set accounting_timestamp to now */ + if (!dev->power.disable_depth) + dev->power.accounting_timestamp = ktime_get_mono_fast_ns(); + } else { dev_warn(dev, "Unbalanced %s!\n", __func__); - goto out; } - if (--dev->power.disable_depth > 0) - goto out; + WARN(!dev->power.disable_depth && + dev->power.runtime_status == RPM_SUSPENDED && + !dev->power.ignore_children && + atomic_read(&dev->power.child_count) > 0, + "Enabling runtime PM for inactive device (%s) with active children\n", + dev_name(dev)); - dev->power.last_status = RPM_INVALID; - dev->power.accounting_timestamp = ktime_get_mono_fast_ns(); - - if (dev->power.runtime_status == RPM_SUSPENDED && - !dev->power.ignore_children && - atomic_read(&dev->power.child_count) > 0) - dev_warn(dev, "Enabling runtime PM for inactive device with active children\n"); - -out: spin_unlock_irqrestore(&dev->power.lock, flags); } EXPORT_SYMBOL_GPL(pm_runtime_enable); @@ -1665,7 +1659,6 @@ EXPORT_SYMBOL_GPL(__pm_runtime_use_autosuspend); void pm_runtime_init(struct device *dev) { dev->power.runtime_status = RPM_SUSPENDED; - dev->power.last_status = RPM_INVALID; dev->power.idle_notification = false; dev->power.disable_depth = 1; @@ -1748,6 +1741,8 @@ void pm_runtime_get_suppliers(struct device *dev) void pm_runtime_put_suppliers(struct device *dev) { struct device_link *link; + unsigned long flags; + bool put; int idx; idx = device_links_read_lock(); @@ -1755,17 +1750,11 @@ void pm_runtime_put_suppliers(struct device *dev) list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, device_links_read_lock_held()) if (link->supplier_preactivated) { - bool put; - link->supplier_preactivated = false; - - spin_lock_irq(&dev->power.lock); - + spin_lock_irqsave(&dev->power.lock, flags); put = pm_runtime_status_suspended(dev) && refcount_dec_not_one(&link->rpm_active); - - spin_unlock_irq(&dev->power.lock); - + spin_unlock_irqrestore(&dev->power.lock, flags); if (put) pm_runtime_put(link->supplier); } diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 72b7a92337..94665037f4 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c @@ -120,11 +120,7 @@ static unsigned int read_magic_time(void) struct rtc_time time; unsigned int val; - if (mc146818_get_time(&time) < 0) { - pr_err("Unable to read current time from RTC\n"); - return 0; - } - + mc146818_get_time(&time); pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time); val = time.tm_year; /* 100 years */ if (val > 100) diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index 0004db4a9d..b91a3a9bf9 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -142,7 +142,24 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq) return IRQ_HANDLED; } -static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) +/** + * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt + * @dev: Device entry + * @irq: Device wake-up interrupt + * + * Unless your hardware has separate wake-up interrupts in addition + * to the device IO interrupts, you don't need this. + * + * Sets up a threaded interrupt handler for a device that has + * a dedicated wake-up interrupt in addition to the device IO + * interrupt. + * + * The interrupt starts disabled, and needs to be managed for + * the device by the bus code or the device driver using + * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() + * functions. + */ +int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) { struct wake_irq *wirq; int err; @@ -180,7 +197,7 @@ static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned if (err) goto err_free_irq; - wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; + wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; return err; @@ -193,57 +210,8 @@ static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned return err; } - - -/** - * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt - * @dev: Device entry - * @irq: Device wake-up interrupt - * - * Unless your hardware has separate wake-up interrupts in addition - * to the device IO interrupts, you don't need this. - * - * Sets up a threaded interrupt handler for a device that has - * a dedicated wake-up interrupt in addition to the device IO - * interrupt. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() - * functions. - */ -int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) -{ - return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); -} EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); -/** - * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt - * with reverse enable ordering - * @dev: Device entry - * @irq: Device wake-up interrupt - * - * Unless your hardware has separate wake-up interrupts in addition - * to the device IO interrupts, you don't need this. - * - * Sets up a threaded interrupt handler for a device that has a dedicated - * wake-up interrupt in addition to the device IO interrupt. It sets - * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() - * to enable dedicated wake-up interrupt after running the runtime suspend - * callback for @dev. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() - * functions. - */ -int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) -{ - return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); -} -EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); - /** * dev_pm_enable_wake_irq - Enable device wake-up interrupt * @dev: Device @@ -314,54 +282,27 @@ void dev_pm_enable_wake_irq_check(struct device *dev, return; enable: - if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) - enable_irq(wirq->irq); + enable_irq(wirq->irq); } /** * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt * @dev: Device - * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE * * Disables wake-up interrupt conditionally based on status. * Should be only called from rpm_suspend() and rpm_resume() path. */ -void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) +void dev_pm_disable_wake_irq_check(struct device *dev) { struct wake_irq *wirq = dev->power.wakeirq; if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) return; - if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) - return; - if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) disable_irq_nosync(wirq->irq); } -/** - * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before - * @dev: Device using the wake IRQ - * - * Enable wake IRQ conditionally based on status, mainly used if want to - * enable wake IRQ after running ->runtime_suspend() which depends on - * WAKE_IRQ_DEDICATED_REVERSE. - * - * Should be only called from rpm_suspend() path. - */ -void dev_pm_enable_wake_irq_complete(struct device *dev) -{ - struct wake_irq *wirq = dev->power.wakeirq; - - if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) - return; - - if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && - wirq->status & WAKE_IRQ_DEDICATED_REVERSE) - enable_irq(wirq->irq); -} - /** * dev_pm_arm_wake_irq - Arm device wake-up * @wirq: Device wake-up interrupt diff --git a/drivers/base/property.c b/drivers/base/property.c index e6497f6877..4c77837769 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -15,6 +15,7 @@ #include #include #include +#include #include struct fwnode_handle *dev_fwnode(struct device *dev) @@ -478,17 +479,8 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, unsigned int nargs, unsigned int index, struct fwnode_reference_args *args) { - int ret; - - ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop, - nargs, index, args); - - if (ret < 0 && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_int_op(fwnode->secondary, get_reference_args, - prop, nargs_prop, nargs, index, args); - - return ret; + return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop, + nargs, index, args); } EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); @@ -516,6 +508,54 @@ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_find_reference); +/** + * device_remove_properties - Remove properties from a device object. + * @dev: Device whose properties to remove. + * + * The function removes properties previously associated to the device + * firmware node with device_add_properties(). Memory allocated to the + * properties will also be released. + */ +void device_remove_properties(struct device *dev) +{ + struct fwnode_handle *fwnode = dev_fwnode(dev); + + if (!fwnode) + return; + + if (is_software_node(fwnode->secondary)) { + fwnode_remove_software_node(fwnode->secondary); + set_secondary_fwnode(dev, NULL); + } +} +EXPORT_SYMBOL_GPL(device_remove_properties); + +/** + * device_add_properties - Add a collection of properties to a device object. + * @dev: Device to add properties to. + * @properties: Collection of properties to add. + * + * Associate a collection of device properties represented by @properties with + * @dev. The function takes a copy of @properties. + * + * WARNING: The callers should not use this function if it is known that there + * is no real firmware node associated with @dev! In that case the callers + * should create a software node and assign it to @dev directly. + */ +int device_add_properties(struct device *dev, + const struct property_entry *properties) +{ + struct fwnode_handle *fwnode; + + fwnode = fwnode_create_software_node(properties, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + set_secondary_fwnode(dev, fwnode); + return 0; +} +EXPORT_SYMBOL_GPL(device_add_properties); + /** * fwnode_get_name - Return the name of a node * @fwnode: The firmware node @@ -895,6 +935,68 @@ int device_get_phy_mode(struct device *dev) } EXPORT_SYMBOL_GPL(device_get_phy_mode); +static void *fwnode_get_mac_addr(struct fwnode_handle *fwnode, + const char *name, char *addr, + int alen) +{ + int ret = fwnode_property_read_u8_array(fwnode, name, addr, alen); + + if (ret == 0 && alen == ETH_ALEN && is_valid_ether_addr(addr)) + return addr; + return NULL; +} + +/** + * fwnode_get_mac_address - Get the MAC from the firmware node + * @fwnode: Pointer to the firmware node + * @addr: Address of buffer to store the MAC in + * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN + * + * Search the firmware node for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the firmware tables, but were not updated by the firmware. For + * example, the DTS could define 'mac-address' and 'local-mac-address', with + * zero MAC addresses. Some older U-Boots only initialized 'local-mac-address'. + * In this case, the real MAC is in 'local-mac-address', and 'mac-address' + * exists but is all zeros. +*/ +void *fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr, int alen) +{ + char *res; + + res = fwnode_get_mac_addr(fwnode, "mac-address", addr, alen); + if (res) + return res; + + res = fwnode_get_mac_addr(fwnode, "local-mac-address", addr, alen); + if (res) + return res; + + return fwnode_get_mac_addr(fwnode, "address", addr, alen); +} +EXPORT_SYMBOL(fwnode_get_mac_address); + +/** + * device_get_mac_address - Get the MAC for a given device + * @dev: Pointer to the device + * @addr: Address of buffer to store the MAC in + * @alen: Length of the buffer pointed to by addr, should be ETH_ALEN + */ +void *device_get_mac_address(struct device *dev, char *addr, int alen) +{ + return fwnode_get_mac_address(dev_fwnode(dev), addr, alen); +} +EXPORT_SYMBOL(device_get_mac_address); + /** * fwnode_irq_get - Get IRQ directly from a fwnode * @fwnode: Pointer to the firmware node @@ -919,22 +1021,6 @@ int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index) } EXPORT_SYMBOL(fwnode_irq_get); -/** - * fwnode_iomap - Maps the memory mapped IO for a given fwnode - * @fwnode: Pointer to the firmware node - * @index: Index of the IO range - * - * Returns a pointer to the mapped memory. - */ -void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index) -{ - if (IS_ENABLED(CONFIG_OF_ADDRESS) && is_of_node(fwnode)) - return of_iomap(to_of_node(fwnode), index); - - return NULL; -} -EXPORT_SYMBOL(fwnode_iomap); - /** * fwnode_graph_get_next_endpoint - Get next endpoint firmware node * @fwnode: Pointer to the parent firmware node @@ -1036,17 +1122,43 @@ fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) } EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint); -static bool fwnode_graph_remote_available(struct fwnode_handle *ep) +/** + * fwnode_graph_get_remote_node - get remote parent node for given port/endpoint + * @fwnode: pointer to parent fwnode_handle containing graph port/endpoint + * @port_id: identifier of the parent port node + * @endpoint_id: identifier of the endpoint node + * + * Return: Remote fwnode handle associated with remote endpoint node linked + * to @node. Use fwnode_node_put() on it when done. + */ +struct fwnode_handle * +fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port_id, + u32 endpoint_id) { - struct fwnode_handle *dev_node; - bool available; + struct fwnode_handle *endpoint = NULL; - dev_node = fwnode_graph_get_remote_port_parent(ep); - available = fwnode_device_is_available(dev_node); - fwnode_handle_put(dev_node); + while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) { + struct fwnode_endpoint fwnode_ep; + struct fwnode_handle *remote; + int ret; - return available; + ret = fwnode_graph_parse_endpoint(endpoint, &fwnode_ep); + if (ret < 0) + continue; + + if (fwnode_ep.port != port_id || fwnode_ep.id != endpoint_id) + continue; + + remote = fwnode_graph_get_remote_port_parent(endpoint); + if (!remote) + return NULL; + + return fwnode_device_is_available(remote) ? remote : NULL; + } + + return NULL; } +EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node); /** * fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers @@ -1062,8 +1174,8 @@ static bool fwnode_graph_remote_available(struct fwnode_handle *ep) * has not been found, look for the closest endpoint ID greater than the * specified one and return the endpoint that corresponds to it, if present. * - * Does not return endpoints that belong to disabled devices or endpoints that - * are unconnected, unless FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags. + * Do not return endpoints that belong to disabled devices, unless + * FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags. * * The returned endpoint needs to be released by calling fwnode_handle_put() on * it when it is not needed any more. @@ -1072,17 +1184,25 @@ struct fwnode_handle * fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode, u32 port, u32 endpoint, unsigned long flags) { - struct fwnode_handle *ep, *best_ep = NULL; + struct fwnode_handle *ep = NULL, *best_ep = NULL; unsigned int best_ep_id = 0; bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT; bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED); - fwnode_graph_for_each_endpoint(fwnode, ep) { + while ((ep = fwnode_graph_get_next_endpoint(fwnode, ep))) { struct fwnode_endpoint fwnode_ep = { 0 }; int ret; - if (enabled_only && !fwnode_graph_remote_available(ep)) - continue; + if (enabled_only) { + struct fwnode_handle *dev_node; + bool available; + + dev_node = fwnode_graph_get_remote_port_parent(ep); + available = fwnode_device_is_available(dev_node); + fwnode_handle_put(dev_node); + if (!available) + continue; + } ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep); if (ret < 0) @@ -1115,31 +1235,6 @@ fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id); -/** - * fwnode_graph_get_endpoint_count - Count endpoints on a device node - * @fwnode: The node related to a device - * @flags: fwnode lookup flags - * Count endpoints in a device node. - * - * If FWNODE_GRAPH_DEVICE_DISABLED flag is specified, also unconnected endpoints - * and endpoints connected to disabled devices are counted. - */ -unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode, - unsigned long flags) -{ - struct fwnode_handle *ep; - unsigned int count = 0; - - fwnode_graph_for_each_endpoint(fwnode, ep) { - if (flags & FWNODE_GRAPH_DEVICE_DISABLED || - fwnode_graph_remote_available(ep)) - count++; - } - - return count; -} -EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_count); - /** * fwnode_graph_parse_endpoint - parse common endpoint node properties * @fwnode: pointer to endpoint fwnode_handle diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 817eda2075..ad684d37c2 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -598,7 +598,7 @@ void regmap_debugfs_init(struct regmap *map) map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", dummy_index); if (!map->debugfs_name) - return; + return; name = map->debugfs_name; dummy_index++; } diff --git a/drivers/base/regmap/regmap-mdio.c b/drivers/base/regmap/regmap-mdio.c index f7293040a2..6a20201299 100644 --- a/drivers/base/regmap/regmap-mdio.c +++ b/drivers/base/regmap/regmap-mdio.c @@ -14,7 +14,7 @@ static int regmap_mdio_read(struct mdio_device *mdio_dev, u32 reg, unsigned int { int ret; - ret = mdiodev_read(mdio_dev, reg); + ret = mdiobus_read(mdio_dev->bus, mdio_dev->addr, reg); if (ret < 0) return ret; @@ -24,7 +24,7 @@ static int regmap_mdio_read(struct mdio_device *mdio_dev, u32 reg, unsigned int static int regmap_mdio_write(struct mdio_device *mdio_dev, u32 reg, unsigned int val) { - return mdiodev_write(mdio_dev, reg, val); + return mdiobus_write(mdio_dev->bus, mdio_dev->addr, reg, val); } static int regmap_mdio_c22_read(void *context, unsigned int reg, unsigned int *val) @@ -44,7 +44,7 @@ static int regmap_mdio_c22_write(void *context, unsigned int reg, unsigned int v if (unlikely(reg & ~REGNUM_C22_MASK)) return -ENXIO; - return mdiodev_write(mdio_dev, reg, val); + return mdiobus_write(mdio_dev->bus, mdio_dev->addr, reg, val); } static const struct regmap_bus regmap_mdio_c22_bus = { diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 719323bc6c..c1894e93c3 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -109,37 +109,13 @@ static const struct regmap_bus regmap_spi = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; -static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, - const struct regmap_config *config) -{ - size_t max_size = spi_max_transfer_size(spi); - struct regmap_bus *bus; - - if (max_size != SIZE_MAX) { - bus = kmemdup(®map_spi, sizeof(*bus), GFP_KERNEL); - if (!bus) - return ERR_PTR(-ENOMEM); - - bus->free_on_exit = true; - bus->max_raw_read = max_size; - bus->max_raw_write = max_size; - return bus; - } - - return ®map_spi; -} - struct regmap *__regmap_init_spi(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { - const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); - - if (IS_ERR(bus)) - return ERR_CAST(bus); - - return __regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); + return __regmap_init(&spi->dev, ®map_spi, &spi->dev, config, + lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_spi); @@ -148,12 +124,8 @@ struct regmap *__devm_regmap_init_spi(struct spi_device *spi, struct lock_class_key *lock_key, const char *lock_name) { - const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); - - if (IS_ERR(bus)) - return ERR_CAST(bus); - - return __devm_regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); + return __devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config, + lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_spi); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 8f9fe5fd47..f7811641ed 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -877,7 +877,6 @@ struct regmap *__regmap_init(struct device *dev, if (!bus) { map->reg_read = config->reg_read; map->reg_write = config->reg_write; - map->reg_update_bits = config->reg_update_bits; map->defer_caching = false; goto skip_format_initialization; diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 0a482212c7..3ba1232ce8 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -413,6 +413,9 @@ software_node_get_name(const struct fwnode_handle *fwnode) { const struct swnode *swnode = to_swnode(fwnode); + if (!swnode) + return "(null)"; + return kobject_name(&swnode->kobj); } @@ -504,6 +507,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, int error; int i; + if (!swnode) + return -ENOENT; + prop = property_entry_get(swnode->node->properties, propname); if (!prop) return -ENOENT; diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c index 4d1976ca50..3bb7beb127 100644 --- a/drivers/base/test/test_async_driver_probe.c +++ b/drivers/base/test/test_async_driver_probe.c @@ -104,7 +104,7 @@ static int __init test_async_probe_init(void) struct platform_device **pdev = NULL; int async_id = 0, sync_id = 0; unsigned long long duration; - ktime_t calltime; + ktime_t calltime, delta; int err, nid, cpu; pr_info("registering first set of asynchronous devices...\n"); @@ -133,7 +133,8 @@ static int __init test_async_probe_init(void) goto err_unregister_async_devs; } - duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime); + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); pr_info("registration took %lld msecs\n", duration); if (duration > TEST_PROBE_THRESHOLD) { pr_err("test failed: probe took too long\n"); @@ -160,7 +161,8 @@ static int __init test_async_probe_init(void) async_id++; } - duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime); + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); dev_info(&(*pdev)->dev, "registration took %lld msecs\n", duration); if (duration > TEST_PROBE_THRESHOLD) { @@ -195,7 +197,8 @@ static int __init test_async_probe_init(void) goto err_unregister_sync_devs; } - duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime); + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); pr_info("registration took %lld msecs\n", duration); if (duration < TEST_PROBE_THRESHOLD) { dev_err(&(*pdev)->dev, @@ -220,7 +223,8 @@ static int __init test_async_probe_init(void) sync_id++; - duration = (unsigned long long)ktime_ms_delta(ktime_get(), calltime); + delta = ktime_sub(ktime_get(), calltime); + duration = (unsigned long long) ktime_to_ms(delta); dev_info(&(*pdev)->dev, "registration took %lld msecs\n", duration); if (duration < TEST_PROBE_THRESHOLD) { diff --git a/drivers/base/topology.c b/drivers/base/topology.c index fc24e89f95..43c0940643 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -45,15 +45,8 @@ static ssize_t name##_list_read(struct file *file, struct kobject *kobj, \ define_id_show_func(physical_package_id); static DEVICE_ATTR_RO(physical_package_id); -#ifdef TOPOLOGY_DIE_SYSFS define_id_show_func(die_id); static DEVICE_ATTR_RO(die_id); -#endif - -#ifdef TOPOLOGY_CLUSTER_SYSFS -define_id_show_func(cluster_id); -static DEVICE_ATTR_RO(cluster_id); -#endif define_id_show_func(core_id); static DEVICE_ATTR_RO(core_id); @@ -70,23 +63,15 @@ define_siblings_read_func(core_siblings, core_cpumask); static BIN_ATTR_RO(core_siblings, 0); static BIN_ATTR_RO(core_siblings_list, 0); -#ifdef TOPOLOGY_CLUSTER_SYSFS -define_siblings_read_func(cluster_cpus, cluster_cpumask); -static BIN_ATTR_RO(cluster_cpus, 0); -static BIN_ATTR_RO(cluster_cpus_list, 0); -#endif - -#ifdef TOPOLOGY_DIE_SYSFS define_siblings_read_func(die_cpus, die_cpumask); static BIN_ATTR_RO(die_cpus, 0); static BIN_ATTR_RO(die_cpus_list, 0); -#endif define_siblings_read_func(package_cpus, core_cpumask); static BIN_ATTR_RO(package_cpus, 0); static BIN_ATTR_RO(package_cpus_list, 0); -#ifdef TOPOLOGY_BOOK_SYSFS +#ifdef CONFIG_SCHED_BOOK define_id_show_func(book_id); static DEVICE_ATTR_RO(book_id); define_siblings_read_func(book_siblings, book_cpumask); @@ -94,7 +79,7 @@ static BIN_ATTR_RO(book_siblings, 0); static BIN_ATTR_RO(book_siblings_list, 0); #endif -#ifdef TOPOLOGY_DRAWER_SYSFS +#ifdef CONFIG_SCHED_DRAWER define_id_show_func(drawer_id); static DEVICE_ATTR_RO(drawer_id); define_siblings_read_func(drawer_siblings, drawer_cpumask); @@ -109,21 +94,15 @@ static struct bin_attribute *bin_attrs[] = { &bin_attr_thread_siblings_list, &bin_attr_core_siblings, &bin_attr_core_siblings_list, -#ifdef TOPOLOGY_CLUSTER_SYSFS - &bin_attr_cluster_cpus, - &bin_attr_cluster_cpus_list, -#endif -#ifdef TOPOLOGY_DIE_SYSFS &bin_attr_die_cpus, &bin_attr_die_cpus_list, -#endif &bin_attr_package_cpus, &bin_attr_package_cpus_list, -#ifdef TOPOLOGY_BOOK_SYSFS +#ifdef CONFIG_SCHED_BOOK &bin_attr_book_siblings, &bin_attr_book_siblings_list, #endif -#ifdef TOPOLOGY_DRAWER_SYSFS +#ifdef CONFIG_SCHED_DRAWER &bin_attr_drawer_siblings, &bin_attr_drawer_siblings_list, #endif @@ -132,17 +111,12 @@ static struct bin_attribute *bin_attrs[] = { static struct attribute *default_attrs[] = { &dev_attr_physical_package_id.attr, -#ifdef TOPOLOGY_DIE_SYSFS &dev_attr_die_id.attr, -#endif -#ifdef TOPOLOGY_CLUSTER_SYSFS - &dev_attr_cluster_id.attr, -#endif &dev_attr_core_id.attr, -#ifdef TOPOLOGY_BOOK_SYSFS +#ifdef CONFIG_SCHED_BOOK &dev_attr_book_id.attr, #endif -#ifdef TOPOLOGY_DRAWER_SYSFS +#ifdef CONFIG_SCHED_DRAWER &dev_attr_drawer_id.attr, #endif NULL diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 960632197b..69c10a7b7c 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -162,6 +162,7 @@ static int bcma_host_pci_probe(struct pci_dev *dev, { struct bcma_bus *bus; int err = -ENOMEM; + const char *name; u32 val; /* Alloc */ @@ -174,7 +175,10 @@ static int bcma_host_pci_probe(struct pci_dev *dev, if (err) goto err_kfree_bus; - err = pci_request_regions(dev, "bcma-pci-bridge"); + name = dev_name(&dev->dev); + if (dev->driver && dev->driver->name) + name = dev->driver->name; + err = pci_request_regions(dev, name); if (err) goto err_pci_disable; pci_set_master(dev); diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 8e7ca3e4c8..c6d6ba0d00 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -20,7 +20,7 @@ MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); MODULE_LICENSE("GPL"); /* contains the number the next bus should get. */ -static unsigned int bcma_bus_next_num; +static unsigned int bcma_bus_next_num = 0; /* bcma_buses_mutex locks the bcma_bus_next_num */ static DEFINE_MUTEX(bcma_buses_mutex); diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 519b6d38d4..ab3e37aa18 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -180,6 +180,14 @@ config BLK_DEV_LOOP bits of, say, a sound file). This is also safe if the file resides on a remote file server. + There are several ways of encrypting disks. Some of these require + kernel patches. The vanilla kernel offers the cryptoloop option + and a Device Mapper target (which is superior, as it supports all + file systems). If you want to use the cryptoloop, say Y to both + LOOP and CRYPTOLOOP, and make sure you have a recent (version 2.12 + or later) version of util-linux. Additionally, be aware that + the cryptoloop is not safe for storing journaled filesystems. + Note that this loop device has nothing to do with the loopback device used for network connections from the machine to itself. @@ -203,6 +211,21 @@ config BLK_DEV_LOOP_MIN_COUNT is used, it can be set to 0, since needed loop devices can be dynamically allocated with the /dev/loop-control interface. +config BLK_DEV_CRYPTOLOOP + tristate "Cryptoloop Support (DEPRECATED)" + select CRYPTO + select CRYPTO_CBC + depends on BLK_DEV_LOOP + help + Say Y here if you want to be able to use the ciphers that are + provided by the CryptoAPI as loop transformation. This might be + used as hard disk encryption. + + WARNING: This device is not safe for journaled file systems like + ext3 or Reiserfs. Please use the Device Mapper crypto module + instead, which can be configured to be on-disk compatible with the + cryptoloop device. cryptoloop support will be removed in Linux 5.16. + source "drivers/block/drbd/Kconfig" config BLK_DEV_NBD @@ -281,8 +304,8 @@ config BLK_DEV_RAM_SIZE config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media (DEPRECATED)" depends on !UML - depends on SCSI select CDROM + select SCSI_COMMON help Note: This driver is deprecated and will be removed from the kernel in the near future! @@ -371,7 +394,6 @@ config XEN_BLKDEV_BACKEND config VIRTIO_BLK tristate "Virtio block driver" depends on VIRTIO - select SG_POOL help This is the virtual block driver for virtio. It can be used with QEMU based VMMs (like KVM or Xen). Say Y or M. @@ -392,6 +414,17 @@ config BLK_DEV_RBD If unsure, say N. +config BLK_DEV_RSXX + tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" + depends on PCI + select CRC32 + help + Device driver for IBM's high speed PCIe SSD + storage device: Flash Adapter 900GB Full Height. + + To compile this driver as a module, choose M here: the + module will be called rsxx. + source "drivers/block/rnbd/Kconfig" endif # BLK_DEV diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 934a9c7c3a..bc68817ef4 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o obj-$(CONFIG_SUNVDC) += sunvdc.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o +obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o @@ -34,6 +35,7 @@ obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ obj-$(CONFIG_BLK_DEV_RBD) += rbd.o obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/ +obj-$(CONFIG_BLK_DEV_RSXX) += rsxx/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_BLK_DEV_RNBD) += rnbd/ diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 5a566f2fd5..8b17140214 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -61,10 +61,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -1505,7 +1505,7 @@ static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { struct request *rq = bd->rq; - struct amiga_floppy_struct *floppy = rq->q->disk->private_data; + struct amiga_floppy_struct *floppy = rq->rq_disk->private_data; blk_status_t err; if (!spin_trylock_irq(&amiflop_lock)) @@ -1780,7 +1780,6 @@ static const struct blk_mq_ops amiflop_mq_ops = { static int fd_alloc_disk(int drive, int system) { struct gendisk *disk; - int err; disk = blk_mq_alloc_disk(&unit[drive].tag_set, NULL); if (IS_ERR(disk)) @@ -1790,7 +1789,6 @@ static int fd_alloc_disk(int drive, int system) disk->first_minor = drive + system; disk->minors = 1; disk->fops = &floppy_fops; - disk->flags |= GENHD_FL_NO_PART; disk->events = DISK_EVENT_MEDIA_CHANGE; if (system) sprintf(disk->disk_name, "fd%d_msdos", drive); @@ -1800,10 +1798,8 @@ static int fd_alloc_disk(int drive, int system) set_capacity(disk, 880 * 2); unit[drive].gendisk[system] = disk; - err = add_disk(disk); - if (err) - blk_cleanup_disk(disk); - return err; + add_disk(disk); + return 0; } static int fd_alloc_drive(int drive) diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 52484bcded..06b360f712 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -37,7 +37,8 @@ static ssize_t aoedisk_show_state(struct device *dev, struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; - return sysfs_emit(page, "%s%s\n", + return snprintf(page, PAGE_SIZE, + "%s%s\n", (d->flags & DEVFL_UP) ? "up" : "down", (d->flags & DEVFL_KICKME) ? ",kickme" : (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); @@ -51,8 +52,8 @@ static ssize_t aoedisk_show_mac(struct device *dev, struct aoetgt *t = d->targets[0]; if (t == NULL) - return sysfs_emit(page, "none\n"); - return sysfs_emit(page, "%pm\n", t->addr); + return snprintf(page, PAGE_SIZE, "none\n"); + return snprintf(page, PAGE_SIZE, "%pm\n", t->addr); } static ssize_t aoedisk_show_netif(struct device *dev, struct device_attribute *attr, char *page) @@ -84,7 +85,7 @@ static ssize_t aoedisk_show_netif(struct device *dev, ne = nd; nd = nds; if (*nd == NULL) - return sysfs_emit(page, "none\n"); + return snprintf(page, PAGE_SIZE, "none\n"); for (p = page; nd < ne; nd++) p += scnprintf(p, PAGE_SIZE - (p-page), "%s%s", p == page ? "" : ",", (*nd)->name); @@ -98,7 +99,7 @@ static ssize_t aoedisk_show_fwver(struct device *dev, struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; - return sysfs_emit(page, "0x%04x\n", (unsigned int) d->fw_ver); + return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); } static ssize_t aoedisk_show_payload(struct device *dev, struct device_attribute *attr, char *page) @@ -106,7 +107,7 @@ static ssize_t aoedisk_show_payload(struct device *dev, struct gendisk *disk = dev_to_disk(dev); struct aoedev *d = disk->private_data; - return sysfs_emit(page, "%lu\n", d->maxbcnt); + return snprintf(page, PAGE_SIZE, "%lu\n", d->maxbcnt); } static int aoedisk_debugfs_show(struct seq_file *s, void *ignored) @@ -416,9 +417,7 @@ aoeblk_gdalloc(void *vp) spin_unlock_irqrestore(&d->lock, flags); - err = device_add_disk(NULL, gd, aoe_attr_groups); - if (err) - goto out_disk_cleanup; + device_add_disk(NULL, gd, aoe_attr_groups); aoedisk_add_debugfs(d); spin_lock_irqsave(&d->lock, flags); @@ -427,8 +426,6 @@ aoeblk_gdalloc(void *vp) spin_unlock_irqrestore(&d->lock, flags); return; -out_disk_cleanup: - blk_cleanup_disk(gd); err_tagset: blk_mq_free_tag_set(set); err_mempool: diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 6af111f568..588889bea7 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -122,7 +122,7 @@ newtag(struct aoedev *d) register ulong n; n = jiffies & 0xffff; - return n | (++d->lasttag & 0x7fff) << 16; + return n |= (++d->lasttag & 0x7fff) << 16; } static u32 diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 5d819a466e..aab48b292a 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -68,7 +68,6 @@ #include #include #include -#include #include #include #include @@ -1460,7 +1459,8 @@ static int floppy_revalidate(struct gendisk *disk) unsigned int drive = p - unit; if (test_bit(drive, &changed_floppies) || - test_bit(drive, &fake_change) || !p->disktype) { + test_bit(drive, &fake_change) || + p->disktype == 0) { if (UD.flags & FTD_MSG) printk(KERN_ERR "floppy: clear format %p!\n", UDT); BufferDrive = -1; @@ -1502,7 +1502,7 @@ static void setup_req_params( int drive ) static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { - struct atari_floppy_struct *floppy = bd->rq->q->disk->private_data; + struct atari_floppy_struct *floppy = bd->rq->rq_disk->private_data; int drive = floppy - unit; int type = floppy->type; @@ -1538,7 +1538,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, if (!UDT) { Probing = 1; UDT = atari_disk_type + StartDiskType[DriveType]; - set_capacity(bd->rq->q->disk, UDT->blocks); + set_capacity(bd->rq->rq_disk, UDT->blocks); UD.autoprobe = 1; } } @@ -1558,7 +1558,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, } type = minor2disktype[type].index; UDT = &atari_disk_type[type]; - set_capacity(bd->rq->q->disk, UDT->blocks); + set_capacity(bd->rq->rq_disk, UDT->blocks); UD.autoprobe = 0; } @@ -2000,7 +2000,6 @@ static int ataflop_alloc_disk(unsigned int drive, unsigned int type) disk->minors = 1; sprintf(disk->disk_name, "fd%d", drive); disk->fops = &floppy_fops; - disk->flags |= GENHD_FL_NO_PART; disk->events = DISK_EVENT_MEDIA_CHANGE; disk->private_data = &unit[drive]; set_capacity(disk, MAX_DISK_SIZE * 2); @@ -2019,18 +2018,12 @@ static void ataflop_probe(dev_t dev) if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS) return; - if (unit[drive].disk[type]) - return; - if (ataflop_alloc_disk(drive, type)) - return; - if (add_disk(unit[drive].disk[type])) - goto cleanup_disk; - unit[drive].registered[type] = true; - return; - -cleanup_disk: - blk_cleanup_disk(unit[drive].disk[type]); - unit[drive].disk[type] = NULL; + if (!unit[drive].disk[type]) { + if (ataflop_alloc_disk(drive, type) == 0) { + add_disk(unit[drive].disk[type]); + unit[drive].registered[type] = true; + } + } } static void atari_floppy_cleanup(void) @@ -2120,9 +2113,7 @@ static int __init atari_floppy_init (void) for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].track = -1; unit[i].flags = 0; - ret = add_disk(unit[i].disk[0]); - if (ret) - goto err_out_dma; + add_disk(unit[i].disk[0]); unit[i].registered[0] = true; } @@ -2138,8 +2129,6 @@ static int __init atari_floppy_init (void) } return ret; -err_out_dma: - atari_stram_free(DMABuffer); err: while (--i >= 0) atari_cleanup_floppy_disk(&unit[i]); diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 6e3f2f0d23..530b312402 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -282,7 +282,7 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page, return err; } -static void brd_submit_bio(struct bio *bio) +static blk_qc_t brd_submit_bio(struct bio *bio) { struct brd_device *brd = bio->bi_bdev->bd_disk->private_data; sector_t sector = bio->bi_iter.bi_sector; @@ -299,14 +299,16 @@ static void brd_submit_bio(struct bio *bio) err = brd_do_bvec(brd, bvec.bv_page, len, bvec.bv_offset, bio_op(bio), sector); - if (err) { - bio_io_error(bio); - return; - } + if (err) + goto io_error; sector += len >> SECTOR_SHIFT; } bio_endio(bio); + return BLK_QC_T_NONE; +io_error: + bio_io_error(bio); + return BLK_QC_T_NONE; } static int brd_rw_page(struct block_device *bdev, sector_t sector, @@ -362,6 +364,7 @@ __setup("ramdisk_size=", ramdisk_size); * (should share code eventually). */ static LIST_HEAD(brd_devices); +static DEFINE_MUTEX(brd_devices_mutex); static struct dentry *brd_debugfs_dir; static int brd_alloc(int i) @@ -369,16 +372,22 @@ static int brd_alloc(int i) struct brd_device *brd; struct gendisk *disk; char buf[DISK_NAME_LEN]; - int err = -ENOMEM; - list_for_each_entry(brd, &brd_devices, brd_list) - if (brd->brd_number == i) + mutex_lock(&brd_devices_mutex); + list_for_each_entry(brd, &brd_devices, brd_list) { + if (brd->brd_number == i) { + mutex_unlock(&brd_devices_mutex); return -EEXIST; + } + } brd = kzalloc(sizeof(*brd), GFP_KERNEL); - if (!brd) + if (!brd) { + mutex_unlock(&brd_devices_mutex); return -ENOMEM; + } brd->brd_number = i; list_add_tail(&brd->brd_list, &brd_devices); + mutex_unlock(&brd_devices_mutex); spin_lock_init(&brd->brd_lock); INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC); @@ -397,6 +406,7 @@ static int brd_alloc(int i) disk->minors = max_part; disk->fops = &brd_fops; disk->private_data = brd; + disk->flags = GENHD_FL_EXT_DEVT; strlcpy(disk->disk_name, buf, DISK_NAME_LEN); set_capacity(disk, rd_size * 2); @@ -412,18 +422,16 @@ static int brd_alloc(int i) /* Tell the block layer that this is not a rotational device */ blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue); blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue); - err = add_disk(disk); - if (err) - goto out_cleanup_disk; + add_disk(disk); return 0; -out_cleanup_disk: - blk_cleanup_disk(disk); out_free_dev: + mutex_lock(&brd_devices_mutex); list_del(&brd->brd_list); + mutex_unlock(&brd_devices_mutex); kfree(brd); - return err; + return -ENOMEM; } static void brd_probe(dev_t dev) @@ -431,19 +439,15 @@ static void brd_probe(dev_t dev) brd_alloc(MINOR(dev) / max_part); } -static void brd_cleanup(void) +static void brd_del_one(struct brd_device *brd) { - struct brd_device *brd, *next; - - debugfs_remove_recursive(brd_debugfs_dir); - - list_for_each_entry_safe(brd, next, &brd_devices, brd_list) { - del_gendisk(brd->brd_disk); - blk_cleanup_disk(brd->brd_disk); - brd_free_pages(brd); - list_del(&brd->brd_list); - kfree(brd); - } + del_gendisk(brd->brd_disk); + blk_cleanup_disk(brd->brd_disk); + brd_free_pages(brd); + mutex_lock(&brd_devices_mutex); + list_del(&brd->brd_list); + mutex_unlock(&brd_devices_mutex); + kfree(brd); } static inline void brd_check_and_reset_par(void) @@ -467,18 +471,9 @@ static inline void brd_check_and_reset_par(void) static int __init brd_init(void) { + struct brd_device *brd, *next; int err, i; - brd_check_and_reset_par(); - - brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL); - - for (i = 0; i < rd_nr; i++) { - err = brd_alloc(i); - if (err) - goto out_free; - } - /* * brd module now has a feature to instantiate underlying device * structure on-demand, provided that there is an access dev node. @@ -494,16 +489,28 @@ static int __init brd_init(void) * dynamically. */ - if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe)) { - err = -EIO; - goto out_free; + if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe)) + return -EIO; + + brd_check_and_reset_par(); + + brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL); + + for (i = 0; i < rd_nr; i++) { + err = brd_alloc(i); + if (err) + goto out_free; } pr_info("brd: module loaded\n"); return 0; out_free: - brd_cleanup(); + unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); + debugfs_remove_recursive(brd_debugfs_dir); + + list_for_each_entry_safe(brd, next, &brd_devices, brd_list) + brd_del_one(brd); pr_info("brd: module NOT loaded !!!\n"); return err; @@ -511,9 +518,13 @@ static int __init brd_init(void) static void __exit brd_exit(void) { + struct brd_device *brd, *next; unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); - brd_cleanup(); + debugfs_remove_recursive(brd_debugfs_dir); + + list_for_each_entry_safe(brd, next, &brd_devices, brd_list) + brd_del_one(brd); pr_info("brd: module unloaded\n"); } diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index f27d5b0f9a..5d9181382c 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1448,7 +1448,7 @@ extern void conn_free_crypto(struct drbd_connection *connection); /* drbd_req */ extern void do_submit(struct work_struct *ws); extern void __drbd_make_request(struct drbd_device *, struct bio *); -void drbd_submit_bio(struct bio *bio); +extern blk_qc_t drbd_submit_bio(struct bio *bio); extern int drbd_read_remote(struct drbd_device *device, struct drbd_request *req); extern int is_valid_ar_handle(struct drbd_request *, sector_t); @@ -1826,7 +1826,8 @@ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) /* Returns the number of 512 byte sectors of the device */ static inline sector_t drbd_get_capacity(struct block_device *bdev) { - return bdev ? bdev_nr_sectors(bdev) : 0; + /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ + return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0; } /** diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 6f450816c4..55234a558e 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -729,8 +729,7 @@ int drbd_send_sync_param(struct drbd_peer_device *peer_device) cmd = apv >= 89 ? P_SYNC_PARAM89 : P_SYNC_PARAM; /* initialize verify_alg and csums_alg */ - BUILD_BUG_ON(sizeof(p->algs) != 2 * SHARED_SECRET_MAX); - memset(&p->algs, 0, sizeof(p->algs)); + memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); if (get_ldev(peer_device->device)) { dc = rcu_dereference(peer_device->device->ldev->disk_conf); @@ -2735,7 +2734,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig disk->first_minor = minor; disk->minors = 1; disk->fops = &drbd_ops; - disk->flags |= GENHD_FL_NO_PART; sprintf(disk->disk_name, "drbd%d", minor); disk->private_data = device; @@ -2796,9 +2794,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig goto out_idr_remove_vol; } - err = add_disk(disk); - if (err) - goto out_idr_remove_vol; + add_disk(disk); /* inherit the connection state */ device->state.conn = first_connection(resource)->cstate; diff --git a/drivers/block/drbd/drbd_protocol.h b/drivers/block/drbd/drbd_protocol.h index a882b65ab5..dea59c92ec 100644 --- a/drivers/block/drbd/drbd_protocol.h +++ b/drivers/block/drbd/drbd_protocol.h @@ -283,10 +283,8 @@ struct p_rs_param_89 { struct p_rs_param_95 { u32 resync_rate; - struct_group(algs, - char verify_alg[SHARED_SECRET_MAX]; - char csums_alg[SHARED_SECRET_MAX]; - ); + char verify_alg[SHARED_SECRET_MAX]; + char csums_alg[SHARED_SECRET_MAX]; u32 c_plan_ahead; u32 c_delay_target; u32 c_fill_target; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 6df2539e21..1f740e42e4 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3921,8 +3921,7 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i /* initialize verify_alg and csums_alg */ p = pi->data; - BUILD_BUG_ON(sizeof(p->algs) != 2 * SHARED_SECRET_MAX); - memset(&p->algs, 0, sizeof(p->algs)); + memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); err = drbd_recv_all(peer_device->connection, p, header_size); if (err) diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 3235532ae0..5ca233644d 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -1596,7 +1596,7 @@ void do_submit(struct work_struct *ws) } } -void drbd_submit_bio(struct bio *bio) +blk_qc_t drbd_submit_bio(struct bio *bio) { struct drbd_device *device = bio->bi_bdev->bd_disk->private_data; @@ -1609,6 +1609,7 @@ void drbd_submit_bio(struct bio *bio) inc_ap_bio(device); __drbd_make_request(device, bio); + return BLK_QC_T_NONE; } static bool net_timeout_reached(struct drbd_request *net_req, diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index e611411a93..4a6a74177b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -184,7 +184,6 @@ static int print_unex = 1; #include #include #include -#include #include #include #include @@ -2259,7 +2258,7 @@ static int do_format(int drive, struct format_descr *tmp_format_req) static void floppy_end_request(struct request *req, blk_status_t error) { unsigned int nr_sectors = current_count_sectors; - unsigned int drive = (unsigned long)req->q->disk->private_data; + unsigned int drive = (unsigned long)req->rq_disk->private_data; /* current_count_sectors can be zero if transfer failed */ if (error) @@ -2550,7 +2549,7 @@ static int make_raw_rw_request(void) if (WARN(max_buffer_sectors == 0, "VFS: Block I/O scheduled on unopened device\n")) return 0; - set_fdc((long)current_req->q->disk->private_data); + set_fdc((long)current_req->rq_disk->private_data); raw_cmd = &default_raw_cmd; raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK; @@ -2792,7 +2791,7 @@ static void redo_fd_request(void) return; } } - drive = (long)current_req->q->disk->private_data; + drive = (long)current_req->rq_disk->private_data; set_fdc(drive); reschedule_timeout(current_drive, "redo fd request"); @@ -4505,7 +4504,6 @@ static int floppy_alloc_disk(unsigned int drive, unsigned int type) disk->first_minor = TOMINOR(drive) | (type << 2); disk->minors = 1; disk->fops = &floppy_fops; - disk->flags |= GENHD_FL_NO_PART; disk->events = DISK_EVENT_MEDIA_CHANGE; if (type) sprintf(disk->disk_name, "fd%d_type%d", drive, type); @@ -4531,19 +4529,10 @@ static void floppy_probe(dev_t dev) return; mutex_lock(&floppy_probe_lock); - if (disks[drive][type]) - goto out; - if (floppy_alloc_disk(drive, type)) - goto out; - if (add_disk(disks[drive][type])) - goto cleanup_disk; -out: - mutex_unlock(&floppy_probe_lock); - return; - -cleanup_disk: - blk_cleanup_disk(disks[drive][type]); - disks[drive][type] = NULL; + if (!disks[drive][type]) { + if (floppy_alloc_disk(drive, type) == 0) + add_disk(disks[drive][type]); + } mutex_unlock(&floppy_probe_lock); } @@ -4709,10 +4698,8 @@ static int __init do_floppy_init(void) registered[drive] = true; - err = device_add_disk(&floppy_device[drive].dev, - disks[drive][0], NULL); - if (err) - goto out_remove_drives; + device_add_disk(&floppy_device[drive].dev, disks[drive][0], + NULL); } return 0; @@ -4970,9 +4957,26 @@ static void __exit floppy_module_exit(void) } for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { if (disks[drive][i]) - blk_cleanup_disk(disks[drive][i]); + blk_cleanup_queue(disks[drive][i]->queue); } blk_mq_free_tag_set(&tag_sets[drive]); + + /* + * These disks have not called add_disk(). Don't put down + * queue reference in put_disk(). + */ + if (!(allowed_drive_mask & (1 << drive)) || + fdc_state[FDC(drive)].version == FDC_NONE) { + for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { + if (disks[drive][i]) + disks[drive][i]->queue = NULL; + } + } + + for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { + if (disks[drive][i]) + put_disk(disks[drive][i]); + } } cancel_delayed_work_sync(&fd_timeout); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 19fe19eaa5..92f9d32bfa 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -134,6 +134,58 @@ static void loop_global_unlock(struct loop_device *lo, bool global) static int max_part; static int part_shift; +static int transfer_xor(struct loop_device *lo, int cmd, + struct page *raw_page, unsigned raw_off, + struct page *loop_page, unsigned loop_off, + int size, sector_t real_block) +{ + char *raw_buf = kmap_atomic(raw_page) + raw_off; + char *loop_buf = kmap_atomic(loop_page) + loop_off; + char *in, *out, *key; + int i, keysize; + + if (cmd == READ) { + in = raw_buf; + out = loop_buf; + } else { + in = loop_buf; + out = raw_buf; + } + + key = lo->lo_encrypt_key; + keysize = lo->lo_encrypt_key_size; + for (i = 0; i < size; i++) + *out++ = *in++ ^ key[(i & 511) % keysize]; + + kunmap_atomic(loop_buf); + kunmap_atomic(raw_buf); + cond_resched(); + return 0; +} + +static int xor_init(struct loop_device *lo, const struct loop_info64 *info) +{ + if (unlikely(info->lo_encrypt_key_size <= 0)) + return -EINVAL; + return 0; +} + +static struct loop_func_table none_funcs = { + .number = LO_CRYPT_NONE, +}; + +static struct loop_func_table xor_funcs = { + .number = LO_CRYPT_XOR, + .transfer = transfer_xor, + .init = xor_init +}; + +/* xfer_funcs[0] is special - its release function is never called */ +static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { + &none_funcs, + &xor_funcs +}; + static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file) { loff_t loopsize; @@ -177,7 +229,8 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) /* * We support direct I/O only if lo_offset is aligned with the * logical I/O size of backing device, and the logical block - * size of loop is bigger than the backing device's. + * size of loop is bigger than the backing device's and the loop + * needn't transform transfer. * * TODO: the above condition may be loosed in the future, and * direct I/O may be switched runtime at that time because most @@ -186,7 +239,8 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) if (dio) { if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && !(lo->lo_offset & dio_align) && - mapping->a_ops->direct_IO) + mapping->a_ops->direct_IO && + !lo->transfer) use_dio = true; else use_dio = false; @@ -233,6 +287,24 @@ static void loop_set_size(struct loop_device *lo, loff_t size) kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); } +static inline int +lo_do_transfer(struct loop_device *lo, int cmd, + struct page *rpage, unsigned roffs, + struct page *lpage, unsigned loffs, + int size, sector_t rblock) +{ + int ret; + + ret = lo->transfer(lo, cmd, rpage, roffs, lpage, loffs, size, rblock); + if (likely(!ret)) + return 0; + + printk_ratelimited(KERN_ERR + "loop: Transfer error at byte offset %llu, length %i.\n", + (unsigned long long)rblock << 9, size); + return ret; +} + static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos) { struct iov_iter i; @@ -272,6 +344,41 @@ static int lo_write_simple(struct loop_device *lo, struct request *rq, return ret; } +/* + * This is the slow, transforming version that needs to double buffer the + * data as it cannot do the transformations in place without having direct + * access to the destination pages of the backing file. + */ +static int lo_write_transfer(struct loop_device *lo, struct request *rq, + loff_t pos) +{ + struct bio_vec bvec, b; + struct req_iterator iter; + struct page *page; + int ret = 0; + + page = alloc_page(GFP_NOIO); + if (unlikely(!page)) + return -ENOMEM; + + rq_for_each_segment(bvec, rq, iter) { + ret = lo_do_transfer(lo, WRITE, page, 0, bvec.bv_page, + bvec.bv_offset, bvec.bv_len, pos >> 9); + if (unlikely(ret)) + break; + + b.bv_page = page; + b.bv_offset = 0; + b.bv_len = bvec.bv_len; + ret = lo_write_bvec(lo->lo_backing_file, &b, &pos); + if (ret < 0) + break; + } + + __free_page(page); + return ret; +} + static int lo_read_simple(struct loop_device *lo, struct request *rq, loff_t pos) { @@ -301,12 +408,64 @@ static int lo_read_simple(struct loop_device *lo, struct request *rq, return 0; } +static int lo_read_transfer(struct loop_device *lo, struct request *rq, + loff_t pos) +{ + struct bio_vec bvec, b; + struct req_iterator iter; + struct iov_iter i; + struct page *page; + ssize_t len; + int ret = 0; + + page = alloc_page(GFP_NOIO); + if (unlikely(!page)) + return -ENOMEM; + + rq_for_each_segment(bvec, rq, iter) { + loff_t offset = pos; + + b.bv_page = page; + b.bv_offset = 0; + b.bv_len = bvec.bv_len; + + iov_iter_bvec(&i, READ, &b, 1, b.bv_len); + len = vfs_iter_read(lo->lo_backing_file, &i, &pos, 0); + if (len < 0) { + ret = len; + goto out_free_page; + } + + ret = lo_do_transfer(lo, READ, page, 0, bvec.bv_page, + bvec.bv_offset, len, offset >> 9); + if (ret) + goto out_free_page; + + flush_dcache_page(bvec.bv_page); + + if (len != bvec.bv_len) { + struct bio *bio; + + __rq_for_each_bio(bio, rq) + zero_fill_bio(bio); + break; + } + } + + ret = 0; +out_free_page: + __free_page(page); + return ret; +} + static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos, int mode) { /* * We use fallocate to manipulate the space mappings used by the image - * a.k.a. discard/zerorange. + * a.k.a. discard/zerorange. However we do not support this if + * encryption is enabled, because it may give an attacker useful + * information. */ struct file *file = lo->lo_backing_file; struct request_queue *q = lo->lo_queue; @@ -383,7 +542,7 @@ static void lo_rw_aio_do_completion(struct loop_cmd *cmd) blk_mq_complete_request(rq); } -static void lo_rw_aio_complete(struct kiocb *iocb, long ret) +static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2) { struct loop_cmd *cmd = container_of(iocb, struct loop_cmd, iocb); @@ -456,7 +615,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, lo_rw_aio_do_completion(cmd); if (ret != -EIOCBQUEUED) - lo_rw_aio_complete(&cmd->iocb, ret); + cmd->iocb.ki_complete(&cmd->iocb, ret, 0); return 0; } @@ -489,12 +648,16 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq) case REQ_OP_DISCARD: return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); case REQ_OP_WRITE: - if (cmd->use_aio) + if (lo->transfer) + return lo_write_transfer(lo, rq, pos); + else if (cmd->use_aio) return lo_rw_aio(lo, cmd, pos, WRITE); else return lo_write_simple(lo, rq, pos); case REQ_OP_READ: - if (cmd->use_aio) + if (lo->transfer) + return lo_read_transfer(lo, rq, pos); + else if (cmd->use_aio) return lo_rw_aio(lo, cmd, pos, READ); else return lo_read_simple(lo, rq, pos); @@ -759,7 +922,7 @@ static void loop_config_discard(struct loop_device *lo) * not blkdev_issue_discard(). This maintains consistent behavior with * file-backed loop devices: discarded regions read back as zero. */ - if (S_ISBLK(inode->i_mode)) { + if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) { struct request_queue *backingq = bdev_get_queue(I_BDEV(inode)); max_discard_sectors = backingq->limits.max_write_zeroes_sectors; @@ -768,9 +931,11 @@ static void loop_config_discard(struct loop_device *lo) /* * We use punch hole to reclaim the free space used by the - * image a.k.a. discard. + * image a.k.a. discard. However we do not support discard if + * encryption is enabled, because it may give an attacker + * useful information. */ - } else if (!file->f_op->fallocate) { + } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) { max_discard_sectors = 0; granularity = 0; @@ -826,7 +991,7 @@ static inline int queue_on_root_worker(struct cgroup_subsys_state *css) static void loop_queue_work(struct loop_device *lo, struct loop_cmd *cmd) { - struct rb_node **node, *parent = NULL; + struct rb_node **node = &(lo->worker_tree.rb_node), *parent = NULL; struct loop_worker *cur_worker, *worker = NULL; struct work_struct *work; struct list_head *cmd_list; @@ -912,6 +1077,43 @@ static void loop_update_rotational(struct loop_device *lo) blk_queue_flag_clear(QUEUE_FLAG_NONROT, q); } +static int +loop_release_xfer(struct loop_device *lo) +{ + int err = 0; + struct loop_func_table *xfer = lo->lo_encryption; + + if (xfer) { + if (xfer->release) + err = xfer->release(lo); + lo->transfer = NULL; + lo->lo_encryption = NULL; + module_put(xfer->owner); + } + return err; +} + +static int +loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, + const struct loop_info64 *i) +{ + int err = 0; + + if (xfer) { + struct module *owner = xfer->owner; + + if (!try_module_get(owner)) + return -EINVAL; + if (xfer->init) + err = xfer->init(lo, i); + if (err) + module_put(owner); + else + lo->lo_encryption = xfer; + } + return err; +} + /** * loop_set_status_from_info - configure device from loop_info * @lo: struct loop_device to configure @@ -924,27 +1126,55 @@ static int loop_set_status_from_info(struct loop_device *lo, const struct loop_info64 *info) { + int err; + struct loop_func_table *xfer; + kuid_t uid = current_uid(); + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) return -EINVAL; - switch (info->lo_encrypt_type) { - case LO_CRYPT_NONE: - break; - case LO_CRYPT_XOR: - pr_warn("support for the xor transformation has been removed.\n"); - return -EINVAL; - case LO_CRYPT_CRYPTOAPI: - pr_warn("support for cryptoloop has been removed. Use dm-crypt instead.\n"); - return -EINVAL; - default: - return -EINVAL; - } + err = loop_release_xfer(lo); + if (err) + return err; + + if (info->lo_encrypt_type) { + unsigned int type = info->lo_encrypt_type; + + if (type >= MAX_LO_CRYPT) + return -EINVAL; + xfer = xfer_funcs[type]; + if (xfer == NULL) + return -EINVAL; + } else + xfer = NULL; + + err = loop_init_xfer(lo, xfer, info); + if (err) + return err; lo->lo_offset = info->lo_offset; lo->lo_sizelimit = info->lo_sizelimit; memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); + memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); lo->lo_file_name[LO_NAME_SIZE-1] = 0; + lo->lo_crypt_name[LO_NAME_SIZE-1] = 0; + + if (!xfer) + xfer = &none_funcs; + lo->transfer = xfer->transfer; + lo->ioctl = xfer->ioctl; + lo->lo_flags = info->lo_flags; + + lo->lo_encrypt_key_size = info->lo_encrypt_key_size; + lo->lo_init[0] = info->lo_init[0]; + lo->lo_init[1] = info->lo_init[1]; + if (info->lo_encrypt_key_size) { + memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, + info->lo_encrypt_key_size); + lo->lo_key_owner = uid; + } + return 0; } @@ -1067,7 +1297,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, lo->lo_flags |= LO_FLAGS_PARTSCAN; partscan = lo->lo_flags & LO_FLAGS_PARTSCAN; if (partscan) - lo->lo_disk->flags &= ~GENHD_FL_NO_PART; + lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; loop_global_unlock(lo, is_loop); if (partscan) @@ -1088,10 +1318,14 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, return error; } -static void __loop_clr_fd(struct loop_device *lo, bool release) +static int __loop_clr_fd(struct loop_device *lo, bool release) { - struct file *filp; + struct file *filp = NULL; gfp_t gfp = lo->old_gfp_mask; + struct block_device *bdev = lo->lo_device; + int err = 0; + bool partscan = false; + int lo_number; struct loop_worker *pos, *worker; /* @@ -1106,14 +1340,17 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) * became visible. */ - /* - * Since this function is called upon "ioctl(LOOP_CLR_FD)" xor "close() - * after ioctl(LOOP_CLR_FD)", it is a sign of something going wrong if - * lo->lo_state has changed while waiting for lo->lo_mutex. - */ mutex_lock(&lo->lo_mutex); - BUG_ON(lo->lo_state != Lo_rundown); - mutex_unlock(&lo->lo_mutex); + if (WARN_ON_ONCE(lo->lo_state != Lo_rundown)) { + err = -ENXIO; + goto out_unlock; + } + + filp = lo->lo_backing_file; + if (filp == NULL) { + err = -EINVAL; + goto out_unlock; + } if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags)) blk_queue_write_cache(lo->lo_queue, false, false); @@ -1134,31 +1371,44 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) del_timer_sync(&lo->timer); spin_lock_irq(&lo->lo_lock); - filp = lo->lo_backing_file; lo->lo_backing_file = NULL; spin_unlock_irq(&lo->lo_lock); + loop_release_xfer(lo); + lo->transfer = NULL; + lo->ioctl = NULL; lo->lo_device = NULL; + lo->lo_encryption = NULL; lo->lo_offset = 0; lo->lo_sizelimit = 0; + lo->lo_encrypt_key_size = 0; + memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); + memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); blk_queue_logical_block_size(lo->lo_queue, 512); blk_queue_physical_block_size(lo->lo_queue, 512); blk_queue_io_min(lo->lo_queue, 512); - invalidate_disk(lo->lo_disk); + if (bdev) { + invalidate_bdev(bdev); + bdev->bd_inode->i_mapping->wb_err = 0; + } + set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); - /* let user-space know about this change */ - kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE); + if (bdev) { + /* let user-space know about this change */ + kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); + } mapping_set_gfp_mask(filp->f_mapping, gfp); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); blk_mq_unfreeze_queue(lo->lo_queue); + partscan = lo->lo_flags & LO_FLAGS_PARTSCAN && bdev; + lo_number = lo->lo_number; disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE); - - if (lo->lo_flags & LO_FLAGS_PARTSCAN) { - int err; - +out_unlock: + mutex_unlock(&lo->lo_mutex); + if (partscan) { /* * open_mutex has been held already in release path, so don't * acquire it if this function is called in such case. @@ -1174,20 +1424,24 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) mutex_unlock(&lo->lo_disk->open_mutex); if (err) pr_warn("%s: partition scan of loop%d failed (rc=%d)\n", - __func__, lo->lo_number, err); + __func__, lo_number, err); /* Device is gone, no point in returning error */ + err = 0; } /* * lo->lo_state is set to Lo_unbound here after above partscan has - * finished. There cannot be anybody else entering __loop_clr_fd() as - * Lo_rundown state protects us from all the other places trying to - * change the 'lo' device. + * finished. + * + * There cannot be anybody else entering __loop_clr_fd() as + * lo->lo_backing_file is already cleared and Lo_rundown state + * protects us from all the other places trying to change the 'lo' + * device. */ + mutex_lock(&lo->lo_mutex); lo->lo_flags = 0; if (!part_shift) - lo->lo_disk->flags |= GENHD_FL_NO_PART; - mutex_lock(&lo->lo_mutex); + lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; lo->lo_state = Lo_unbound; mutex_unlock(&lo->lo_mutex); @@ -1196,7 +1450,9 @@ static void __loop_clr_fd(struct loop_device *lo, bool release) * lo_mutex triggers a circular lock dependency possibility warning as * fput can take open_mutex which is usually taken before lo_mutex. */ - fput(filp); + if (filp) + fput(filp); + return err; } static int loop_clr_fd(struct loop_device *lo) @@ -1228,14 +1484,14 @@ static int loop_clr_fd(struct loop_device *lo) lo->lo_state = Lo_rundown; mutex_unlock(&lo->lo_mutex); - __loop_clr_fd(lo, false); - return 0; + return __loop_clr_fd(lo, false); } static int loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { int err; + kuid_t uid = current_uid(); int prev_lo_flags; bool partscan = false; bool size_changed = false; @@ -1243,6 +1499,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) err = mutex_lock_killable(&lo->lo_mutex); if (err) return err; + if (lo->lo_encrypt_key_size && + !uid_eq(lo->lo_key_owner, uid) && + !capable(CAP_SYS_ADMIN)) { + err = -EPERM; + goto out_unlock; + } if (lo->lo_state != Lo_bound) { err = -ENXIO; goto out_unlock; @@ -1296,7 +1558,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) && !(prev_lo_flags & LO_FLAGS_PARTSCAN)) { - lo->lo_disk->flags &= ~GENHD_FL_NO_PART; + lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; partscan = true; } out_unlock: @@ -1328,6 +1590,14 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) info->lo_sizelimit = lo->lo_sizelimit; info->lo_flags = lo->lo_flags; memcpy(info->lo_file_name, lo->lo_file_name, LO_NAME_SIZE); + memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE); + info->lo_encrypt_type = + lo->lo_encryption ? lo->lo_encryption->number : 0; + if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { + info->lo_encrypt_key_size = lo->lo_encrypt_key_size; + memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, + lo->lo_encrypt_key_size); + } /* Drop lo_mutex while we call into the filesystem. */ path = lo->lo_backing_file->f_path; @@ -1353,8 +1623,16 @@ loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64) info64->lo_rdevice = info->lo_rdevice; info64->lo_offset = info->lo_offset; info64->lo_sizelimit = 0; + info64->lo_encrypt_type = info->lo_encrypt_type; + info64->lo_encrypt_key_size = info->lo_encrypt_key_size; info64->lo_flags = info->lo_flags; - memcpy(info64->lo_file_name, info->lo_name, LO_NAME_SIZE); + info64->lo_init[0] = info->lo_init[0]; + info64->lo_init[1] = info->lo_init[1]; + if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI) + memcpy(info64->lo_crypt_name, info->lo_name, LO_NAME_SIZE); + else + memcpy(info64->lo_file_name, info->lo_name, LO_NAME_SIZE); + memcpy(info64->lo_encrypt_key, info->lo_encrypt_key, LO_KEY_SIZE); } static int @@ -1366,8 +1644,16 @@ loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info) info->lo_inode = info64->lo_inode; info->lo_rdevice = info64->lo_rdevice; info->lo_offset = info64->lo_offset; + info->lo_encrypt_type = info64->lo_encrypt_type; + info->lo_encrypt_key_size = info64->lo_encrypt_key_size; info->lo_flags = info64->lo_flags; - memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE); + info->lo_init[0] = info64->lo_init[0]; + info->lo_init[1] = info64->lo_init[1]; + if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI) + memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE); + else + memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE); + memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE); /* error in case values were truncated */ if (info->lo_device != info64->lo_device || @@ -1516,7 +1802,7 @@ static int lo_simple_ioctl(struct loop_device *lo, unsigned int cmd, err = loop_set_block_size(lo, arg); break; default: - err = -EINVAL; + err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL; } mutex_unlock(&lo->lo_mutex); return err; @@ -1592,6 +1878,7 @@ struct compat_loop_info { compat_ulong_t lo_inode; /* ioctl r/o */ compat_dev_t lo_rdevice; /* ioctl r/o */ compat_int_t lo_offset; + compat_int_t lo_encrypt_type; compat_int_t lo_encrypt_key_size; /* ioctl w/o */ compat_int_t lo_flags; /* ioctl r/o */ char lo_name[LO_NAME_SIZE]; @@ -1620,8 +1907,16 @@ loop_info64_from_compat(const struct compat_loop_info __user *arg, info64->lo_rdevice = info.lo_rdevice; info64->lo_offset = info.lo_offset; info64->lo_sizelimit = 0; + info64->lo_encrypt_type = info.lo_encrypt_type; + info64->lo_encrypt_key_size = info.lo_encrypt_key_size; info64->lo_flags = info.lo_flags; - memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE); + info64->lo_init[0] = info.lo_init[0]; + info64->lo_init[1] = info.lo_init[1]; + if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) + memcpy(info64->lo_crypt_name, info.lo_name, LO_NAME_SIZE); + else + memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE); + memcpy(info64->lo_encrypt_key, info.lo_encrypt_key, LO_KEY_SIZE); return 0; } @@ -1641,14 +1936,24 @@ loop_info64_to_compat(const struct loop_info64 *info64, info.lo_inode = info64->lo_inode; info.lo_rdevice = info64->lo_rdevice; info.lo_offset = info64->lo_offset; + info.lo_encrypt_type = info64->lo_encrypt_type; + info.lo_encrypt_key_size = info64->lo_encrypt_key_size; info.lo_flags = info64->lo_flags; - memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE); + info.lo_init[0] = info64->lo_init[0]; + info.lo_init[1] = info64->lo_init[1]; + if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) + memcpy(info.lo_name, info64->lo_crypt_name, LO_NAME_SIZE); + else + memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE); + memcpy(info.lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE); /* error in case values were truncated */ if (info.lo_device != info64->lo_device || info.lo_rdevice != info64->lo_rdevice || info.lo_inode != info64->lo_inode || - info.lo_offset != info64->lo_offset) + info.lo_offset != info64->lo_offset || + info.lo_init[0] != info64->lo_init[0] || + info.lo_init[1] != info64->lo_init[1]) return -EOVERFLOW; if (copy_to_user(arg, &info, sizeof(info))) @@ -1789,6 +2094,43 @@ MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); +int loop_register_transfer(struct loop_func_table *funcs) +{ + unsigned int n = funcs->number; + + if (n >= MAX_LO_CRYPT || xfer_funcs[n]) + return -EINVAL; + xfer_funcs[n] = funcs; + return 0; +} + +int loop_unregister_transfer(int number) +{ + unsigned int n = number; + struct loop_func_table *xfer; + + if (n == 0 || n >= MAX_LO_CRYPT || (xfer = xfer_funcs[n]) == NULL) + return -EINVAL; + /* + * This function is called from only cleanup_cryptoloop(). + * Given that each loop device that has a transfer enabled holds a + * reference to the module implementing it we should never get here + * with a transfer that is set (unless forced module unloading is + * requested). Thus, check module's refcount and warn if this is + * not a clean unloading. + */ +#ifdef CONFIG_MODULE_UNLOAD + if (xfer->owner && module_refcount(xfer->owner) != -1) + pr_err("Danger! Unregistering an in use transfer function.\n"); +#endif + + xfer_funcs[n] = NULL; + return 0; +} + +EXPORT_SYMBOL(loop_register_transfer); +EXPORT_SYMBOL(loop_unregister_transfer); + static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1978,6 +2320,7 @@ static int loop_add(int i) goto out_free_dev; i = err; + err = -ENOMEM; lo->tag_set.ops = &loop_mq_ops; lo->tag_set.nr_hw_queues = 1; lo->tag_set.queue_depth = 128; @@ -2027,7 +2370,8 @@ static int loop_add(int i) * userspace tools. Parameters like this in general should be avoided. */ if (!part_shift) - disk->flags |= GENHD_FL_NO_PART; + disk->flags |= GENHD_FL_NO_PART_SCAN; + disk->flags |= GENHD_FL_EXT_DEVT; atomic_set(&lo->lo_refcnt, 0); mutex_init(&lo->lo_mutex); lo->lo_number = i; @@ -2043,19 +2387,13 @@ static int loop_add(int i) disk->event_flags = DISK_EVENT_FLAG_UEVENT; sprintf(disk->disk_name, "loop%d", i); /* Make this loop device reachable from pathname. */ - err = add_disk(disk); - if (err) - goto out_cleanup_disk; - + add_disk(disk); /* Show this loop device. */ mutex_lock(&loop_ctl_mutex); lo->idr_visible = true; mutex_unlock(&loop_ctl_mutex); - return i; -out_cleanup_disk: - blk_cleanup_disk(disk); out_cleanup_tags: blk_mq_free_tag_set(&lo->tag_set); out_free_idr: diff --git a/drivers/block/loop.h b/drivers/block/loop.h index 082d4b6bfc..04c88dd6ea 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -32,10 +32,23 @@ struct loop_device { loff_t lo_offset; loff_t lo_sizelimit; int lo_flags; + int (*transfer)(struct loop_device *, int cmd, + struct page *raw_page, unsigned raw_off, + struct page *loop_page, unsigned loop_off, + int size, sector_t real_block); char lo_file_name[LO_NAME_SIZE]; + char lo_crypt_name[LO_NAME_SIZE]; + char lo_encrypt_key[LO_KEY_SIZE]; + int lo_encrypt_key_size; + struct loop_func_table *lo_encryption; + __u32 lo_init[2]; + kuid_t lo_key_owner; /* Who set the key */ + int (*ioctl)(struct loop_device *, int cmd, + unsigned long arg); struct file * lo_backing_file; struct block_device *lo_device; + void *key_data; gfp_t old_gfp_mask; @@ -69,4 +82,21 @@ struct loop_cmd { struct cgroup_subsys_state *memcg_css; }; +/* Support for loadable transfer modules */ +struct loop_func_table { + int number; /* filter type */ + int (*transfer)(struct loop_device *lo, int cmd, + struct page *raw_page, unsigned raw_off, + struct page *loop_page, unsigned loop_off, + int size, sector_t real_block); + int (*init)(struct loop_device *, const struct loop_info64 *); + /* release is called from loop_unregister_transfer or clr_fd */ + int (*release)(struct loop_device *); + int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); + struct module *owner; +}; + +int loop_register_transfer(struct loop_func_table *funcs); +int loop_unregister_transfer(int number); + #endif diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 2b588b62cb..ba61e72741 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -136,15 +136,16 @@ struct mtip_compat_ide_task_request_s { * return value * true if device removed, else false */ -static bool mtip_check_surprise_removal(struct driver_data *dd) +static bool mtip_check_surprise_removal(struct pci_dev *pdev) { u16 vendor_id = 0; + struct driver_data *dd = pci_get_drvdata(pdev); if (dd->sr) return true; /* Read the vendorID from the configuration space */ - pci_read_config_word(dd->pdev, 0x00, &vendor_id); + pci_read_config_word(pdev, 0x00, &vendor_id); if (vendor_id == 0xFFFF) { dd->sr = true; if (dd->queue) @@ -446,7 +447,7 @@ static int mtip_device_reset(struct driver_data *dd) { int rv = 0; - if (mtip_check_surprise_removal(dd)) + if (mtip_check_surprise_removal(dd->pdev)) return 0; if (mtip_hba_reset(dd) < 0) @@ -726,7 +727,7 @@ static inline void mtip_process_errors(struct driver_data *dd, u32 port_stat) dev_warn(&dd->pdev->dev, "Port stat errors %x unhandled\n", (port_stat & ~PORT_IRQ_HANDLED)); - if (mtip_check_surprise_removal(dd)) + if (mtip_check_surprise_removal(dd->pdev)) return; } if (likely(port_stat & (PORT_IRQ_TF_ERR | PORT_IRQ_IF_ERR))) { @@ -751,7 +752,7 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) /* Acknowledge the interrupt status on the port.*/ port_stat = readl(port->mmio + PORT_IRQ_STAT); if (unlikely(port_stat == 0xFFFFFFFF)) { - mtip_check_surprise_removal(dd); + mtip_check_surprise_removal(dd->pdev); return IRQ_HANDLED; } writel(port_stat, port->mmio + PORT_IRQ_STAT); @@ -795,7 +796,7 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) } if (unlikely(port_stat & PORT_IRQ_ERR)) { - if (unlikely(mtip_check_surprise_removal(dd))) { + if (unlikely(mtip_check_surprise_removal(dd->pdev))) { /* don't proceed further */ return IRQ_HANDLED; } @@ -914,7 +915,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) msleep(100); - if (mtip_check_surprise_removal(port->dd)) + if (mtip_check_surprise_removal(port->dd->pdev)) goto err_fault; active = mtip_commands_active(port); @@ -979,7 +980,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, return -EFAULT; } - if (mtip_check_surprise_removal(dd)) + if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; rq = blk_mq_alloc_request(dd->queue, REQ_OP_DRV_IN, BLK_MQ_REQ_RESERVED); @@ -1014,14 +1015,14 @@ static int mtip_exec_internal_command(struct mtip_port *port, rq->timeout = timeout; /* insert request and run queue */ - blk_execute_rq(rq, true); + blk_execute_rq(NULL, rq, true); if (int_cmd->status) { dev_err(&dd->pdev->dev, "Internal command [%02X] failed %d\n", fis->command, int_cmd->status); rv = -EIO; - if (mtip_check_surprise_removal(dd) || + if (mtip_check_surprise_removal(dd->pdev) || test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { dev_err(&dd->pdev->dev, @@ -2512,7 +2513,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) return -EFAULT; - if (mtip_check_surprise_removal(dd)) + if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; if (mtip_get_identify(dd->port, NULL) < 0) @@ -2890,7 +2891,7 @@ static int mtip_hw_init(struct driver_data *dd) time_before(jiffies, timeout)) { mdelay(100); } - if (unlikely(mtip_check_surprise_removal(dd))) { + if (unlikely(mtip_check_surprise_removal(dd->pdev))) { timetaken = jiffies - timetaken; dev_warn(&dd->pdev->dev, "Surprise removal detected at %u ms\n", @@ -3632,9 +3633,7 @@ static int mtip_block_initialize(struct driver_data *dd) set_capacity(dd->disk, capacity); /* Enable the block device and add it to /dev */ - rv = device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups); - if (rv) - goto read_capacity_error; + device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups); if (dd->mtip_svc_handler) { set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); @@ -4062,6 +4061,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, msi_initialize_err: if (dd->isr_workq) { + flush_workqueue(dd->isr_workq); destroy_workqueue(dd->isr_workq); drop_cpu(dd->work[0].cpu_binding); drop_cpu(dd->work[1].cpu_binding); @@ -4097,7 +4097,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) list_add(&dd->remove_list, &removing_list); spin_unlock_irqrestore(&dev_lock, flags); - mtip_check_surprise_removal(dd); + mtip_check_surprise_removal(pdev); synchronize_irq(dd->pdev->irq); /* Spin until workers are done */ @@ -4119,6 +4119,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) mtip_block_remove(dd); if (dd->isr_workq) { + flush_workqueue(dd->isr_workq); destroy_workqueue(dd->isr_workq); drop_cpu(dd->work[0].cpu_binding); drop_cpu(dd->work[1].cpu_binding); @@ -4144,17 +4145,36 @@ static void mtip_pci_remove(struct pci_dev *pdev) * 0 Success * <0 Error */ -static int __maybe_unused mtip_pci_suspend(struct device *dev) +static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) { int rv = 0; - struct driver_data *dd = dev_get_drvdata(dev); + struct driver_data *dd = pci_get_drvdata(pdev); + + if (!dd) { + dev_err(&pdev->dev, + "Driver private datastructure is NULL\n"); + return -EFAULT; + } set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); /* Disable ports & interrupts then send standby immediate */ rv = mtip_block_suspend(dd); - if (rv < 0) - dev_err(dev, "Failed to suspend controller\n"); + if (rv < 0) { + dev_err(&pdev->dev, + "Failed to suspend controller\n"); + return rv; + } + + /* + * Save the pci config space to pdev structure & + * disable the device + */ + pci_save_state(pdev); + pci_disable_device(pdev); + + /* Move to Low power state*/ + pci_set_power_state(pdev, PCI_D3hot); return rv; } @@ -4166,10 +4186,32 @@ static int __maybe_unused mtip_pci_suspend(struct device *dev) * 0 Success * <0 Error */ -static int __maybe_unused mtip_pci_resume(struct device *dev) +static int mtip_pci_resume(struct pci_dev *pdev) { int rv = 0; - struct driver_data *dd = dev_get_drvdata(dev); + struct driver_data *dd; + + dd = pci_get_drvdata(pdev); + if (!dd) { + dev_err(&pdev->dev, + "Driver private datastructure is NULL\n"); + return -EFAULT; + } + + /* Move the device to active State */ + pci_set_power_state(pdev, PCI_D0); + + /* Restore PCI configuration space */ + pci_restore_state(pdev); + + /* Enable the PCI device*/ + rv = pcim_enable_device(pdev); + if (rv < 0) { + dev_err(&pdev->dev, + "Failed to enable card during resume\n"); + goto err; + } + pci_set_master(pdev); /* * Calls hbaReset, initPort, & startPort function @@ -4177,8 +4219,9 @@ static int __maybe_unused mtip_pci_resume(struct device *dev) */ rv = mtip_block_resume(dd); if (rv < 0) - dev_err(dev, "Unable to resume\n"); + dev_err(&pdev->dev, "Unable to resume\n"); +err: clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); return rv; @@ -4209,15 +4252,14 @@ static const struct pci_device_id mtip_pci_tbl[] = { { 0 } }; -static SIMPLE_DEV_PM_OPS(mtip_pci_pm_ops, mtip_pci_suspend, mtip_pci_resume); - /* Structure that describes the PCI driver functions. */ static struct pci_driver mtip_pci_driver = { .name = MTIP_DRV_NAME, .id_table = mtip_pci_tbl, .probe = mtip_pci_probe, .remove = mtip_pci_remove, - .driver.pm = &mtip_pci_pm_ops, + .suspend = mtip_pci_suspend, + .resume = mtip_pci_resume, .shutdown = mtip_pci_shutdown, }; diff --git a/drivers/block/n64cart.c b/drivers/block/n64cart.c index 4db9a8c244..26798da661 100644 --- a/drivers/block/n64cart.c +++ b/drivers/block/n64cart.c @@ -84,7 +84,7 @@ static bool n64cart_do_bvec(struct device *dev, struct bio_vec *bv, u32 pos) return true; } -static void n64cart_submit_bio(struct bio *bio) +static blk_qc_t n64cart_submit_bio(struct bio *bio) { struct bio_vec bvec; struct bvec_iter iter; @@ -92,14 +92,16 @@ static void n64cart_submit_bio(struct bio *bio) u32 pos = bio->bi_iter.bi_sector << SECTOR_SHIFT; bio_for_each_segment(bvec, bio, iter) { - if (!n64cart_do_bvec(dev, &bvec, pos)) { - bio_io_error(bio); - return; - } + if (!n64cart_do_bvec(dev, &bvec, pos)) + goto io_error; pos += bvec.bv_len; } bio_endio(bio); + return BLK_QC_T_NONE; +io_error: + bio_io_error(bio); + return BLK_QC_T_NONE; } static const struct block_device_operations n64cart_fops = { @@ -115,7 +117,6 @@ static const struct block_device_operations n64cart_fops = { static int __init n64cart_probe(struct platform_device *pdev) { struct gendisk *disk; - int err = -ENOMEM; if (!start || !size) { pr_err("start or size not specified\n"); @@ -133,10 +134,10 @@ static int __init n64cart_probe(struct platform_device *pdev) disk = blk_alloc_disk(NUMA_NO_NODE); if (!disk) - goto out; + return -ENOMEM; disk->first_minor = 0; - disk->flags = GENHD_FL_NO_PART; + disk->flags = GENHD_FL_NO_PART_SCAN; disk->fops = &n64cart_fops; disk->private_data = &pdev->dev; strcpy(disk->disk_name, "n64cart"); @@ -148,18 +149,11 @@ static int __init n64cart_probe(struct platform_device *pdev) blk_queue_physical_block_size(disk->queue, 4096); blk_queue_logical_block_size(disk->queue, 4096); - err = add_disk(disk); - if (err) - goto out_cleanup_disk; + add_disk(disk); pr_info("n64cart: %u kb disk\n", size / 1024); return 0; - -out_cleanup_disk: - blk_cleanup_disk(disk); -out: - return err; } static struct platform_driver n64cart_driver = { diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 5a1f98494d..577c7dba5d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -131,12 +131,6 @@ struct nbd_device { }; #define NBD_CMD_REQUEUED 1 -/* - * This flag will be set if nbd_queue_rq() succeed, and will be checked and - * cleared in completion. Both setting and clearing of the flag are protected - * by cmd->lock. - */ -#define NBD_CMD_INFLIGHT 2 struct nbd_cmd { struct nbd_device *nbd; @@ -260,7 +254,7 @@ static void nbd_dev_remove(struct nbd_device *nbd) mutex_lock(&nbd_index_mutex); idr_remove(&nbd_index_idr, nbd->index); mutex_unlock(&nbd_index_mutex); - destroy_workqueue(nbd->recv_workq); + kfree(nbd); } @@ -316,13 +310,20 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock, nsock->sent = 0; } +static void nbd_size_clear(struct nbd_device *nbd) +{ + if (nbd->config->bytesize) { + set_capacity(nbd->disk, 0); + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); + } +} + static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, loff_t blksize) { if (!blksize) blksize = 1u << NBD_DEF_BLKSIZE_BITS; - - if (blk_validate_block_size(blksize)) + if (blksize < 512 || blksize > PAGE_SIZE || !is_power_of_2(blksize)) return -EINVAL; nbd->config->bytesize = bytesize; @@ -404,11 +405,6 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, if (!mutex_trylock(&cmd->lock)) return BLK_EH_RESET_TIMER; - if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { - mutex_unlock(&cmd->lock); - return BLK_EH_DONE; - } - if (!refcount_inc_not_zero(&nbd->config_refs)) { cmd->status = BLK_STS_TIMEOUT; mutex_unlock(&cmd->lock); @@ -488,8 +484,7 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, } /* - * Send or receive packet. Return a positive value on success and - * negtive value on failue, and never return 0. + * Send or receive packet. */ static int sock_xmit(struct nbd_device *nbd, int index, int send, struct iov_iter *iter, int msg_flags, int *sent) @@ -615,7 +610,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) result = sock_xmit(nbd, index, 1, &from, (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); trace_nbd_header_sent(req, handle); - if (result < 0) { + if (result <= 0) { if (was_interrupted(result)) { /* If we havne't sent anything we can just return BUSY, * however if we have sent something we need to make @@ -659,7 +654,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) skip = 0; } result = sock_xmit(nbd, index, 1, &from, flags, &sent); - if (result < 0) { + if (result <= 0) { if (was_interrupted(result)) { /* We've already sent the header, we * have no choice but to set pending and @@ -693,45 +688,38 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) return 0; } -static int nbd_read_reply(struct nbd_device *nbd, int index, - struct nbd_reply *reply) -{ - struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; - struct iov_iter to; - int result; - - reply->magic = 0; - iov_iter_kvec(&to, READ, &iov, 1, sizeof(*reply)); - result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); - if (result < 0) { - if (!nbd_disconnected(nbd->config)) - dev_err(disk_to_dev(nbd->disk), - "Receive control failed (result %d)\n", result); - return result; - } - - if (ntohl(reply->magic) != NBD_REPLY_MAGIC) { - dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n", - (unsigned long)ntohl(reply->magic)); - return -EPROTO; - } - - return 0; -} - /* NULL returned = something went wrong, inform userspace */ -static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, - struct nbd_reply *reply) +static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) { + struct nbd_config *config = nbd->config; int result; + struct nbd_reply reply; struct nbd_cmd *cmd; struct request *req = NULL; u64 handle; u16 hwq; u32 tag; + struct kvec iov = {.iov_base = &reply, .iov_len = sizeof(reply)}; + struct iov_iter to; int ret = 0; - memcpy(&handle, reply->handle, sizeof(handle)); + reply.magic = 0; + iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); + if (result <= 0) { + if (!nbd_disconnected(config)) + dev_err(disk_to_dev(nbd->disk), + "Receive control failed (result %d)\n", result); + return ERR_PTR(result); + } + + if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { + dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n", + (unsigned long)ntohl(reply.magic)); + return ERR_PTR(-EPROTO); + } + + memcpy(&handle, reply.handle, sizeof(handle)); tag = nbd_handle_to_tag(handle); hwq = blk_mq_unique_tag_to_hwq(tag); if (hwq < nbd->tag_set.nr_hw_queues) @@ -746,18 +734,6 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, cmd = blk_mq_rq_to_pdu(req); mutex_lock(&cmd->lock); - if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { - dev_err(disk_to_dev(nbd->disk), "Suspicious reply %d (status %u flags %lu)", - tag, cmd->status, cmd->flags); - ret = -ENOENT; - goto out; - } - if (cmd->index != index) { - dev_err(disk_to_dev(nbd->disk), "Unexpected reply %d from different sock %d (expected %d)", - tag, index, cmd->index); - ret = -ENOENT; - goto out; - } if (cmd->cmd_cookie != nbd_handle_to_cookie(handle)) { dev_err(disk_to_dev(nbd->disk), "Double reply on req %p, cmd_cookie %u, handle cookie %u\n", req, cmd->cmd_cookie, nbd_handle_to_cookie(handle)); @@ -776,9 +752,9 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, ret = -ENOENT; goto out; } - if (ntohl(reply->error)) { + if (ntohl(reply.error)) { dev_err(disk_to_dev(nbd->disk), "Other side returned error (%d)\n", - ntohl(reply->error)); + ntohl(reply.error)); cmd->status = BLK_STS_IOERR; goto out; } @@ -787,12 +763,11 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, if (rq_data_dir(req) != WRITE) { struct req_iterator iter; struct bio_vec bvec; - struct iov_iter to; rq_for_each_segment(bvec, req, iter) { iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); - if (result < 0) { + if (result <= 0) { dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", result); /* @@ -801,7 +776,7 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, * and let the timeout stuff handle resubmitting * this request onto another connection. */ - if (nbd_disconnected(nbd->config)) { + if (nbd_disconnected(config)) { cmd->status = BLK_STS_IOERR; goto out; } @@ -825,46 +800,24 @@ static void recv_work(struct work_struct *work) work); struct nbd_device *nbd = args->nbd; struct nbd_config *config = nbd->config; - struct request_queue *q = nbd->disk->queue; - struct nbd_sock *nsock; struct nbd_cmd *cmd; struct request *rq; while (1) { - struct nbd_reply reply; - - if (nbd_read_reply(nbd, args->index, &reply)) - break; - - /* - * Grab .q_usage_counter so request pool won't go away, then no - * request use-after-free is possible during nbd_handle_reply(). - * If queue is frozen, there won't be any inflight requests, we - * needn't to handle the incoming garbage message. - */ - if (!percpu_ref_tryget(&q->q_usage_counter)) { - dev_err(disk_to_dev(nbd->disk), "%s: no io inflight\n", - __func__); - break; - } - - cmd = nbd_handle_reply(nbd, args->index, &reply); + cmd = nbd_read_stat(nbd, args->index); if (IS_ERR(cmd)) { - percpu_ref_put(&q->q_usage_counter); + struct nbd_sock *nsock = config->socks[args->index]; + + mutex_lock(&nsock->tx_lock); + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); break; } rq = blk_mq_rq_from_pdu(cmd); if (likely(!blk_should_fake_timeout(rq->q))) blk_mq_complete_request(rq); - percpu_ref_put(&q->q_usage_counter); } - - nsock = config->socks[args->index]; - mutex_lock(&nsock->tx_lock); - nbd_mark_nsock_dead(nbd, nsock, 1); - mutex_unlock(&nsock->tx_lock); - nbd_config_put(nbd); atomic_dec(&config->recv_threads); wake_up(&config->recv_wq); @@ -880,10 +833,6 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved) return true; mutex_lock(&cmd->lock); - if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { - mutex_unlock(&cmd->lock); - return true; - } cmd->status = BLK_STS_IOERR; mutex_unlock(&cmd->lock); @@ -965,6 +914,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) if (!refcount_inc_not_zero(&nbd->config_refs)) { dev_err_ratelimited(disk_to_dev(nbd->disk), "Socks array is empty\n"); + blk_mq_start_request(req); return -EINVAL; } config = nbd->config; @@ -973,6 +923,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) dev_err_ratelimited(disk_to_dev(nbd->disk), "Attempted send on invalid socket\n"); nbd_config_put(nbd); + blk_mq_start_request(req); return -EINVAL; } cmd->status = BLK_STS_OK; @@ -996,6 +947,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) */ sock_shutdown(nbd); nbd_config_put(nbd); + blk_mq_start_request(req); return -EIO; } goto again; @@ -1017,13 +969,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) * returns EAGAIN can be retried on a different socket. */ ret = nbd_send_cmd(nbd, cmd, index); - /* - * Access to this flag is protected by cmd->lock, thus it's safe to set - * the flag after nbd_send_cmd() succeed to send request to server. - */ - if (!ret) - __set_bit(NBD_CMD_INFLIGHT, &cmd->flags); - else if (ret == -EAGAIN) { + if (ret == -EAGAIN) { dev_err_ratelimited(disk_to_dev(nbd->disk), "Request send failed, requeueing\n"); nbd_mark_nsock_dead(nbd, nsock, 1); @@ -1260,7 +1206,7 @@ static void send_disconnects(struct nbd_device *nbd) iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); mutex_lock(&nsock->tx_lock); ret = sock_xmit(nbd, i, 1, &from, 0, NULL); - if (ret < 0) + if (ret <= 0) dev_err(disk_to_dev(nbd->disk), "Send disconnect failed %d\n", ret); mutex_unlock(&nsock->tx_lock); @@ -1291,9 +1237,7 @@ static void nbd_config_put(struct nbd_device *nbd) &nbd->config_lock)) { struct nbd_config *config = nbd->config; nbd_dev_dbg_close(nbd); - invalidate_disk(nbd->disk); - if (nbd->config->bytesize) - kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); + nbd_size_clear(nbd); if (test_and_clear_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags)) device_remove_file(disk_to_dev(nbd->disk), &pid_attr); @@ -1316,6 +1260,10 @@ static void nbd_config_put(struct nbd_device *nbd) kfree(nbd->config); nbd->config = NULL; + if (nbd->recv_workq) + destroy_workqueue(nbd->recv_workq); + nbd->recv_workq = NULL; + nbd->tag_set.timeout = 0; nbd->disk->queue->limits.discard_granularity = 0; nbd->disk->queue->limits.discard_alignment = 0; @@ -1344,6 +1292,14 @@ static int nbd_start_device(struct nbd_device *nbd) return -EINVAL; } + nbd->recv_workq = alloc_workqueue("knbd%d-recv", + WQ_MEM_RECLAIM | WQ_HIGHPRI | + WQ_UNBOUND, 0, nbd->index); + if (!nbd->recv_workq) { + dev_err(disk_to_dev(nbd->disk), "Could not allocate knbd recv work queue.\n"); + return -ENOMEM; + } + blk_mq_update_nr_hw_queues(&nbd->tag_set, config->num_connections); nbd->pid = task_pid_nr(current); @@ -1769,15 +1725,6 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) } nbd->disk = disk; - nbd->recv_workq = alloc_workqueue("nbd%d-recv", - WQ_MEM_RECLAIM | WQ_HIGHPRI | - WQ_UNBOUND, 0, nbd->index); - if (!nbd->recv_workq) { - dev_err(disk_to_dev(nbd->disk), "Could not allocate knbd recv work queue.\n"); - err = -ENOMEM; - goto out_err_disk; - } - /* * Tell the block layer that we are not a rotational device */ @@ -1808,16 +1755,14 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) disk->first_minor = index << part_shift; if (disk->first_minor < index || disk->first_minor > MINORMASK) { err = -EINVAL; - goto out_free_work; + goto out_free_idr; } disk->minors = 1 << part_shift; disk->fops = &nbd_fops; disk->private_data = nbd; sprintf(disk->disk_name, "nbd%d", index); - err = add_disk(disk); - if (err) - goto out_free_work; + add_disk(disk); /* * Now publish the device. @@ -1826,10 +1771,6 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) nbd_total_devices++; return nbd; -out_free_work: - destroy_workqueue(nbd->recv_workq); -out_err_disk: - blk_cleanup_disk(disk); out_free_idr: mutex_lock(&nbd_index_mutex); idr_remove(&nbd_index_idr, index); @@ -2083,10 +2024,13 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd) nbd_disconnect(nbd); sock_shutdown(nbd); /* - * Make sure recv thread has finished, we can safely call nbd_clear_que() + * Make sure recv thread has finished, so it does not drop the last + * config ref and try to destroy the workqueue from inside the work + * queue. And this also ensure that we can safely call nbd_clear_que() * to cancel the inflight I/Os. */ - flush_workqueue(nbd->recv_workq); + if (nbd->recv_workq) + flush_workqueue(nbd->recv_workq); nbd_clear_que(nbd); nbd->task_setup = NULL; mutex_unlock(&nbd->config_lock); diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 13004beb48..187d779c8c 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -92,10 +92,6 @@ static int g_submit_queues = 1; module_param_named(submit_queues, g_submit_queues, int, 0444); MODULE_PARM_DESC(submit_queues, "Number of submission queues"); -static int g_poll_queues = 1; -module_param_named(poll_queues, g_poll_queues, int, 0444); -MODULE_PARM_DESC(poll_queues, "Number of IOPOLL submission queues"); - static int g_home_node = NUMA_NO_NODE; module_param_named(home_node, g_home_node, int, 0444); MODULE_PARM_DESC(home_node, "Home node for the device"); @@ -328,69 +324,29 @@ nullb_device_##NAME##_store(struct config_item *item, const char *page, \ } \ CONFIGFS_ATTR(nullb_device_, NAME); -static int nullb_update_nr_hw_queues(struct nullb_device *dev, - unsigned int submit_queues, - unsigned int poll_queues) - +static int nullb_apply_submit_queues(struct nullb_device *dev, + unsigned int submit_queues) { + struct nullb *nullb = dev->nullb; struct blk_mq_tag_set *set; - int ret, nr_hw_queues; - if (!dev->nullb) + if (!nullb) return 0; - /* - * Make sure at least one submit queue exists. - */ - if (!submit_queues) - return -EINVAL; - /* * Make sure that null_init_hctx() does not access nullb->queues[] past * the end of that array. */ - if (submit_queues > nr_cpu_ids || poll_queues > g_poll_queues) + if (submit_queues > nr_cpu_ids) return -EINVAL; - - /* - * Keep previous and new queue numbers in nullb_device for reference in - * the call back function null_map_queues(). - */ - dev->prev_submit_queues = dev->submit_queues; - dev->prev_poll_queues = dev->poll_queues; - dev->submit_queues = submit_queues; - dev->poll_queues = poll_queues; - - set = dev->nullb->tag_set; - nr_hw_queues = submit_queues + poll_queues; - blk_mq_update_nr_hw_queues(set, nr_hw_queues); - ret = set->nr_hw_queues == nr_hw_queues ? 0 : -ENOMEM; - - if (ret) { - /* on error, revert the queue numbers */ - dev->submit_queues = dev->prev_submit_queues; - dev->poll_queues = dev->prev_poll_queues; - } - - return ret; -} - -static int nullb_apply_submit_queues(struct nullb_device *dev, - unsigned int submit_queues) -{ - return nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues); -} - -static int nullb_apply_poll_queues(struct nullb_device *dev, - unsigned int poll_queues) -{ - return nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues); + set = nullb->tag_set; + blk_mq_update_nr_hw_queues(set, submit_queues); + return set->nr_hw_queues == submit_queues ? 0 : -ENOMEM; } NULLB_DEVICE_ATTR(size, ulong, NULL); NULLB_DEVICE_ATTR(completion_nsec, ulong, NULL); NULLB_DEVICE_ATTR(submit_queues, uint, nullb_apply_submit_queues); -NULLB_DEVICE_ATTR(poll_queues, uint, nullb_apply_poll_queues); NULLB_DEVICE_ATTR(home_node, uint, NULL); NULLB_DEVICE_ATTR(queue_mode, uint, NULL); NULLB_DEVICE_ATTR(blocksize, uint, NULL); @@ -510,7 +466,6 @@ static struct configfs_attribute *nullb_device_attrs[] = { &nullb_device_attr_size, &nullb_device_attr_completion_nsec, &nullb_device_attr_submit_queues, - &nullb_device_attr_poll_queues, &nullb_device_attr_home_node, &nullb_device_attr_queue_mode, &nullb_device_attr_blocksize, @@ -638,9 +593,6 @@ static struct nullb_device *null_alloc_dev(void) dev->size = g_gb * 1024; dev->completion_nsec = g_completion_nsec; dev->submit_queues = g_submit_queues; - dev->prev_submit_queues = g_submit_queues; - dev->poll_queues = g_poll_queues; - dev->prev_poll_queues = g_poll_queues; dev->home_node = g_home_node; dev->queue_mode = g_queue_mode; dev->blocksize = g_bs; @@ -1470,7 +1422,7 @@ static struct nullb_queue *nullb_to_queue(struct nullb *nullb) return &nullb->queues[index]; } -static void null_submit_bio(struct bio *bio) +static blk_qc_t null_submit_bio(struct bio *bio) { sector_t sector = bio->bi_iter.bi_sector; sector_t nr_sectors = bio_sectors(bio); @@ -1482,6 +1434,7 @@ static void null_submit_bio(struct bio *bio) cmd->bio = bio; null_handle_cmd(cmd, sector, nr_sectors, bio_op(bio)); + return BLK_QC_T_NONE; } static bool should_timeout_request(struct request *rq) @@ -1502,102 +1455,12 @@ static bool should_requeue_request(struct request *rq) return false; } -static int null_map_queues(struct blk_mq_tag_set *set) -{ - struct nullb *nullb = set->driver_data; - int i, qoff; - unsigned int submit_queues = g_submit_queues; - unsigned int poll_queues = g_poll_queues; - - if (nullb) { - struct nullb_device *dev = nullb->dev; - - /* - * Refer nr_hw_queues of the tag set to check if the expected - * number of hardware queues are prepared. If block layer failed - * to prepare them, use previous numbers of submit queues and - * poll queues to map queues. - */ - if (set->nr_hw_queues == - dev->submit_queues + dev->poll_queues) { - submit_queues = dev->submit_queues; - poll_queues = dev->poll_queues; - } else if (set->nr_hw_queues == - dev->prev_submit_queues + dev->prev_poll_queues) { - submit_queues = dev->prev_submit_queues; - poll_queues = dev->prev_poll_queues; - } else { - pr_warn("tag set has unexpected nr_hw_queues: %d\n", - set->nr_hw_queues); - return -EINVAL; - } - } - - for (i = 0, qoff = 0; i < set->nr_maps; i++) { - struct blk_mq_queue_map *map = &set->map[i]; - - switch (i) { - case HCTX_TYPE_DEFAULT: - map->nr_queues = submit_queues; - break; - case HCTX_TYPE_READ: - map->nr_queues = 0; - continue; - case HCTX_TYPE_POLL: - map->nr_queues = poll_queues; - break; - } - map->queue_offset = qoff; - qoff += map->nr_queues; - blk_mq_map_queues(map); - } - - return 0; -} - -static int null_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) -{ - struct nullb_queue *nq = hctx->driver_data; - LIST_HEAD(list); - int nr = 0; - - spin_lock(&nq->poll_lock); - list_splice_init(&nq->poll_list, &list); - spin_unlock(&nq->poll_lock); - - while (!list_empty(&list)) { - struct nullb_cmd *cmd; - struct request *req; - - req = list_first_entry(&list, struct request, queuelist); - list_del_init(&req->queuelist); - cmd = blk_mq_rq_to_pdu(req); - cmd->error = null_process_cmd(cmd, req_op(req), blk_rq_pos(req), - blk_rq_sectors(req)); - if (!blk_mq_add_to_batch(req, iob, (__force int) cmd->error, - blk_mq_end_request_batch)) - end_cmd(cmd); - nr++; - } - - return nr; -} - static enum blk_eh_timer_return null_timeout_rq(struct request *rq, bool res) { - struct blk_mq_hw_ctx *hctx = rq->mq_hctx; struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); pr_info("rq %p timed out\n", rq); - if (hctx->type == HCTX_TYPE_POLL) { - struct nullb_queue *nq = hctx->driver_data; - - spin_lock(&nq->poll_lock); - list_del_init(&rq->queuelist); - spin_unlock(&nq->poll_lock); - } - /* * If the device is marked as blocking (i.e. memory backed or zoned * device), the submission path may be blocked waiting for resources @@ -1618,11 +1481,10 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, struct nullb_queue *nq = hctx->driver_data; sector_t nr_sectors = blk_rq_sectors(bd->rq); sector_t sector = blk_rq_pos(bd->rq); - const bool is_poll = hctx->type == HCTX_TYPE_POLL; might_sleep_if(hctx->flags & BLK_MQ_F_BLOCKING); - if (!is_poll && nq->dev->irqmode == NULL_IRQ_TIMER) { + if (nq->dev->irqmode == NULL_IRQ_TIMER) { hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); cmd->timer.function = null_cmd_timer_expired; } @@ -1646,13 +1508,6 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, return BLK_STS_OK; } } - - if (is_poll) { - spin_lock(&nq->poll_lock); - list_add_tail(&bd->rq->queuelist, &nq->poll_list); - spin_unlock(&nq->poll_lock); - return BLK_STS_OK; - } if (cmd->fake_timeout) return BLK_STS_OK; @@ -1688,8 +1543,6 @@ static void null_init_queue(struct nullb *nullb, struct nullb_queue *nq) init_waitqueue_head(&nq->wait); nq->queue_depth = nullb->queue_depth; nq->dev = nullb->dev; - INIT_LIST_HEAD(&nq->poll_list); - spin_lock_init(&nq->poll_lock); } static int null_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data, @@ -1715,8 +1568,6 @@ static const struct blk_mq_ops null_mq_ops = { .queue_rq = null_queue_rq, .complete = null_complete_rq, .timeout = null_timeout_rq, - .poll = null_poll, - .map_queues = null_map_queues, .init_hctx = null_init_hctx, .exit_hctx = null_exit_hctx, }; @@ -1813,17 +1664,13 @@ static int setup_commands(struct nullb_queue *nq) static int setup_queues(struct nullb *nullb) { - int nqueues = nr_cpu_ids; - - if (g_poll_queues) - nqueues += g_poll_queues; - - nullb->queues = kcalloc(nqueues, sizeof(struct nullb_queue), + nullb->queues = kcalloc(nr_cpu_ids, sizeof(struct nullb_queue), GFP_KERNEL); if (!nullb->queues) return -ENOMEM; nullb->queue_depth = nullb->dev->hw_queue_depth; + return 0; } @@ -1852,6 +1699,7 @@ static int null_gendisk_register(struct nullb *nullb) set_capacity(disk, size); + disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO; disk->major = null_major; disk->first_minor = nullb->index; disk->minors = 1; @@ -1874,14 +1722,9 @@ static int null_gendisk_register(struct nullb *nullb) static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) { - int poll_queues; - set->ops = &null_mq_ops; set->nr_hw_queues = nullb ? nullb->dev->submit_queues : g_submit_queues; - poll_queues = nullb ? nullb->dev->poll_queues : g_poll_queues; - if (poll_queues) - set->nr_hw_queues += poll_queues; set->queue_depth = nullb ? nullb->dev->hw_queue_depth : g_hw_queue_depth; set->numa_node = nullb ? nullb->dev->home_node : g_home_node; @@ -1891,11 +1734,7 @@ static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set) set->flags |= BLK_MQ_F_NO_SCHED; if (g_shared_tag_bitmap) set->flags |= BLK_MQ_F_TAG_HCTX_SHARED; - set->driver_data = nullb; - if (poll_queues) - set->nr_maps = 3; - else - set->nr_maps = 1; + set->driver_data = NULL; if ((nullb && nullb->dev->blocking) || g_blocking) set->flags |= BLK_MQ_F_BLOCKING; @@ -1915,11 +1754,6 @@ static int null_validate_conf(struct nullb_device *dev) dev->submit_queues = nr_cpu_ids; else if (dev->submit_queues == 0) dev->submit_queues = 1; - dev->prev_submit_queues = dev->submit_queues; - - if (dev->poll_queues > g_poll_queues) - dev->poll_queues = g_poll_queues; - dev->prev_poll_queues = dev->poll_queues; dev->queue_mode = min_t(unsigned int, dev->queue_mode, NULL_Q_MQ); dev->irqmode = min_t(unsigned int, dev->irqmode, NULL_IRQ_TIMER); diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h index 78eb56b0ca..64bef125d1 100644 --- a/drivers/block/null_blk/null_blk.h +++ b/drivers/block/null_blk/null_blk.h @@ -32,9 +32,6 @@ struct nullb_queue { struct nullb_device *dev; unsigned int requeue_selection; - struct list_head poll_list; - spinlock_t poll_lock; - struct nullb_cmd *cmds; }; @@ -86,9 +83,6 @@ struct nullb_device { unsigned int zone_max_open; /* max number of open zones */ unsigned int zone_max_active; /* max number of active zones */ unsigned int submit_queues; /* number of submission queues */ - unsigned int prev_submit_queues; /* number of submission queues before change */ - unsigned int poll_queues; /* number of IOPOLL submission queues */ - unsigned int prev_poll_queues; /* number of IOPOLL submission queues before change */ unsigned int home_node; /* home node for the device */ unsigned int queue_mode; /* block interface */ unsigned int blocksize; /* block size */ diff --git a/drivers/block/paride/bpck.c b/drivers/block/paride/bpck.c index d880a9465e..f5f63ca288 100644 --- a/drivers/block/paride/bpck.c +++ b/drivers/block/paride/bpck.c @@ -28,7 +28,6 @@ #undef r2 #undef w2 -#undef PC #define PC pi->private #define r2() (PC=(in_p(2) & 0xff)) diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index f462ad6793..f9cdd11f02 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -183,6 +183,8 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi, static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc); +static int pcd_detect(void); +static void pcd_probe_capabilities(void); static void do_pcd_read_drq(void); static blk_status_t pcd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd); @@ -300,6 +302,53 @@ static const struct blk_mq_ops pcd_mq_ops = { .queue_rq = pcd_queue_rq, }; +static void pcd_init_units(void) +{ + struct pcd_unit *cd; + int unit; + + pcd_drive_count = 0; + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + struct gendisk *disk; + + if (blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, + BLK_MQ_F_SHOULD_MERGE)) + continue; + + disk = blk_mq_alloc_disk(&cd->tag_set, cd); + if (IS_ERR(disk)) { + blk_mq_free_tag_set(&cd->tag_set); + continue; + } + + INIT_LIST_HEAD(&cd->rq_list); + blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); + cd->disk = disk; + cd->pi = &cd->pia; + cd->present = 0; + cd->last_sense = 0; + cd->changed = 1; + cd->drive = (*drives[unit])[D_SLV]; + if ((*drives[unit])[D_PRT]) + pcd_drive_count++; + + cd->name = &cd->info.name[0]; + snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); + cd->info.ops = &pcd_dops; + cd->info.handle = cd; + cd->info.speed = 0; + cd->info.capacity = 1; + cd->info.mask = 0; + disk->major = major; + disk->first_minor = unit; + disk->minors = 1; + strcpy(disk->disk_name, cd->name); /* umm... */ + disk->fops = &pcd_bdops; + disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + disk->events = DISK_EVENT_MEDIA_CHANGE; + } +} + static int pcd_open(struct cdrom_device_info *cdi, int purpose) { struct pcd_unit *cd = cdi->handle; @@ -581,11 +630,10 @@ static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr) return CDS_DISC_OK; } -static int pcd_identify(struct pcd_unit *cd) +static int pcd_identify(struct pcd_unit *cd, char *id) { - char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 }; - char id[18]; int k, s; + char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 }; pcd_bufblk = -1; @@ -613,47 +661,108 @@ static int pcd_identify(struct pcd_unit *cd) } /* - * returns 0, with id set if drive is detected, otherwise an error code. + * returns 0, with id set if drive is detected + * -1, if drive detection failed */ -static int pcd_probe(struct pcd_unit *cd, int ms) +static int pcd_probe(struct pcd_unit *cd, int ms, char *id) { if (ms == -1) { for (cd->drive = 0; cd->drive <= 1; cd->drive++) - if (!pcd_reset(cd) && !pcd_identify(cd)) + if (!pcd_reset(cd) && !pcd_identify(cd, id)) return 0; } else { cd->drive = ms; - if (!pcd_reset(cd) && !pcd_identify(cd)) + if (!pcd_reset(cd) && !pcd_identify(cd, id)) return 0; } - return -ENODEV; + return -1; } -static int pcd_probe_capabilities(struct pcd_unit *cd) +static void pcd_probe_capabilities(void) { - char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 }; + int unit, r; char buffer[32]; - int ret; + char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 }; + struct pcd_unit *cd; - ret = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); - if (ret) - return ret; + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + if (!cd->present) + continue; + r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); + if (r) + continue; + /* we should now have the cap page */ + if ((buffer[11] & 1) == 0) + cd->info.mask |= CDC_CD_R; + if ((buffer[11] & 2) == 0) + cd->info.mask |= CDC_CD_RW; + if ((buffer[12] & 1) == 0) + cd->info.mask |= CDC_PLAY_AUDIO; + if ((buffer[14] & 1) == 0) + cd->info.mask |= CDC_LOCK; + if ((buffer[14] & 8) == 0) + cd->info.mask |= CDC_OPEN_TRAY; + if ((buffer[14] >> 6) == 0) + cd->info.mask |= CDC_CLOSE_TRAY; + } +} - /* we should now have the cap page */ - if ((buffer[11] & 1) == 0) - cd->info.mask |= CDC_CD_R; - if ((buffer[11] & 2) == 0) - cd->info.mask |= CDC_CD_RW; - if ((buffer[12] & 1) == 0) - cd->info.mask |= CDC_PLAY_AUDIO; - if ((buffer[14] & 1) == 0) - cd->info.mask |= CDC_LOCK; - if ((buffer[14] & 8) == 0) - cd->info.mask |= CDC_OPEN_TRAY; - if ((buffer[14] >> 6) == 0) - cd->info.mask |= CDC_CLOSE_TRAY; +static int pcd_detect(void) +{ + char id[18]; + int k, unit; + struct pcd_unit *cd; - return 0; + printk("%s: %s version %s, major %d, nice %d\n", + name, name, PCD_VERSION, major, nice); + + par_drv = pi_register_driver(name); + if (!par_drv) { + pr_err("failed to register %s driver\n", name); + return -1; + } + + k = 0; + if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ + cd = pcd; + if (cd->disk && pi_init(cd->pi, 1, -1, -1, -1, -1, -1, + pcd_buffer, PI_PCD, verbose, cd->name)) { + if (!pcd_probe(cd, -1, id)) { + cd->present = 1; + k++; + } else + pi_release(cd->pi); + } + } else { + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + int *conf = *drives[unit]; + if (!conf[D_PRT]) + continue; + if (!cd->disk) + continue; + if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD], + conf[D_UNI], conf[D_PRO], conf[D_DLY], + pcd_buffer, PI_PCD, verbose, cd->name)) + continue; + if (!pcd_probe(cd, conf[D_SLV], id)) { + cd->present = 1; + k++; + } else + pi_release(cd->pi); + } + } + if (k) + return 0; + + printk("%s: No CD-ROM drive found\n", name); + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + if (!cd->disk) + continue; + blk_cleanup_disk(cd->disk); + blk_mq_free_tag_set(&cd->tag_set); + } + pi_unregister_driver(par_drv); + return -1; } /* I/O request processing */ @@ -690,7 +799,7 @@ static void pcd_request(void) if (!pcd_req && !set_next_request()) return; - cd = pcd_req->q->disk->private_data; + cd = pcd_req->rq_disk->private_data; if (cd != pcd_current) pcd_bufblk = -1; pcd_current = cd; @@ -890,131 +999,43 @@ static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) return 0; } -static int pcd_init_unit(struct pcd_unit *cd, bool autoprobe, int port, - int mode, int unit, int protocol, int delay, int ms) -{ - struct gendisk *disk; - int ret; - - ret = blk_mq_alloc_sq_tag_set(&cd->tag_set, &pcd_mq_ops, 1, - BLK_MQ_F_SHOULD_MERGE); - if (ret) - return ret; - - disk = blk_mq_alloc_disk(&cd->tag_set, cd); - if (IS_ERR(disk)) { - ret = PTR_ERR(disk); - goto out_free_tag_set; - } - - INIT_LIST_HEAD(&cd->rq_list); - blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); - cd->disk = disk; - cd->pi = &cd->pia; - cd->present = 0; - cd->last_sense = 0; - cd->changed = 1; - cd->drive = (*drives[cd - pcd])[D_SLV]; - - cd->name = &cd->info.name[0]; - snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); - cd->info.ops = &pcd_dops; - cd->info.handle = cd; - cd->info.speed = 0; - cd->info.capacity = 1; - cd->info.mask = 0; - disk->major = major; - disk->first_minor = unit; - disk->minors = 1; - strcpy(disk->disk_name, cd->name); /* umm... */ - disk->fops = &pcd_bdops; - disk->flags |= GENHD_FL_NO_PART; - disk->events = DISK_EVENT_MEDIA_CHANGE; - disk->event_flags = DISK_EVENT_FLAG_BLOCK_ON_EXCL_WRITE; - - if (!pi_init(cd->pi, autoprobe, port, mode, unit, protocol, delay, - pcd_buffer, PI_PCD, verbose, cd->name)) { - ret = -ENODEV; - goto out_free_disk; - } - ret = pcd_probe(cd, ms); - if (ret) - goto out_pi_release; - - cd->present = 1; - pcd_probe_capabilities(cd); - ret = register_cdrom(cd->disk, &cd->info); - if (ret) - goto out_pi_release; - ret = add_disk(cd->disk); - if (ret) - goto out_unreg_cdrom; - return 0; - -out_unreg_cdrom: - unregister_cdrom(&cd->info); -out_pi_release: - pi_release(cd->pi); -out_free_disk: - blk_cleanup_disk(cd->disk); -out_free_tag_set: - blk_mq_free_tag_set(&cd->tag_set); - return ret; -} - static int __init pcd_init(void) { - int found = 0, unit; + struct pcd_unit *cd; + int unit; if (disable) return -EINVAL; - if (register_blkdev(major, name)) - return -EBUSY; + pcd_init_units(); - pr_info("%s: %s version %s, major %d, nice %d\n", - name, name, PCD_VERSION, major, nice); + if (pcd_detect()) + return -ENODEV; - par_drv = pi_register_driver(name); - if (!par_drv) { - pr_err("failed to register %s driver\n", name); - goto out_unregister_blkdev; - } + /* get the atapi capabilities page */ + pcd_probe_capabilities(); - for (unit = 0; unit < PCD_UNITS; unit++) { - if ((*drives[unit])[D_PRT]) - pcd_drive_count++; - } - - if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ - if (!pcd_init_unit(pcd, 1, -1, -1, -1, -1, -1, -1)) - found++; - } else { - for (unit = 0; unit < PCD_UNITS; unit++) { - struct pcd_unit *cd = &pcd[unit]; - int *conf = *drives[unit]; - - if (!conf[D_PRT]) + if (register_blkdev(major, name)) { + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + if (!cd->disk) continue; - if (!pcd_init_unit(cd, 0, conf[D_PRT], conf[D_MOD], - conf[D_UNI], conf[D_PRO], conf[D_DLY], - conf[D_SLV])) - found++; + + blk_cleanup_queue(cd->disk->queue); + blk_mq_free_tag_set(&cd->tag_set); + put_disk(cd->disk); + } + return -EBUSY; + } + + for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { + if (cd->present) { + register_cdrom(cd->disk, &cd->info); + cd->disk->private_data = cd; + add_disk(cd->disk); } } - if (!found) { - pr_info("%s: No CD-ROM drive found\n", name); - goto out_unregister_pi_driver; - } - return 0; - -out_unregister_pi_driver: - pi_unregister_driver(par_drv); -out_unregister_blkdev: - unregister_blkdev(major, name); - return -ENODEV; } static void __exit pcd_exit(void) @@ -1023,18 +1044,20 @@ static void __exit pcd_exit(void) int unit; for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { - if (!cd->present) + if (!cd->disk) continue; - unregister_cdrom(&cd->info); - del_gendisk(cd->disk); - pi_release(cd->pi); - blk_cleanup_disk(cd->disk); - + if (cd->present) { + del_gendisk(cd->disk); + pi_release(cd->pi); + unregister_cdrom(&cd->info); + } + blk_cleanup_queue(cd->disk->queue); blk_mq_free_tag_set(&cd->tag_set); + put_disk(cd->disk); } - pi_unregister_driver(par_drv); unregister_blkdev(major, name); + pi_unregister_driver(par_drv); } MODULE_LICENSE("GPL"); diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 3637c38c72..675327df6a 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -430,7 +430,7 @@ static void run_fsm(void) int stop = 0; if (!phase) { - pd_current = pd_req->q->disk->private_data; + pd_current = pd_req->rq_disk->private_data; pi_current = pd_current->pi; phase = do_pd_io_start; } @@ -492,7 +492,7 @@ static enum action do_pd_io_start(void) case REQ_OP_WRITE: pd_block = blk_rq_pos(pd_req); pd_count = blk_rq_cur_sectors(pd_req); - if (pd_block + pd_count > get_capacity(pd_req->q->disk)) + if (pd_block + pd_count > get_capacity(pd_req->rq_disk)) return Fail; pd_run = blk_rq_sectors(pd_req); pd_buf = bio_data(pd_req->bio); @@ -775,14 +775,14 @@ static int pd_special_command(struct pd_unit *disk, struct request *rq; struct pd_req *req; - rq = blk_mq_alloc_request(disk->gd->queue, REQ_OP_DRV_IN, 0); + rq = blk_get_request(disk->gd->queue, REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); req = blk_mq_rq_to_pdu(rq); req->func = func; - blk_execute_rq(rq, false); - blk_mq_free_request(rq); + blk_execute_rq(disk->gd, rq, 0); + blk_put_request(rq); return 0; } @@ -875,27 +875,9 @@ static const struct blk_mq_ops pd_mq_ops = { .queue_rq = pd_queue_rq, }; -static int pd_probe_drive(struct pd_unit *disk, int autoprobe, int port, - int mode, int unit, int protocol, int delay) +static void pd_probe_drive(struct pd_unit *disk) { - int index = disk - pd; - int *parm = *drives[index]; struct gendisk *p; - int ret; - - disk->pi = &disk->pia; - disk->access = 0; - disk->changed = 1; - disk->capacity = 0; - disk->drive = parm[D_SLV]; - snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a' + index); - disk->alt_geom = parm[D_GEO]; - disk->standby = parm[D_SBY]; - INIT_LIST_HEAD(&disk->rq_list); - - if (!pi_init(disk->pi, autoprobe, port, mode, unit, protocol, delay, - pd_scratch, PI_PD, verbose, disk->name)) - return -ENXIO; memset(&disk->tag_set, 0, sizeof(disk->tag_set)); disk->tag_set.ops = &pd_mq_ops; @@ -905,14 +887,14 @@ static int pd_probe_drive(struct pd_unit *disk, int autoprobe, int port, disk->tag_set.queue_depth = 2; disk->tag_set.numa_node = NUMA_NO_NODE; disk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING; - ret = blk_mq_alloc_tag_set(&disk->tag_set); - if (ret) - goto pi_release; + + if (blk_mq_alloc_tag_set(&disk->tag_set)) + return; p = blk_mq_alloc_disk(&disk->tag_set, disk); if (IS_ERR(p)) { - ret = PTR_ERR(p); - goto free_tag_set; + blk_mq_free_tag_set(&disk->tag_set); + return; } disk->gd = p; @@ -923,88 +905,102 @@ static int pd_probe_drive(struct pd_unit *disk, int autoprobe, int port, p->minors = 1 << PD_BITS; p->events = DISK_EVENT_MEDIA_CHANGE; p->private_data = disk; + blk_queue_max_hw_sectors(p->queue, cluster); blk_queue_bounce_limit(p->queue, BLK_BOUNCE_HIGH); if (disk->drive == -1) { - for (disk->drive = 0; disk->drive <= 1; disk->drive++) { - ret = pd_special_command(disk, pd_identify); - if (ret == 0) - break; - } - } else { - ret = pd_special_command(disk, pd_identify); - } - if (ret) - goto put_disk; - set_capacity(disk->gd, disk->capacity); - ret = add_disk(disk->gd); - if (ret) - goto cleanup_disk; - return 0; -cleanup_disk: - blk_cleanup_disk(disk->gd); -put_disk: - put_disk(p); + for (disk->drive = 0; disk->drive <= 1; disk->drive++) + if (pd_special_command(disk, pd_identify) == 0) + return; + } else if (pd_special_command(disk, pd_identify) == 0) + return; disk->gd = NULL; -free_tag_set: - blk_mq_free_tag_set(&disk->tag_set); -pi_release: - pi_release(disk->pi); - return ret; + put_disk(p); } -static int __init pd_init(void) +static int pd_detect(void) { int found = 0, unit, pd_drive_count = 0; struct pd_unit *disk; - if (disable) - return -ENODEV; - - if (register_blkdev(major, name)) - return -ENODEV; - - printk("%s: %s version %s, major %d, cluster %d, nice %d\n", - name, name, PD_VERSION, major, cluster, nice); + for (unit = 0; unit < PD_UNITS; unit++) { + int *parm = *drives[unit]; + struct pd_unit *disk = pd + unit; + disk->pi = &disk->pia; + disk->access = 0; + disk->changed = 1; + disk->capacity = 0; + disk->drive = parm[D_SLV]; + snprintf(disk->name, PD_NAMELEN, "%s%c", name, 'a'+unit); + disk->alt_geom = parm[D_GEO]; + disk->standby = parm[D_SBY]; + if (parm[D_PRT]) + pd_drive_count++; + INIT_LIST_HEAD(&disk->rq_list); + } par_drv = pi_register_driver(name); if (!par_drv) { pr_err("failed to register %s driver\n", name); - goto out_unregister_blkdev; - } - - for (unit = 0; unit < PD_UNITS; unit++) { - int *parm = *drives[unit]; - - if (parm[D_PRT]) - pd_drive_count++; + return -1; } if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ - if (!pd_probe_drive(pd, 1, -1, -1, -1, -1, -1)) - found++; + disk = pd; + if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch, + PI_PD, verbose, disk->name)) { + pd_probe_drive(disk); + if (!disk->gd) + pi_release(disk->pi); + } + } else { for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) { int *parm = *drives[unit]; if (!parm[D_PRT]) continue; - if (!pd_probe_drive(disk, 0, parm[D_PRT], parm[D_MOD], - parm[D_UNI], parm[D_PRO], parm[D_DLY])) - found++; + if (pi_init(disk->pi, 0, parm[D_PRT], parm[D_MOD], + parm[D_UNI], parm[D_PRO], parm[D_DLY], + pd_scratch, PI_PD, verbose, disk->name)) { + pd_probe_drive(disk); + if (!disk->gd) + pi_release(disk->pi); + } + } + } + for (unit = 0, disk = pd; unit < PD_UNITS; unit++, disk++) { + if (disk->gd) { + set_capacity(disk->gd, disk->capacity); + add_disk(disk->gd); + found = 1; } } if (!found) { printk("%s: no valid drive found\n", name); - goto out_pi_unregister_driver; + pi_unregister_driver(par_drv); } + return found; +} + +static int __init pd_init(void) +{ + if (disable) + goto out1; + + if (register_blkdev(major, name)) + goto out1; + + printk("%s: %s version %s, major %d, cluster %d, nice %d\n", + name, name, PD_VERSION, major, cluster, nice); + if (!pd_detect()) + goto out2; return 0; -out_pi_unregister_driver: - pi_unregister_driver(par_drv); -out_unregister_blkdev: +out2: unregister_blkdev(major, name); +out1: return -ENODEV; } diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 292e9a4ce1..d5b9c88ba7 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -214,6 +214,7 @@ static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); static void pf_release(struct gendisk *disk, fmode_t mode); +static int pf_detect(void); static void do_pf_read(void); static void do_pf_read_start(void); static void do_pf_write(void); @@ -284,6 +285,45 @@ static const struct blk_mq_ops pf_mq_ops = { .queue_rq = pf_queue_rq, }; +static void __init pf_init_units(void) +{ + struct pf_unit *pf; + int unit; + + pf_drive_count = 0; + for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) { + struct gendisk *disk; + + if (blk_mq_alloc_sq_tag_set(&pf->tag_set, &pf_mq_ops, 1, + BLK_MQ_F_SHOULD_MERGE)) + continue; + + disk = blk_mq_alloc_disk(&pf->tag_set, pf); + if (IS_ERR(disk)) { + blk_mq_free_tag_set(&pf->tag_set); + continue; + } + + INIT_LIST_HEAD(&pf->rq_list); + blk_queue_max_segments(disk->queue, cluster); + blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); + pf->disk = disk; + pf->pi = &pf->pia; + pf->media_status = PF_NM; + pf->drive = (*drives[unit])[D_SLV]; + pf->lun = (*drives[unit])[D_LUN]; + snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit); + disk->major = major; + disk->first_minor = unit; + disk->minors = 1; + strcpy(disk->disk_name, pf->name); + disk->fops = &pf_fops; + disk->events = DISK_EVENT_MEDIA_CHANGE; + if (!(*drives[unit])[D_PRT]) + pf_drive_count++; + } +} + static int pf_open(struct block_device *bdev, fmode_t mode) { struct pf_unit *pf = bdev->bd_disk->private_data; @@ -651,9 +691,9 @@ static int pf_identify(struct pf_unit *pf) return 0; } -/* - * returns 0, with id set if drive is detected, otherwise an error code. - */ +/* returns 0, with id set if drive is detected + -1, if drive detection failed +*/ static int pf_probe(struct pf_unit *pf) { if (pf->drive == -1) { @@ -675,7 +715,60 @@ static int pf_probe(struct pf_unit *pf) if (!pf_identify(pf)) return 0; } - return -ENODEV; + return -1; +} + +static int pf_detect(void) +{ + struct pf_unit *pf = units; + int k, unit; + + printk("%s: %s version %s, major %d, cluster %d, nice %d\n", + name, name, PF_VERSION, major, cluster, nice); + + par_drv = pi_register_driver(name); + if (!par_drv) { + pr_err("failed to register %s driver\n", name); + return -1; + } + k = 0; + if (pf_drive_count == 0) { + if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF, + verbose, pf->name)) { + if (!pf_probe(pf) && pf->disk) { + pf->present = 1; + k++; + } else + pi_release(pf->pi); + } + + } else + for (unit = 0; unit < PF_UNITS; unit++, pf++) { + int *conf = *drives[unit]; + if (!conf[D_PRT]) + continue; + if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], + conf[D_UNI], conf[D_PRO], conf[D_DLY], + pf_scratch, PI_PF, verbose, pf->name)) { + if (pf->disk && !pf_probe(pf)) { + pf->present = 1; + k++; + } else + pi_release(pf->pi); + } + } + if (k) + return 0; + + printk("%s: No ATAPI disk detected\n", name); + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { + if (!pf->disk) + continue; + blk_cleanup_disk(pf->disk); + blk_mq_free_tag_set(&pf->tag_set); + } + pi_unregister_driver(par_drv); + return -1; } /* The i/o request engine */ @@ -746,12 +839,12 @@ static void pf_request(void) if (!pf_req && !set_next_request()) return; - pf_current = pf_req->q->disk->private_data; + pf_current = pf_req->rq_disk->private_data; pf_block = blk_rq_pos(pf_req); pf_run = blk_rq_sectors(pf_req); pf_count = blk_rq_cur_sectors(pf_req); - if (pf_block + pf_count > get_capacity(pf_req->q->disk)) { + if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) { pf_end_request(BLK_STS_IOERR); goto repeat; } @@ -921,135 +1014,61 @@ static void do_pf_write_done(void) next_request(0); } -static int __init pf_init_unit(struct pf_unit *pf, bool autoprobe, int port, - int mode, int unit, int protocol, int delay, int ms) -{ - struct gendisk *disk; - int ret; - - ret = blk_mq_alloc_sq_tag_set(&pf->tag_set, &pf_mq_ops, 1, - BLK_MQ_F_SHOULD_MERGE); - if (ret) - return ret; - - disk = blk_mq_alloc_disk(&pf->tag_set, pf); - if (IS_ERR(disk)) { - ret = PTR_ERR(disk); - goto out_free_tag_set; - } - disk->major = major; - disk->first_minor = pf - units; - disk->minors = 1; - strcpy(disk->disk_name, pf->name); - disk->fops = &pf_fops; - disk->flags |= GENHD_FL_NO_PART; - disk->events = DISK_EVENT_MEDIA_CHANGE; - disk->private_data = pf; - - blk_queue_max_segments(disk->queue, cluster); - blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); - - INIT_LIST_HEAD(&pf->rq_list); - pf->disk = disk; - pf->pi = &pf->pia; - pf->media_status = PF_NM; - pf->drive = (*drives[disk->first_minor])[D_SLV]; - pf->lun = (*drives[disk->first_minor])[D_LUN]; - snprintf(pf->name, PF_NAMELEN, "%s%d", name, disk->first_minor); - - if (!pi_init(pf->pi, autoprobe, port, mode, unit, protocol, delay, - pf_scratch, PI_PF, verbose, pf->name)) { - ret = -ENODEV; - goto out_free_disk; - } - ret = pf_probe(pf); - if (ret) - goto out_pi_release; - - ret = add_disk(disk); - if (ret) - goto out_pi_release; - pf->present = 1; - return 0; - -out_pi_release: - pi_release(pf->pi); -out_free_disk: - blk_cleanup_disk(pf->disk); -out_free_tag_set: - blk_mq_free_tag_set(&pf->tag_set); - return ret; -} - static int __init pf_init(void) { /* preliminary initialisation */ struct pf_unit *pf; - int found = 0, unit; + int unit; if (disable) return -EINVAL; - if (register_blkdev(major, name)) - return -EBUSY; + pf_init_units(); - printk("%s: %s version %s, major %d, cluster %d, nice %d\n", - name, name, PF_VERSION, major, cluster, nice); - - par_drv = pi_register_driver(name); - if (!par_drv) { - pr_err("failed to register %s driver\n", name); - goto out_unregister_blkdev; - } - - for (unit = 0; unit < PF_UNITS; unit++) { - if (!(*drives[unit])[D_PRT]) - pf_drive_count++; - } - - pf = units; - if (pf_drive_count == 0) { - if (pf_init_unit(pf, 1, -1, -1, -1, -1, -1, verbose)) - found++; - } else { - for (unit = 0; unit < PF_UNITS; unit++, pf++) { - int *conf = *drives[unit]; - if (!conf[D_PRT]) - continue; - if (pf_init_unit(pf, 0, conf[D_PRT], conf[D_MOD], - conf[D_UNI], conf[D_PRO], conf[D_DLY], - verbose)) - found++; - } - } - if (!found) { - printk("%s: No ATAPI disk detected\n", name); - goto out_unregister_pi_driver; - } + if (pf_detect()) + return -ENODEV; pf_busy = 0; - return 0; -out_unregister_pi_driver: - pi_unregister_driver(par_drv); -out_unregister_blkdev: - unregister_blkdev(major, name); - return -ENODEV; + if (register_blkdev(major, name)) { + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { + if (!pf->disk) + continue; + blk_cleanup_queue(pf->disk->queue); + blk_mq_free_tag_set(&pf->tag_set); + put_disk(pf->disk); + } + return -EBUSY; + } + + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { + struct gendisk *disk = pf->disk; + + if (!pf->present) + continue; + disk->private_data = pf; + add_disk(disk); + } + return 0; } static void __exit pf_exit(void) { struct pf_unit *pf; int unit; - - for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { - if (!pf->present) - continue; - del_gendisk(pf->disk); - blk_cleanup_disk(pf->disk); - blk_mq_free_tag_set(&pf->tag_set); - pi_release(pf->pi); - } - unregister_blkdev(major, name); + for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { + if (!pf->disk) + continue; + + if (pf->present) + del_gendisk(pf->disk); + + blk_cleanup_queue(pf->disk->queue); + blk_mq_free_tag_set(&pf->tag_set); + put_disk(pf->disk); + + if (pf->present) + pi_release(pf->pi); + } } MODULE_LICENSE("GPL"); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 2b6b70a39e..0f26b2510a 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -113,10 +113,57 @@ static sector_t get_zone(sector_t sector, struct pktcdvd_device *pd) return (sector + pd->offset) & ~(sector_t)(pd->settings.size - 1); } +/* + * create and register a pktcdvd kernel object. + */ +static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd, + const char* name, + struct kobject* parent, + struct kobj_type* ktype) +{ + struct pktcdvd_kobj *p; + int error; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return NULL; + p->pd = pd; + error = kobject_init_and_add(&p->kobj, ktype, parent, "%s", name); + if (error) { + kobject_put(&p->kobj); + return NULL; + } + kobject_uevent(&p->kobj, KOBJ_ADD); + return p; +} +/* + * remove a pktcdvd kernel object. + */ +static void pkt_kobj_remove(struct pktcdvd_kobj *p) +{ + if (p) + kobject_put(&p->kobj); +} +/* + * default release function for pktcdvd kernel objects. + */ +static void pkt_kobj_release(struct kobject *kobj) +{ + kfree(to_pktcdvdkobj(kobj)); +} + + /********************************************************** + * * sysfs interface for pktcdvd * by (C) 2006 Thomas Maier - + * + **********************************************************/ + +#define DEF_ATTR(_obj,_name,_mode) \ + static struct attribute _obj = { .name = _name, .mode = _mode } + +/********************************************************** /sys/class/pktcdvd/pktcdvd[0-7]/ stat/reset stat/packets_started @@ -129,94 +176,75 @@ static sector_t get_zone(sector_t sector, struct pktcdvd_device *pd) write_queue/congestion_on **********************************************************/ -static ssize_t packets_started_show(struct device *dev, - struct device_attribute *attr, char *buf) +DEF_ATTR(kobj_pkt_attr_st1, "reset", 0200); +DEF_ATTR(kobj_pkt_attr_st2, "packets_started", 0444); +DEF_ATTR(kobj_pkt_attr_st3, "packets_finished", 0444); +DEF_ATTR(kobj_pkt_attr_st4, "kb_written", 0444); +DEF_ATTR(kobj_pkt_attr_st5, "kb_read", 0444); +DEF_ATTR(kobj_pkt_attr_st6, "kb_read_gather", 0444); + +static struct attribute *kobj_pkt_attrs_stat[] = { + &kobj_pkt_attr_st1, + &kobj_pkt_attr_st2, + &kobj_pkt_attr_st3, + &kobj_pkt_attr_st4, + &kobj_pkt_attr_st5, + &kobj_pkt_attr_st6, + NULL +}; + +DEF_ATTR(kobj_pkt_attr_wq1, "size", 0444); +DEF_ATTR(kobj_pkt_attr_wq2, "congestion_off", 0644); +DEF_ATTR(kobj_pkt_attr_wq3, "congestion_on", 0644); + +static struct attribute *kobj_pkt_attrs_wqueue[] = { + &kobj_pkt_attr_wq1, + &kobj_pkt_attr_wq2, + &kobj_pkt_attr_wq3, + NULL +}; + +static ssize_t kobj_pkt_show(struct kobject *kobj, + struct attribute *attr, char *data) { - struct pktcdvd_device *pd = dev_get_drvdata(dev); + struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd; + int n = 0; + int v; + if (strcmp(attr->name, "packets_started") == 0) { + n = sprintf(data, "%lu\n", pd->stats.pkt_started); - return sysfs_emit(buf, "%lu\n", pd->stats.pkt_started); -} -static DEVICE_ATTR_RO(packets_started); + } else if (strcmp(attr->name, "packets_finished") == 0) { + n = sprintf(data, "%lu\n", pd->stats.pkt_ended); -static ssize_t packets_finished_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); + } else if (strcmp(attr->name, "kb_written") == 0) { + n = sprintf(data, "%lu\n", pd->stats.secs_w >> 1); - return sysfs_emit(buf, "%lu\n", pd->stats.pkt_ended); -} -static DEVICE_ATTR_RO(packets_finished); + } else if (strcmp(attr->name, "kb_read") == 0) { + n = sprintf(data, "%lu\n", pd->stats.secs_r >> 1); -static ssize_t kb_written_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); + } else if (strcmp(attr->name, "kb_read_gather") == 0) { + n = sprintf(data, "%lu\n", pd->stats.secs_rg >> 1); - return sysfs_emit(buf, "%lu\n", pd->stats.secs_w >> 1); -} -static DEVICE_ATTR_RO(kb_written); + } else if (strcmp(attr->name, "size") == 0) { + spin_lock(&pd->lock); + v = pd->bio_queue_size; + spin_unlock(&pd->lock); + n = sprintf(data, "%d\n", v); -static ssize_t kb_read_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); + } else if (strcmp(attr->name, "congestion_off") == 0) { + spin_lock(&pd->lock); + v = pd->write_congestion_off; + spin_unlock(&pd->lock); + n = sprintf(data, "%d\n", v); - return sysfs_emit(buf, "%lu\n", pd->stats.secs_r >> 1); -} -static DEVICE_ATTR_RO(kb_read); - -static ssize_t kb_read_gather_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%lu\n", pd->stats.secs_rg >> 1); -} -static DEVICE_ATTR_RO(kb_read_gather); - -static ssize_t reset_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t len) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); - - if (len > 0) { - pd->stats.pkt_started = 0; - pd->stats.pkt_ended = 0; - pd->stats.secs_w = 0; - pd->stats.secs_rg = 0; - pd->stats.secs_r = 0; + } else if (strcmp(attr->name, "congestion_on") == 0) { + spin_lock(&pd->lock); + v = pd->write_congestion_on; + spin_unlock(&pd->lock); + n = sprintf(data, "%d\n", v); } - return len; -} -static DEVICE_ATTR_WO(reset); - -static struct attribute *pkt_stat_attrs[] = { - &dev_attr_packets_finished.attr, - &dev_attr_packets_started.attr, - &dev_attr_kb_read.attr, - &dev_attr_kb_written.attr, - &dev_attr_kb_read_gather.attr, - &dev_attr_reset.attr, - NULL, -}; - -static const struct attribute_group pkt_stat_group = { - .name = "stat", - .attrs = pkt_stat_attrs, -}; - -static ssize_t size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); - int n; - - spin_lock(&pd->lock); - n = sysfs_emit(buf, "%d\n", pd->bio_queue_size); - spin_unlock(&pd->lock); return n; } -static DEVICE_ATTR_RO(size); static void init_write_congestion_marks(int* lo, int* hi) { @@ -235,56 +263,30 @@ static void init_write_congestion_marks(int* lo, int* hi) } } -static ssize_t congestion_off_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t kobj_pkt_store(struct kobject *kobj, + struct attribute *attr, + const char *data, size_t len) { - struct pktcdvd_device *pd = dev_get_drvdata(dev); - int n; - - spin_lock(&pd->lock); - n = sysfs_emit(buf, "%d\n", pd->write_congestion_off); - spin_unlock(&pd->lock); - return n; -} - -static ssize_t congestion_off_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); + struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd; int val; - if (sscanf(buf, "%d", &val) == 1) { + if (strcmp(attr->name, "reset") == 0 && len > 0) { + pd->stats.pkt_started = 0; + pd->stats.pkt_ended = 0; + pd->stats.secs_w = 0; + pd->stats.secs_rg = 0; + pd->stats.secs_r = 0; + + } else if (strcmp(attr->name, "congestion_off") == 0 + && sscanf(data, "%d", &val) == 1) { spin_lock(&pd->lock); pd->write_congestion_off = val; init_write_congestion_marks(&pd->write_congestion_off, &pd->write_congestion_on); spin_unlock(&pd->lock); - } - return len; -} -static DEVICE_ATTR_RW(congestion_off); -static ssize_t congestion_on_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); - int n; - - spin_lock(&pd->lock); - n = sysfs_emit(buf, "%d\n", pd->write_congestion_on); - spin_unlock(&pd->lock); - return n; -} - -static ssize_t congestion_on_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct pktcdvd_device *pd = dev_get_drvdata(dev); - int val; - - if (sscanf(buf, "%d", &val) == 1) { + } else if (strcmp(attr->name, "congestion_on") == 0 + && sscanf(data, "%d", &val) == 1) { spin_lock(&pd->lock); pd->write_congestion_on = val; init_write_congestion_marks(&pd->write_congestion_off, @@ -293,39 +295,44 @@ static ssize_t congestion_on_store(struct device *dev, } return len; } -static DEVICE_ATTR_RW(congestion_on); -static struct attribute *pkt_wq_attrs[] = { - &dev_attr_congestion_on.attr, - &dev_attr_congestion_off.attr, - &dev_attr_size.attr, - NULL, +static const struct sysfs_ops kobj_pkt_ops = { + .show = kobj_pkt_show, + .store = kobj_pkt_store }; - -static const struct attribute_group pkt_wq_group = { - .name = "write_queue", - .attrs = pkt_wq_attrs, +static struct kobj_type kobj_pkt_type_stat = { + .release = pkt_kobj_release, + .sysfs_ops = &kobj_pkt_ops, + .default_attrs = kobj_pkt_attrs_stat }; - -static const struct attribute_group *pkt_groups[] = { - &pkt_stat_group, - &pkt_wq_group, - NULL, +static struct kobj_type kobj_pkt_type_wqueue = { + .release = pkt_kobj_release, + .sysfs_ops = &kobj_pkt_ops, + .default_attrs = kobj_pkt_attrs_wqueue }; static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) { if (class_pktcdvd) { - pd->dev = device_create_with_groups(class_pktcdvd, NULL, - MKDEV(0, 0), pd, pkt_groups, - "%s", pd->name); + pd->dev = device_create(class_pktcdvd, NULL, MKDEV(0, 0), NULL, + "%s", pd->name); if (IS_ERR(pd->dev)) pd->dev = NULL; } + if (pd->dev) { + pd->kobj_stat = pkt_kobj_create(pd, "stat", + &pd->dev->kobj, + &kobj_pkt_type_stat); + pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue", + &pd->dev->kobj, + &kobj_pkt_type_wqueue); + } } static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) { + pkt_kobj_remove(pd->kobj_stat); + pkt_kobj_remove(pd->kobj_wqueue); if (class_pktcdvd) device_unregister(pd->dev); } @@ -696,7 +703,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * struct request *rq; int ret = 0; - rq = scsi_alloc_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? + rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); @@ -715,11 +722,11 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * if (cgc->quiet) rq->rq_flags |= RQF_QUIET; - blk_execute_rq(rq, false); + blk_execute_rq(pd->bdev->bd_disk, rq, 0); if (scsi_req(rq)->result) ret = -EIO; out: - blk_mq_free_request(rq); + blk_put_request(rq); return ret; } @@ -1100,6 +1107,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd) sector_t zone = 0; /* Suppress gcc warning */ struct pkt_rb_node *node, *first_node; struct rb_node *n; + int wakeup; atomic_set(&pd->scan_queue, 0); @@ -1171,14 +1179,12 @@ static int pkt_handle_queue(struct pktcdvd_device *pd) spin_unlock(&pkt->lock); } /* check write congestion marks, and if bio_queue_size is - * below, wake up any waiters - */ - if (pd->congested && - pd->bio_queue_size <= pd->write_congestion_off) { - pd->congested = false; - wake_up_var(&pd->congested); - } + below, wake up any waiters */ + wakeup = (pd->write_congestion_on > 0 + && pd->bio_queue_size <= pd->write_congestion_off); spin_unlock(&pd->lock); + if (wakeup) + clear_bdi_congested(pd->disk->bdi, BLK_RW_ASYNC); pkt->sleep_time = max(PACKET_WAIT_TIME, 1); pkt_set_state(pkt, PACKET_WAITING_STATE); @@ -2350,7 +2356,7 @@ static void pkt_make_request_write(struct request_queue *q, struct bio *bio) } spin_unlock(&pd->cdrw.active_list_lock); - /* + /* * Test if there is enough room left in the bio work queue * (queue size >= congestion on mark). * If not, wait till the work queue size is below the congestion off mark. @@ -2358,20 +2364,12 @@ static void pkt_make_request_write(struct request_queue *q, struct bio *bio) spin_lock(&pd->lock); if (pd->write_congestion_on > 0 && pd->bio_queue_size >= pd->write_congestion_on) { - struct wait_bit_queue_entry wqe; - - init_wait_var_entry(&wqe, &pd->congested, 0); - for (;;) { - prepare_to_wait_event(__var_waitqueue(&pd->congested), - &wqe.wq_entry, - TASK_UNINTERRUPTIBLE); - if (pd->bio_queue_size <= pd->write_congestion_off) - break; - pd->congested = true; + set_bdi_congested(bio->bi_bdev->bd_disk->bdi, BLK_RW_ASYNC); + do { spin_unlock(&pd->lock); - schedule(); + congestion_wait(BLK_RW_ASYNC, HZ); spin_lock(&pd->lock); - } + } while(pd->bio_queue_size > pd->write_congestion_off); } spin_unlock(&pd->lock); @@ -2402,7 +2400,7 @@ static void pkt_make_request_write(struct request_queue *q, struct bio *bio) } } -static void pkt_submit_bio(struct bio *bio) +static blk_qc_t pkt_submit_bio(struct bio *bio) { struct pktcdvd_device *pd; char b[BDEVNAME_SIZE]; @@ -2425,7 +2423,7 @@ static void pkt_submit_bio(struct bio *bio) */ if (bio_data_dir(bio) == READ) { pkt_make_request_read(pd, bio); - return; + return BLK_QC_T_NONE; } if (!test_bit(PACKET_WRITABLE, &pd->flags)) { @@ -2457,9 +2455,10 @@ static void pkt_submit_bio(struct bio *bio) pkt_make_request_write(bio->bi_bdev->bd_disk->queue, split); } while (split != bio); - return; + return BLK_QC_T_NONE; end_io: bio_io_error(bio); + return BLK_QC_T_NONE; } static void pkt_init_queue(struct pktcdvd_device *pd) @@ -2538,7 +2537,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) int i; char b[BDEVNAME_SIZE]; struct block_device *bdev; - struct scsi_device *sdev; if (pd->pkt_dev == dev) { pkt_err(pd, "recursive setup not allowed\n"); @@ -2562,12 +2560,10 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) bdev = blkdev_get_by_dev(dev, FMODE_READ | FMODE_NDELAY, NULL); if (IS_ERR(bdev)) return PTR_ERR(bdev); - sdev = scsi_device_from_queue(bdev->bd_disk->queue); - if (!sdev) { + if (!blk_queue_scsi_passthrough(bdev_get_queue(bdev))) { blkdev_put(bdev, FMODE_READ | FMODE_NDELAY); return -EINVAL; } - put_device(&sdev->sdev_gendev); /* This is safe, since we have a reference from open(). */ __module_get(THIS_MODULE); @@ -2721,7 +2717,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) disk->first_minor = idx; disk->minors = 1; disk->fops = &pktcdvd_ops; - disk->flags = GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; + disk->flags = GENHD_FL_REMOVABLE; strcpy(disk->disk_name, pd->name); disk->private_data = pd; @@ -2733,9 +2729,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) /* inherit events of the host device */ disk->events = pd->bdev->bd_disk->events; - ret = add_disk(disk); - if (ret) - goto out_mem2; + add_disk(disk); pkt_sysfs_dev_new(pd); pkt_debugfs_dev_new(pd); diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 3054adf774..8d51efbe04 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -467,13 +467,9 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) gendisk->disk_name, priv->model, priv->raw_capacity >> 11, get_capacity(gendisk) >> 11); - error = device_add_disk(&dev->sbd.core, gendisk, NULL); - if (error) - goto fail_cleanup_disk; - + device_add_disk(&dev->sbd.core, gendisk, NULL); return 0; -fail_cleanup_disk: - blk_cleanup_disk(gendisk); + fail_free_tag_set: blk_mq_free_tag_set(&priv->tag_set); fail_teardown: diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index 4f90819e24..c7b19e128b 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -578,7 +578,7 @@ static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev, return next; } -static void ps3vram_submit_bio(struct bio *bio) +static blk_qc_t ps3vram_submit_bio(struct bio *bio) { struct ps3_system_bus_device *dev = bio->bi_bdev->bd_disk->private_data; struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev); @@ -594,11 +594,13 @@ static void ps3vram_submit_bio(struct bio *bio) spin_unlock_irq(&priv->lock); if (busy) - return; + return BLK_QC_T_NONE; do { bio = ps3vram_do_bio(dev, bio); } while (bio); + + return BLK_QC_T_NONE; } static const struct block_device_operations ps3vram_fops = { @@ -742,7 +744,6 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) priv->gendisk = gendisk; gendisk->major = ps3vram_major; gendisk->minors = 1; - gendisk->flags |= GENHD_FL_NO_PART; gendisk->fops = &ps3vram_fops; gendisk->private_data = dev; strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name)); @@ -754,14 +755,9 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) dev_info(&dev->core, "%s: Using %llu MiB of GPU memory\n", gendisk->disk_name, get_capacity(gendisk) >> 11); - error = device_add_disk(&dev->core, gendisk, NULL); - if (error) - goto out_cleanup_disk; - + device_add_disk(&dev->core, gendisk, NULL); return 0; -out_cleanup_disk: - blk_cleanup_disk(gendisk); out_cache_cleanup: remove_proc_entry(DEVICE_NAME, NULL); ps3vram_cache_cleanup(dev); diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index b844432bad..c4a52f3360 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -836,7 +836,7 @@ struct rbd_options { u32 alloc_hint_flags; /* CEPH_OSD_OP_ALLOC_HINT_FLAG_* */ }; -#define RBD_QUEUE_DEPTH_DEFAULT BLKDEV_DEFAULT_RQ +#define RBD_QUEUE_DEPTH_DEFAULT BLKDEV_MAX_RQ #define RBD_ALLOC_SIZE_DEFAULT (64 * 1024) #define RBD_LOCK_TIMEOUT_DEFAULT 0 /* no timeout */ #define RBD_READ_ONLY_DEFAULT false @@ -4924,10 +4924,12 @@ static int rbd_init_disk(struct rbd_device *rbd_dev) rbd_dev->dev_id); disk->major = rbd_dev->major; disk->first_minor = rbd_dev->minor; - if (single_major) + if (single_major) { disk->minors = (1 << RBD_SINGLE_MAJOR_PART_SHIFT); - else + disk->flags |= GENHD_FL_EXT_DEVT; + } else { disk->minors = RBD_MINORS_PER_MAJOR; + } disk->fops = &rbd_bd_ops; disk->private_data = rbd_dev; @@ -6189,7 +6191,7 @@ static inline size_t next_token(const char **buf) * These are the characters that produce nonzero for * isspace() in the "C" and "POSIX" locales. */ - static const char spaces[] = " \f\n\r\t\v"; + const char *spaces = " \f\n\r\t\v"; *buf += strspn(*buf, spaces); /* Find start of token */ @@ -6495,8 +6497,7 @@ static int rbd_add_parse_args(const char *buf, pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT; pctx.opts->trim = RBD_TRIM_DEFAULT; - ret = ceph_parse_mon_ips(mon_addrs, mon_addrs_size, pctx.copts, NULL, - ','); + ret = ceph_parse_mon_ips(mon_addrs, mon_addrs_size, pctx.copts, NULL); if (ret) goto out_err; @@ -7053,9 +7054,7 @@ static ssize_t do_rbd_add(struct bus_type *bus, if (rc) goto err_out_image_lock; - rc = device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL); - if (rc) - goto err_out_cleanup_disk; + device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL); spin_lock(&rbd_dev_list_lock); list_add_tail(&rbd_dev->node, &rbd_dev_list); @@ -7069,8 +7068,6 @@ static ssize_t do_rbd_add(struct bus_type *bus, module_put(THIS_MODULE); return rc; -err_out_cleanup_disk: - rbd_free_disk(rbd_dev); err_out_image_lock: rbd_dev_image_unlock(rbd_dev); rbd_dev_device_release(rbd_dev); diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c index 2be5d87a3c..44e45af00e 100644 --- a/drivers/block/rnbd/rnbd-clt-sysfs.c +++ b/drivers/block/rnbd/rnbd-clt-sysfs.c @@ -452,7 +452,6 @@ static struct attribute *rnbd_dev_attrs[] = { &rnbd_clt_nr_poll_queues.attr, NULL, }; -ATTRIBUTE_GROUPS(rnbd_dev); void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev) { @@ -475,7 +474,7 @@ void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev) static struct kobj_type rnbd_dev_ktype = { .sysfs_ops = &kobj_sysfs_ops, - .default_groups = rnbd_dev_groups, + .default_attrs = rnbd_dev_attrs, }; static int rnbd_clt_add_dev_kobj(struct rnbd_clt_dev *dev) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index c08971de36..bd4a41afbb 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -196,7 +196,7 @@ rnbd_get_cpu_qlist(struct rnbd_clt_session *sess, int cpu) return per_cpu_ptr(sess->cpu_queues, bit); } else if (cpu != 0) { /* Search from 0 to cpu */ - bit = find_first_bit(sess->cpu_queues_bm, cpu); + bit = find_next_bit(sess->cpu_queues_bm, cpu, 0); if (bit < cpu) return per_cpu_ptr(sess->cpu_queues, bit); } @@ -393,7 +393,7 @@ static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu) static void rnbd_softirq_done_fn(struct request *rq) { - struct rnbd_clt_dev *dev = rq->q->disk->private_data; + struct rnbd_clt_dev *dev = rq->rq_disk->private_data; struct rnbd_clt_session *sess = dev->sess; struct rnbd_iu *iu; @@ -433,7 +433,7 @@ static void msg_conf(void *priv, int errno) schedule_work(&iu->work); } -static int send_usr_msg(struct rtrs_clt_sess *rtrs, int dir, +static int send_usr_msg(struct rtrs_clt *rtrs, int dir, struct rnbd_iu *iu, struct kvec *vec, size_t len, struct scatterlist *sg, unsigned int sg_len, void (*conf)(struct work_struct *work), @@ -1010,7 +1010,7 @@ static int rnbd_client_xfer_request(struct rnbd_clt_dev *dev, struct request *rq, struct rnbd_iu *iu) { - struct rtrs_clt_sess *rtrs = dev->sess->rtrs; + struct rtrs_clt *rtrs = dev->sess->rtrs; struct rtrs_permit *permit = iu->permit; struct rnbd_msg_io msg; struct rtrs_clt_req_ops req_ops; @@ -1133,7 +1133,7 @@ static blk_status_t rnbd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { struct request *rq = bd->rq; - struct rnbd_clt_dev *dev = rq->q->disk->private_data; + struct rnbd_clt_dev *dev = rq->rq_disk->private_data; struct rnbd_iu *iu = blk_mq_rq_to_pdu(rq); int err; blk_status_t ret = BLK_STS_IOERR; @@ -1176,7 +1176,7 @@ static blk_status_t rnbd_queue_rq(struct blk_mq_hw_ctx *hctx, return ret; } -static int rnbd_rdma_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) +static int rnbd_rdma_poll(struct blk_mq_hw_ctx *hctx) { struct rnbd_queue *q = hctx->driver_data; struct rnbd_clt_dev *dev = q->dev; @@ -1384,10 +1384,8 @@ static void setup_request_queue(struct rnbd_clt_dev *dev) blk_queue_write_cache(dev->queue, dev->wc, dev->fua); } -static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx) +static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx) { - int err; - dev->gd->major = rnbd_client_major; dev->gd->first_minor = idx << RNBD_PART_BITS; dev->gd->minors = 1 << RNBD_PART_BITS; @@ -1412,11 +1410,7 @@ static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx) if (!dev->rotational) blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue); - err = add_disk(dev->gd); - if (err) - blk_cleanup_disk(dev->gd); - - return err; + add_disk(dev->gd); } static int rnbd_client_setup_device(struct rnbd_clt_dev *dev) @@ -1432,7 +1426,8 @@ static int rnbd_client_setup_device(struct rnbd_clt_dev *dev) rnbd_init_mq_hw_queues(dev); setup_request_queue(dev); - return rnbd_clt_setup_gen_disk(dev, idx); + rnbd_clt_setup_gen_disk(dev, idx); + return 0; } static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, diff --git a/drivers/block/rnbd/rnbd-clt.h b/drivers/block/rnbd/rnbd-clt.h index 0c2cae7f39..9ef8c4f306 100644 --- a/drivers/block/rnbd/rnbd-clt.h +++ b/drivers/block/rnbd/rnbd-clt.h @@ -75,7 +75,7 @@ struct rnbd_cpu_qlist { struct rnbd_clt_session { struct list_head list; - struct rtrs_clt_sess *rtrs; + struct rtrs_clt *rtrs; wait_queue_head_t rtrs_waitq; bool rtrs_ready; struct rnbd_cpu_qlist __percpu diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c index 1ee808fc60..aafecfe970 100644 --- a/drivers/block/rnbd/rnbd-srv.c +++ b/drivers/block/rnbd/rnbd-srv.c @@ -263,15 +263,15 @@ static void destroy_sess(struct rnbd_srv_session *srv_sess) kfree(srv_sess); } -static int create_sess(struct rtrs_srv_sess *rtrs) +static int create_sess(struct rtrs_srv *rtrs) { struct rnbd_srv_session *srv_sess; - char pathname[NAME_MAX]; + char sessname[NAME_MAX]; int err; - err = rtrs_srv_get_path_name(rtrs, pathname, sizeof(pathname)); + err = rtrs_srv_get_sess_name(rtrs, sessname, sizeof(sessname)); if (err) { - pr_err("rtrs_srv_get_path_name(%s): %d\n", pathname, err); + pr_err("rtrs_srv_get_sess_name(%s): %d\n", sessname, err); return err; } @@ -284,8 +284,8 @@ static int create_sess(struct rtrs_srv_sess *rtrs) offsetof(struct rnbd_dev_blk_io, bio), BIOSET_NEED_BVECS); if (err) { - pr_err("Allocating srv_session for path %s failed\n", - pathname); + pr_err("Allocating srv_session for session %s failed\n", + sessname); kfree(srv_sess); return err; } @@ -298,14 +298,14 @@ static int create_sess(struct rtrs_srv_sess *rtrs) mutex_unlock(&sess_lock); srv_sess->rtrs = rtrs; - strscpy(srv_sess->sessname, pathname, sizeof(srv_sess->sessname)); + strscpy(srv_sess->sessname, sessname, sizeof(srv_sess->sessname)); rtrs_srv_set_sess_priv(rtrs, srv_sess); return 0; } -static int rnbd_srv_link_ev(struct rtrs_srv_sess *rtrs, +static int rnbd_srv_link_ev(struct rtrs_srv *rtrs, enum rtrs_srv_link_ev ev, void *priv) { struct rnbd_srv_session *srv_sess = priv; diff --git a/drivers/block/rnbd/rnbd-srv.h b/drivers/block/rnbd/rnbd-srv.h index e5604bce12..98ddc31eb4 100644 --- a/drivers/block/rnbd/rnbd-srv.h +++ b/drivers/block/rnbd/rnbd-srv.h @@ -20,7 +20,7 @@ struct rnbd_srv_session { /* Entry inside global sess_list */ struct list_head list; - struct rtrs_srv_sess *rtrs; + struct rtrs_srv *rtrs; char sessname[NAME_MAX]; int queue_depth; struct bio_set sess_bio_set; diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 146d85d80e..4d4bb810c2 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -143,8 +143,8 @@ static int vdc_getgeo(struct block_device *bdev, struct hd_geometry *geo) static int vdc_ioctl(struct block_device *bdev, fmode_t mode, unsigned command, unsigned long argument) { - struct vdc_port *port = bdev->bd_disk->private_data; int i; + struct gendisk *disk; switch (command) { case CDROMMULTISESSION: @@ -155,15 +155,12 @@ static int vdc_ioctl(struct block_device *bdev, fmode_t mode, return 0; case CDROM_GET_CAPABILITY: - if (!vdc_version_supported(port, 1, 1)) - return -EINVAL; - switch (port->vdisk_mtype) { - case VD_MEDIA_TYPE_CD: - case VD_MEDIA_TYPE_DVD: + disk = bdev->bd_disk; + + if (bdev->bd_disk && (disk->flags & GENHD_FL_CD)) return 0; - default: - return -EINVAL; - } + return -EINVAL; + default: pr_debug(PFX "ioctl %08x not supported\n", command); return -EINVAL; @@ -462,7 +459,7 @@ static int __vdc_tx_trigger(struct vdc_port *port) static int __send_request(struct request *req) { - struct vdc_port *port = req->q->disk->private_data; + struct vdc_port *port = req->rq_disk->private_data; struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING]; struct scatterlist sg[MAX_RING_COOKIES]; struct vdc_req_entry *rqe; @@ -829,8 +826,8 @@ static int probe_disk(struct vdc_port *port) if (IS_ERR(g)) { printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n", port->vio.name); - err = PTR_ERR(g); - goto out_free_tag; + blk_mq_free_tag_set(&port->tag_set); + return PTR_ERR(g); } port->disk = g; @@ -857,12 +854,14 @@ static int probe_disk(struct vdc_port *port) switch (port->vdisk_mtype) { case VD_MEDIA_TYPE_CD: pr_info(PFX "Virtual CDROM %s\n", port->disk_name); + g->flags |= GENHD_FL_CD; g->flags |= GENHD_FL_REMOVABLE; set_disk_ro(g, 1); break; case VD_MEDIA_TYPE_DVD: pr_info(PFX "Virtual DVD %s\n", port->disk_name); + g->flags |= GENHD_FL_CD; g->flags |= GENHD_FL_REMOVABLE; set_disk_ro(g, 1); break; @@ -880,17 +879,9 @@ static int probe_disk(struct vdc_port *port) port->vdisk_size, (port->vdisk_size >> (20 - 9)), port->vio.ver.major, port->vio.ver.minor); - err = device_add_disk(&port->vio.vdev->dev, g, NULL); - if (err) - goto out_cleanup_disk; + device_add_disk(&port->vio.vdev->dev, g, NULL); return 0; - -out_cleanup_disk: - blk_cleanup_disk(g); -out_free_tag: - blk_mq_free_tag_set(&port->tag_set); - return err; } static struct ldc_channel_config vdc_ldc_cfg = { diff --git a/drivers/block/swim.c b/drivers/block/swim.c index fef65a18d5..7ccc8d2a41 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -185,7 +184,6 @@ struct floppy_state { int track; int ref_count; - bool registered; struct gendisk *disk; struct blk_mq_tag_set tag_set; @@ -773,20 +771,6 @@ static const struct blk_mq_ops swim_mq_ops = { .queue_rq = swim_queue_rq, }; -static void swim_cleanup_floppy_disk(struct floppy_state *fs) -{ - struct gendisk *disk = fs->disk; - - if (!disk) - return; - - if (fs->registered) - del_gendisk(fs->disk); - - blk_cleanup_disk(disk); - blk_mq_free_tag_set(&fs->tag_set); -} - static int swim_floppy_init(struct swim_priv *swd) { int err; @@ -840,14 +824,10 @@ static int swim_floppy_init(struct swim_priv *swd) swd->unit[drive].disk->minors = 1; sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); swd->unit[drive].disk->fops = &floppy_fops; - swd->unit[drive].disk->flags |= GENHD_FL_NO_PART; swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; swd->unit[drive].disk->private_data = &swd->unit[drive]; set_capacity(swd->unit[drive].disk, 2880); - err = add_disk(swd->unit[drive].disk); - if (err) - goto exit_put_disks; - swd->unit[drive].registered = true; + add_disk(swd->unit[drive].disk); } return 0; @@ -855,7 +835,12 @@ static int swim_floppy_init(struct swim_priv *swd) exit_put_disks: unregister_blkdev(FLOPPY_MAJOR, "fd"); do { - swim_cleanup_floppy_disk(&swd->unit[drive]); + struct gendisk *disk = swd->unit[drive].disk; + + if (!disk) + continue; + blk_cleanup_disk(disk); + blk_mq_free_tag_set(&swd->unit[drive].tag_set); } while (drive--); return err; } @@ -924,8 +909,12 @@ static int swim_remove(struct platform_device *dev) int drive; struct resource *res; - for (drive = 0; drive < swd->floppy_count; drive++) - swim_cleanup_floppy_disk(&swd->unit[drive]); + for (drive = 0; drive < swd->floppy_count; drive++) { + del_gendisk(swd->unit[drive].disk); + blk_cleanup_queue(swd->unit[drive].disk->queue); + blk_mq_free_tag_set(&swd->unit[drive].tag_set); + put_disk(swd->unit[drive].disk); + } unregister_blkdev(FLOPPY_MAJOR, "fd"); diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 6c39f2c9f8..965af0a3e9 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -1227,12 +1226,10 @@ static int swim3_attach(struct macio_dev *mdev, disk->fops = &floppy_fops; disk->private_data = fs; disk->events = DISK_EVENT_MEDIA_CHANGE; - disk->flags |= GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; + disk->flags |= GENHD_FL_REMOVABLE; sprintf(disk->disk_name, "fd%d", floppy_count); set_capacity(disk, 2880); - rc = add_disk(disk); - if (rc) - goto out_cleanup_disk; + add_disk(disk); disks[floppy_count++] = disk; return 0; diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index b361583944..420cd952dd 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -297,7 +297,6 @@ struct carm_host { struct work_struct fsm_task; - int probe_err; struct completion probe_comp; }; @@ -540,7 +539,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx) spin_unlock_irq(&host->lock); DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag); - blk_execute_rq_nowait(rq, true, NULL); + blk_execute_rq_nowait(NULL, rq, true, NULL); return 0; @@ -579,7 +578,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func) crq->msg_bucket = (u32) rc; DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag); - blk_execute_rq_nowait(rq, true, NULL); + blk_execute_rq_nowait(NULL, rq, true, NULL); return 0; } @@ -1182,11 +1181,8 @@ static void carm_fsm_task (struct work_struct *work) struct gendisk *disk = port->disk; set_capacity(disk, port->capacity); - host->probe_err = add_disk(disk); - if (!host->probe_err) - activated++; - else - break; + add_disk(disk); + activated++; } printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n", @@ -1196,9 +1192,11 @@ static void carm_fsm_task (struct work_struct *work) reschedule = 1; break; } + case HST_PROBE_FINISHED: complete(&host->probe_comp); break; + case HST_ERROR: /* FIXME: TODO */ break; @@ -1509,12 +1507,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_irq; DPRINTK("waiting for probe_comp\n"); - host->probe_err = -ENODEV; wait_for_completion(&host->probe_comp); - if (host->probe_err) { - rc = host->probe_err; - goto err_out_free_irq; - } printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n", host->name, pci_name(pdev), (int) CARM_MAX_PORTS, diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c443cd64fc..303caf2d17 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -24,19 +24,6 @@ /* The maximum number of sg elements that fit into a virtqueue */ #define VIRTIO_BLK_MAX_SG_ELEMS 32768 -#ifdef CONFIG_ARCH_NO_SG_CHAIN -#define VIRTIO_BLK_INLINE_SG_CNT 0 -#else -#define VIRTIO_BLK_INLINE_SG_CNT 2 -#endif - -static unsigned int num_request_queues; -module_param(num_request_queues, uint, 0644); -MODULE_PARM_DESC(num_request_queues, - "Limit the number of request queues to use for blk device. " - "0 for no limit. " - "Values > nr_cpu_ids truncated to nr_cpu_ids."); - static int major; static DEFINE_IDA(vd_index_ida); @@ -90,7 +77,6 @@ struct virtio_blk { struct virtblk_req { struct virtio_blk_outhdr out_hdr; u8 status; - struct sg_table sg_table; struct scatterlist sg[]; }; @@ -176,93 +162,12 @@ static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap) return 0; } -static void virtblk_unmap_data(struct request *req, struct virtblk_req *vbr) -{ - if (blk_rq_nr_phys_segments(req)) - sg_free_table_chained(&vbr->sg_table, - VIRTIO_BLK_INLINE_SG_CNT); -} - -static int virtblk_map_data(struct blk_mq_hw_ctx *hctx, struct request *req, - struct virtblk_req *vbr) -{ - int err; - - if (!blk_rq_nr_phys_segments(req)) - return 0; - - vbr->sg_table.sgl = vbr->sg; - err = sg_alloc_table_chained(&vbr->sg_table, - blk_rq_nr_phys_segments(req), - vbr->sg_table.sgl, - VIRTIO_BLK_INLINE_SG_CNT); - if (unlikely(err)) - return -ENOMEM; - - return blk_rq_map_sg(hctx->queue, req, vbr->sg_table.sgl); -} - -static void virtblk_cleanup_cmd(struct request *req) -{ - if (req->rq_flags & RQF_SPECIAL_PAYLOAD) - kfree(bvec_virt(&req->special_vec)); -} - -static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev, - struct request *req, - struct virtblk_req *vbr) -{ - bool unmap = false; - u32 type; - - vbr->out_hdr.sector = 0; - - switch (req_op(req)) { - case REQ_OP_READ: - type = VIRTIO_BLK_T_IN; - vbr->out_hdr.sector = cpu_to_virtio64(vdev, - blk_rq_pos(req)); - break; - case REQ_OP_WRITE: - type = VIRTIO_BLK_T_OUT; - vbr->out_hdr.sector = cpu_to_virtio64(vdev, - blk_rq_pos(req)); - break; - case REQ_OP_FLUSH: - type = VIRTIO_BLK_T_FLUSH; - break; - case REQ_OP_DISCARD: - type = VIRTIO_BLK_T_DISCARD; - break; - case REQ_OP_WRITE_ZEROES: - type = VIRTIO_BLK_T_WRITE_ZEROES; - unmap = !(req->cmd_flags & REQ_NOUNMAP); - break; - case REQ_OP_DRV_IN: - type = VIRTIO_BLK_T_GET_ID; - break; - default: - WARN_ON_ONCE(1); - return BLK_STS_IOERR; - } - - vbr->out_hdr.type = cpu_to_virtio32(vdev, type); - vbr->out_hdr.ioprio = cpu_to_virtio32(vdev, req_get_ioprio(req)); - - if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) { - if (virtblk_setup_discard_write_zeroes(req, unmap)) - return BLK_STS_RESOURCE; - } - - return 0; -} - static inline void virtblk_request_done(struct request *req) { struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); - virtblk_unmap_data(req, vbr); - virtblk_cleanup_cmd(req); + if (req->rq_flags & RQF_SPECIAL_PAYLOAD) + kfree(bvec_virt(&req->special_vec)); blk_mq_end_request(req, virtblk_result(vbr)); } @@ -316,28 +221,61 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req = bd->rq; struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); unsigned long flags; - int num; + unsigned int num; int qid = hctx->queue_num; - bool notify = false; - blk_status_t status; int err; + bool notify = false; + bool unmap = false; + u32 type; BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); - status = virtblk_setup_cmd(vblk->vdev, req, vbr); - if (unlikely(status)) - return status; + switch (req_op(req)) { + case REQ_OP_READ: + case REQ_OP_WRITE: + type = 0; + break; + case REQ_OP_FLUSH: + type = VIRTIO_BLK_T_FLUSH; + break; + case REQ_OP_DISCARD: + type = VIRTIO_BLK_T_DISCARD; + break; + case REQ_OP_WRITE_ZEROES: + type = VIRTIO_BLK_T_WRITE_ZEROES; + unmap = !(req->cmd_flags & REQ_NOUNMAP); + break; + case REQ_OP_DRV_IN: + type = VIRTIO_BLK_T_GET_ID; + break; + default: + WARN_ON_ONCE(1); + return BLK_STS_IOERR; + } + + vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, type); + vbr->out_hdr.sector = type ? + 0 : cpu_to_virtio64(vblk->vdev, blk_rq_pos(req)); + vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(req)); blk_mq_start_request(req); - num = virtblk_map_data(hctx, req, vbr); - if (unlikely(num < 0)) { - virtblk_cleanup_cmd(req); - return BLK_STS_RESOURCE; + if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) { + err = virtblk_setup_discard_write_zeroes(req, unmap); + if (err) + return BLK_STS_RESOURCE; + } + + num = blk_rq_map_sg(hctx->queue, req, vbr->sg); + if (num) { + if (rq_data_dir(req) == WRITE) + vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_OUT); + else + vbr->out_hdr.type |= cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_IN); } spin_lock_irqsave(&vblk->vqs[qid].lock, flags); - err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg_table.sgl, num); + err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); if (err) { virtqueue_kick(vblk->vqs[qid].vq); /* Don't stop the queue if -ENOMEM: we may have failed to @@ -346,8 +284,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, if (err == -ENOSPC) blk_mq_stop_hw_queue(hctx); spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); - virtblk_unmap_data(req, vbr); - virtblk_cleanup_cmd(req); switch (err) { case -ENOSPC: return BLK_STS_DEV_RESOURCE; @@ -376,7 +312,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) struct request *req; int err; - req = blk_mq_alloc_request(q, REQ_OP_DRV_IN, 0); + req = blk_get_request(q, REQ_OP_DRV_IN, 0); if (IS_ERR(req)) return PTR_ERR(req); @@ -384,10 +320,10 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) if (err) goto out; - blk_execute_rq(req, false); + blk_execute_rq(vblk->disk, req, false); err = blk_status_to_errno(virtblk_result(blk_mq_rq_to_pdu(req))); out: - blk_mq_free_request(req); + blk_put_request(req); return err; } @@ -561,14 +497,8 @@ static int init_vq(struct virtio_blk *vblk) &num_vqs); if (err) num_vqs = 1; - if (!err && !num_vqs) { - dev_err(&vdev->dev, "MQ advertised but zero queues reported\n"); - return -EINVAL; - } - num_vqs = min_t(unsigned int, - min_not_zero(num_request_queues, nr_cpu_ids), - num_vqs); + num_vqs = min_t(unsigned int, nr_cpu_ids, num_vqs); vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); if (!vblk->vqs) @@ -694,7 +624,7 @@ cache_type_show(struct device *dev, struct device_attribute *attr, char *buf) u8 writeback = virtblk_get_cache_mode(vblk->vdev); BUG_ON(writeback >= ARRAY_SIZE(virtblk_cache_types)); - return sysfs_emit(buf, "%s\n", virtblk_cache_types[writeback]); + return snprintf(buf, 40, "%s\n", virtblk_cache_types[writeback]); } static DEVICE_ATTR_RW(cache_type); @@ -730,6 +660,16 @@ static const struct attribute_group *virtblk_attr_groups[] = { NULL, }; +static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq, + unsigned int hctx_idx, unsigned int numa_node) +{ + struct virtio_blk *vblk = set->driver_data; + struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq); + + sg_init_table(vbr->sg, vblk->sg_elems); + return 0; +} + static int virtblk_map_queues(struct blk_mq_tag_set *set) { struct virtio_blk *vblk = set->driver_data; @@ -742,6 +682,7 @@ static const struct blk_mq_ops virtio_mq_ops = { .queue_rq = virtio_queue_rq, .commit_rqs = virtio_commit_rqs, .complete = virtblk_request_done, + .init_request = virtblk_init_request, .map_queues = virtblk_map_queues, }; @@ -821,7 +762,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; vblk->tag_set.cmd_size = sizeof(struct virtblk_req) + - sizeof(struct scatterlist) * VIRTIO_BLK_INLINE_SG_CNT; + sizeof(struct scatterlist) * sg_elems; vblk->tag_set.driver_data = vblk; vblk->tag_set.nr_hw_queues = vblk->num_vqs; @@ -843,6 +784,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->disk->minors = 1 << PART_BITS; vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + vblk->disk->flags |= GENHD_FL_EXT_DEVT; vblk->index = index; /* configure queue flush support */ @@ -873,17 +815,9 @@ static int virtblk_probe(struct virtio_device *vdev) err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE, struct virtio_blk_config, blk_size, &blk_size); - if (!err) { - err = blk_validate_block_size(blk_size); - if (err) { - dev_err(&vdev->dev, - "virtio_blk: invalid block size: 0x%x\n", - blk_size); - goto out_cleanup_disk; - } - + if (!err) blk_queue_logical_block_size(q, blk_size); - } else + else blk_size = queue_logical_block_size(q); /* Use topology information if available */ @@ -976,7 +910,7 @@ static void virtblk_remove(struct virtio_device *vdev) mutex_lock(&vblk->vdev_mutex); /* Stop all the virtqueues. */ - virtio_reset_device(vdev); + vdev->config->reset(vdev); /* Virtqueues are stopped, nothing can use vblk->vdev anymore. */ vblk->vdev = NULL; @@ -995,7 +929,7 @@ static int virtblk_freeze(struct virtio_device *vdev) struct virtio_blk *vblk = vdev->priv; /* Ensure we don't receive any more interrupts */ - virtio_reset_device(vdev); + vdev->config->reset(vdev); /* Make sure no work handler is accessing the device. */ flush_work(&vblk->config_work); diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 62125fd4af..33eba3df4d 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -98,7 +98,7 @@ static void xen_update_blkif_status(struct xen_blkif *blkif) return; } - err = sync_blockdev(blkif->vbd.bdev); + err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping); if (err) { xenbus_dev_error(blkif->be->dev, err, "block flush"); return; @@ -510,7 +510,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, } vbd->size = vbd_sz(vbd); - if (cdrom || disk_to_cdi(vbd->bdev->bd_disk)) + if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) vbd->type |= VDISK_CDROM; if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) vbd->type |= VDISK_REMOVABLE; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ca71a05853..1becbbb3be 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -198,7 +197,6 @@ struct blkfront_info struct gendisk *gd; u16 sector_size; unsigned int physical_sector_size; - unsigned long vdisk_info; int vdevice; blkif_vdev_t handle; enum blkif_state connected; @@ -506,7 +504,6 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) static int blkif_ioctl(struct block_device *bdev, fmode_t mode, unsigned command, unsigned long argument) { - struct blkfront_info *info = bdev->bd_disk->private_data; int i; switch (command) { @@ -516,9 +513,9 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode, return -EFAULT; return 0; case CDROM_GET_CAPABILITY: - if (!(info->vdisk_info & VDISK_CDROM)) - return -EINVAL; - return 0; + if (bdev->bd_disk->flags & GENHD_FL_CD) + return 0; + return -EINVAL; default: return -EINVAL; } @@ -1059,8 +1056,9 @@ static char *encode_disk_name(char *ptr, unsigned int n) } static int xlvbd_alloc_gendisk(blkif_sector_t capacity, - struct blkfront_info *info, u16 sector_size, - unsigned int physical_sector_size) + struct blkfront_info *info, + u16 vdisk_info, u16 sector_size, + unsigned int physical_sector_size) { struct gendisk *gd; int nr_minors = 1; @@ -1158,11 +1156,15 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, xlvbd_flush(info); - if (info->vdisk_info & VDISK_READONLY) + if (vdisk_info & VDISK_READONLY) set_disk_ro(gd, 1); - if (info->vdisk_info & VDISK_REMOVABLE) + + if (vdisk_info & VDISK_REMOVABLE) gd->flags |= GENHD_FL_REMOVABLE; + if (vdisk_info & VDISK_CDROM) + gd->flags |= GENHD_FL_CD; + return 0; out_free_tag_set: @@ -1288,7 +1290,8 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) rinfo->ring_ref[i] = GRANT_INVALID_REF; } } - free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE)); + free_pages_exact(rinfo->ring.sring, + info->nr_ring_pages * XEN_PAGE_SIZE); rinfo->ring.sring = NULL; if (rinfo->irq) @@ -1372,9 +1375,15 @@ static int blkif_get_final_status(enum blk_req_status s1, return BLKIF_RSP_OKAY; } -static bool blkif_completion(unsigned long *id, - struct blkfront_ring_info *rinfo, - struct blkif_response *bret) +/* + * Return values: + * 1 response processed. + * 0 missing further responses. + * -1 error while processing. + */ +static int blkif_completion(unsigned long *id, + struct blkfront_ring_info *rinfo, + struct blkif_response *bret) { int i = 0; struct scatterlist *sg; @@ -1397,7 +1406,7 @@ static bool blkif_completion(unsigned long *id, /* Wait the second response if not yet here. */ if (s2->status < REQ_DONE) - return false; + return 0; bret->status = blkif_get_final_status(s->status, s2->status); @@ -1448,42 +1457,43 @@ static bool blkif_completion(unsigned long *id, } /* Add the persistent grant into the list of free grants */ for (i = 0; i < num_grant; i++) { - if (gnttab_query_foreign_access(s->grants_used[i]->gref)) { + if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) { /* * If the grant is still mapped by the backend (the * backend has chosen to make this grant persistent) * we add it at the head of the list, so it will be * reused first. */ - if (!info->feature_persistent) - pr_alert_ratelimited("backed has not unmapped grant: %u\n", - s->grants_used[i]->gref); + if (!info->feature_persistent) { + pr_alert("backed has not unmapped grant: %u\n", + s->grants_used[i]->gref); + return -1; + } list_add(&s->grants_used[i]->node, &rinfo->grants); rinfo->persistent_gnts_c++; } else { /* - * If the grant is not mapped by the backend we end the - * foreign access and add it to the tail of the list, - * so it will not be picked again unless we run out of - * persistent grants. + * If the grant is not mapped by the backend we add it + * to the tail of the list, so it will not be picked + * again unless we run out of persistent grants. */ - gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL); s->grants_used[i]->gref = GRANT_INVALID_REF; list_add_tail(&s->grants_used[i]->node, &rinfo->grants); } } if (s->req.operation == BLKIF_OP_INDIRECT) { for (i = 0; i < INDIRECT_GREFS(num_grant); i++) { - if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) { - if (!info->feature_persistent) - pr_alert_ratelimited("backed has not unmapped grant: %u\n", - s->indirect_grants[i]->gref); + if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) { + if (!info->feature_persistent) { + pr_alert("backed has not unmapped grant: %u\n", + s->indirect_grants[i]->gref); + return -1; + } list_add(&s->indirect_grants[i]->node, &rinfo->grants); rinfo->persistent_gnts_c++; } else { struct page *indirect_page; - gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL); /* * Add the used indirect page back to the list of * available pages for indirect grefs. @@ -1498,7 +1508,7 @@ static bool blkif_completion(unsigned long *id, } } - return true; + return 1; } static irqreturn_t blkif_interrupt(int irq, void *dev_id) @@ -1564,12 +1574,17 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) } if (bret.operation != BLKIF_OP_DISCARD) { + int ret; + /* * We may need to wait for an extra response if the * I/O request is split in 2 */ - if (!blkif_completion(&id, rinfo, &bret)) + ret = blkif_completion(&id, rinfo, &bret); + if (!ret) continue; + if (unlikely(ret < 0)) + goto err; } if (add_id_to_freelist(rinfo, id)) { @@ -1676,8 +1691,7 @@ static int setup_blkring(struct xenbus_device *dev, for (i = 0; i < info->nr_ring_pages; i++) rinfo->ring_ref[i] = GRANT_INVALID_REF; - sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH, - get_order(ring_size)); + sring = alloc_pages_exact(ring_size, GFP_NOIO); if (!sring) { xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); return -ENOMEM; @@ -1687,7 +1701,7 @@ static int setup_blkring(struct xenbus_device *dev, err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref); if (err < 0) { - free_pages((unsigned long)sring, get_order(ring_size)); + free_pages_exact(sring, ring_size); rinfo->ring.sring = NULL; goto fail; } @@ -2310,6 +2324,7 @@ static void blkfront_connect(struct blkfront_info *info) unsigned long long sectors; unsigned long sector_size; unsigned int physical_sector_size; + unsigned int binfo; int err, i; struct blkfront_ring_info *rinfo; @@ -2347,7 +2362,7 @@ static void blkfront_connect(struct blkfront_info *info) err = xenbus_gather(XBT_NIL, info->xbdev->otherend, "sectors", "%llu", §ors, - "info", "%u", &info->vdisk_info, + "info", "%u", &binfo, "sector-size", "%lu", §or_size, NULL); if (err) { @@ -2376,7 +2391,7 @@ static void blkfront_connect(struct blkfront_info *info) } } - err = xlvbd_alloc_gendisk(sectors, info, sector_size, + err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size, physical_sector_size); if (err) { xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", @@ -2391,13 +2406,7 @@ static void blkfront_connect(struct blkfront_info *info) for_each_rinfo(info, rinfo, i) kick_pending_request_queues(rinfo); - err = device_add_disk(&info->xbdev->dev, info->gd, NULL); - if (err) { - blk_cleanup_disk(info->gd); - blk_mq_free_tag_set(&info->tag_set); - info->rq = NULL; - goto fail; - } + device_add_disk(&info->xbdev->dev, info->gd, NULL); info->is_ready = 1; return; @@ -2532,11 +2541,10 @@ static void purge_persistent_grants(struct blkfront_info *info) list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants, node) { if (gnt_list_entry->gref == GRANT_INVALID_REF || - gnttab_query_foreign_access(gnt_list_entry->gref)) + !gnttab_try_end_foreign_access(gnt_list_entry->gref)) continue; list_del(&gnt_list_entry->node); - gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL); rinfo->persistent_gnts_c--; gnt_list_entry->gref = GRANT_INVALID_REF; list_add_tail(&gnt_list_entry->node, &rinfo->grants); diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 7a6ed83481..4eef218108 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -318,7 +318,6 @@ static const struct blk_mq_ops z2_mq_ops = { static int z2ram_register_disk(int minor) { struct gendisk *disk; - int err; disk = blk_mq_alloc_disk(&tag_set, NULL); if (IS_ERR(disk)) @@ -327,7 +326,6 @@ static int z2ram_register_disk(int minor) disk->major = Z2RAM_MAJOR; disk->first_minor = minor; disk->minors = 1; - disk->flags |= GENHD_FL_NO_PART; disk->fops = &z2_fops; if (minor) sprintf(disk->disk_name, "z2ram%d", minor); @@ -335,10 +333,8 @@ static int z2ram_register_disk(int minor) sprintf(disk->disk_name, "z2ram"); z2ram_gendisk[minor] = disk; - err = add_disk(disk); - if (err) - blk_cleanup_disk(disk); - return err; + add_disk(disk); + return 0; } static int __init z2_init(void) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index cb253d80d7..6383c81ac5 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -291,16 +291,22 @@ static ssize_t mem_used_max_store(struct device *dev, return len; } -/* - * Mark all pages which are older than or equal to cutoff as IDLE. - * Callers should hold the zram init lock in read mode - */ -static void mark_idle(struct zram *zram, ktime_t cutoff) +static ssize_t idle_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) { - int is_idle = 1; + struct zram *zram = dev_to_zram(dev); unsigned long nr_pages = zram->disksize >> PAGE_SHIFT; int index; + if (!sysfs_streq(buf, "all")) + return -EINVAL; + + down_read(&zram->init_lock); + if (!init_done(zram)) { + up_read(&zram->init_lock); + return -EINVAL; + } + for (index = 0; index < nr_pages; index++) { /* * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race. @@ -308,50 +314,14 @@ static void mark_idle(struct zram *zram, ktime_t cutoff) */ zram_slot_lock(zram, index); if (zram_allocated(zram, index) && - !zram_test_flag(zram, index, ZRAM_UNDER_WB)) { -#ifdef CONFIG_ZRAM_MEMORY_TRACKING - is_idle = !cutoff || ktime_after(cutoff, zram->table[index].ac_time); -#endif - if (is_idle) - zram_set_flag(zram, index, ZRAM_IDLE); - } + !zram_test_flag(zram, index, ZRAM_UNDER_WB)) + zram_set_flag(zram, index, ZRAM_IDLE); zram_slot_unlock(zram, index); } -} -static ssize_t idle_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t len) -{ - struct zram *zram = dev_to_zram(dev); - ktime_t cutoff_time = 0; - ssize_t rv = -EINVAL; - - if (!sysfs_streq(buf, "all")) { - /* - * If it did not parse as 'all' try to treat it as an integer when - * we have memory tracking enabled. - */ - u64 age_sec; - - if (IS_ENABLED(CONFIG_ZRAM_MEMORY_TRACKING) && !kstrtoull(buf, 0, &age_sec)) - cutoff_time = ktime_sub(ktime_get_boottime(), - ns_to_ktime(age_sec * NSEC_PER_SEC)); - else - goto out; - } - - down_read(&zram->init_lock); - if (!init_done(zram)) - goto out_unlock; - - /* A cutoff_time of 0 marks everything as idle, this is the "all" behavior */ - mark_idle(zram, cutoff_time); - rv = len; - -out_unlock: up_read(&zram->init_lock); -out: - return rv; + + return len; } #ifdef CONFIG_ZRAM_WRITEBACK @@ -617,7 +587,7 @@ static int read_from_bdev_async(struct zram *zram, struct bio_vec *bvec, { struct bio *bio; - bio = bio_alloc(GFP_NOIO, 1); + bio = bio_alloc(GFP_ATOMIC, 1); if (!bio) return -ENOMEM; @@ -1628,18 +1598,22 @@ static void __zram_make_request(struct zram *zram, struct bio *bio) /* * Handler function for all zram I/O requests. */ -static void zram_submit_bio(struct bio *bio) +static blk_qc_t zram_submit_bio(struct bio *bio) { struct zram *zram = bio->bi_bdev->bd_disk->private_data; if (!valid_io_request(zram, bio->bi_iter.bi_sector, bio->bi_iter.bi_size)) { atomic64_inc(&zram->stats.invalid_io); - bio_io_error(bio); - return; + goto error; } __zram_make_request(zram, bio); + return BLK_QC_T_NONE; + +error: + bio_io_error(bio); + return BLK_QC_T_NONE; } static void zram_slot_free_notify(struct block_device *bdev, @@ -1734,13 +1708,12 @@ static void zram_reset_device(struct zram *zram) set_capacity_and_notify(zram->disk, 0); part_stat_set_all(zram->disk->part0, 0); + up_write(&zram->init_lock); /* I/O operation under all of CPU are done so let's free */ zram_meta_free(zram, disksize); memset(&zram->stats, 0, sizeof(zram->stats)); zcomp_destroy(comp); reset_bdev(zram); - - up_write(&zram->init_lock); } static ssize_t disksize_store(struct device *dev, @@ -1820,7 +1793,7 @@ static ssize_t reset_store(struct device *dev, mutex_unlock(&bdev->bd_disk->open_mutex); /* Make sure all the pending I/O are finished */ - sync_blockdev(bdev); + fsync_bdev(bdev); zram_reset_device(zram); mutex_lock(&bdev->bd_disk->open_mutex); @@ -1853,14 +1826,12 @@ static const struct block_device_operations zram_devops = { .owner = THIS_MODULE }; -#ifdef CONFIG_ZRAM_WRITEBACK static const struct block_device_operations zram_wb_devops = { .open = zram_open, .submit_bio = zram_submit_bio, .swap_slot_free_notify = zram_slot_free_notify, .owner = THIS_MODULE }; -#endif static DEVICE_ATTR_WO(compact); static DEVICE_ATTR_RW(disksize); @@ -1903,7 +1874,14 @@ static struct attribute *zram_disk_attrs[] = { NULL, }; -ATTRIBUTE_GROUPS(zram_disk); +static const struct attribute_group zram_disk_attr_group = { + .attrs = zram_disk_attrs, +}; + +static const struct attribute_group *zram_disk_attr_groups[] = { + &zram_disk_attr_group, + NULL, +}; /* * Allocate and initialize new zram device. the function returns @@ -1940,7 +1918,6 @@ static int zram_add(void) zram->disk->major = zram_major; zram->disk->first_minor = device_id; zram->disk->minors = 1; - zram->disk->flags |= GENHD_FL_NO_PART; zram->disk->fops = &zram_devops; zram->disk->private_data = zram; snprintf(zram->disk->disk_name, 16, "zram%d", device_id); @@ -1976,9 +1953,7 @@ static int zram_add(void) blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX); blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, zram->disk->queue); - ret = device_add_disk(NULL, zram->disk, zram_disk_groups); - if (ret) - goto out_cleanup_disk; + device_add_disk(NULL, zram->disk, zram_disk_attr_groups); strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); @@ -1986,8 +1961,6 @@ static int zram_add(void) pr_info("Added device: %s\n", zram->disk->disk_name); return device_id; -out_cleanup_disk: - blk_cleanup_disk(zram->disk); out_free_idr: idr_remove(&zram_index_idr, device_id); out_free_dev: @@ -1998,47 +1971,25 @@ static int zram_add(void) static int zram_remove(struct zram *zram) { struct block_device *bdev = zram->disk->part0; - bool claimed; mutex_lock(&bdev->bd_disk->open_mutex); - if (bdev->bd_openers) { + if (bdev->bd_openers || zram->claim) { mutex_unlock(&bdev->bd_disk->open_mutex); return -EBUSY; } - claimed = zram->claim; - if (!claimed) - zram->claim = true; + zram->claim = true; mutex_unlock(&bdev->bd_disk->open_mutex); zram_debugfs_unregister(zram); - if (claimed) { - /* - * If we were claimed by reset_store(), del_gendisk() will - * wait until reset_store() is done, so nothing need to do. - */ - ; - } else { - /* Make sure all the pending I/O are finished */ - sync_blockdev(bdev); - zram_reset_device(zram); - } + /* Make sure all the pending I/O are finished */ + fsync_bdev(bdev); + zram_reset_device(zram); pr_info("Removed device: %s\n", zram->disk->disk_name); del_gendisk(zram->disk); - - /* del_gendisk drains pending reset_store */ - WARN_ON_ONCE(claimed && zram->claim); - - /* - * disksize_store() may be called in between zram_reset_device() - * and del_gendisk(), so run the last reset to avoid leaking - * anything allocated with disksize_store() - */ - zram_reset_device(zram); - blk_cleanup_disk(zram->disk); kfree(zram); return 0; @@ -2115,7 +2066,7 @@ static struct class zram_control_class = { static int zram_remove_cb(int id, void *ptr, void *data) { - WARN_ON_ONCE(zram_remove(ptr)); + zram_remove(ptr); return 0; } diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 36380e618b..851842372c 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -19,10 +19,6 @@ config BT_QCA tristate select FW_LOADER -config BT_MTK - tristate - select FW_LOADER - config BT_HCIBTUSB tristate "HCI USB driver" depends on USB @@ -59,7 +55,6 @@ config BT_HCIBTUSB_BCM config BT_HCIBTUSB_MTK bool "MediaTek protocol support" depends on BT_HCIBTUSB - select BT_MTK default n help The MediaTek protocol support enables firmware download @@ -388,7 +383,6 @@ config BT_ATH3K config BT_MTKSDIO tristate "MediaTek HCI SDIO driver" depends on MMC - select BT_MTK help MediaTek Bluetooth HCI SDIO driver. This driver is required if you want to use MediaTek Bluetooth diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 3321a8aea4..16286ea265 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_BT_QCOMSMD) += btqcomsmd.o obj-$(CONFIG_BT_BCM) += btbcm.o obj-$(CONFIG_BT_RTL) += btrtl.o obj-$(CONFIG_BT_QCA) += btqca.o -obj-$(CONFIG_BT_MTK) += btmtk.o obj-$(CONFIG_BT_VIRTIO) += virtio_bt.o diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 1a4f8b227e..e73d4c719b 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -1037,9 +1037,8 @@ static bool btintel_firmware_version(struct hci_dev *hdev, params = (void *)(fw_ptr + sizeof(*cmd)); - *boot_addr = le32_to_cpu(params->boot_addr); - - bt_dev_info(hdev, "Boot Address: 0x%x", *boot_addr); + bt_dev_info(hdev, "Boot Address: 0x%x", + le32_to_cpu(params->boot_addr)); bt_dev_info(hdev, "Firmware Version: %u-%u.%u", params->fw_build_num, params->fw_build_ww, @@ -1072,6 +1071,9 @@ int btintel_download_firmware(struct hci_dev *hdev, /* Skip version checking */ break; default: + /* Skip reading firmware file version in bootloader mode */ + if (ver->fw_variant == 0x06) + break; /* Skip download if firmware has the same version */ if (btintel_firmware_version(hdev, ver->fw_build_num, @@ -1112,16 +1114,19 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev, int err; u32 css_header_ver; - /* Skip download if firmware has the same version */ - if (btintel_firmware_version(hdev, ver->min_fw_build_nn, - ver->min_fw_build_cw, - ver->min_fw_build_yy, - fw, boot_param)) { - bt_dev_info(hdev, "Firmware already loaded"); - /* Return -EALREADY to indicate that firmware has - * already been loaded. - */ - return -EALREADY; + /* Skip reading firmware file version in bootloader mode */ + if (ver->img_type != 0x01) { + /* Skip download if firmware has the same version */ + if (btintel_firmware_version(hdev, ver->min_fw_build_nn, + ver->min_fw_build_cw, + ver->min_fw_build_yy, + fw, boot_param)) { + bt_dev_info(hdev, "Firmware already loaded"); + /* Return -EALREADY to indicate that firmware has + * already been loaded. + */ + return -EALREADY; + } } /* The firmware variant determines if the device is in bootloader @@ -1280,16 +1285,12 @@ static int btintel_read_debug_features(struct hci_dev *hdev, static int btintel_set_debug_features(struct hci_dev *hdev, const struct intel_debug_features *features) { - u8 mask[11] = { 0x0a, 0x92, 0x02, 0x7f, 0x00, 0x00, 0x00, 0x00, + u8 mask[11] = { 0x0a, 0x92, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 period[5] = { 0x04, 0x91, 0x02, 0x05, 0x00 }; - u8 trace_enable = 0x02; struct sk_buff *skb; - if (!features) { - bt_dev_warn(hdev, "Debug features not read"); + if (!features) return -EINVAL; - } if (!(features->page1[0] & 0x3f)) { bt_dev_info(hdev, "Telemetry exception format not supported"); @@ -1302,95 +1303,11 @@ static int btintel_set_debug_features(struct hci_dev *hdev, PTR_ERR(skb)); return PTR_ERR(skb); } + kfree_skb(skb); - - skb = __hci_cmd_sync(hdev, 0xfc8b, 5, period, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - bt_dev_err(hdev, "Setting periodicity for link statistics traces failed (%ld)", - PTR_ERR(skb)); - return PTR_ERR(skb); - } - kfree_skb(skb); - - skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - bt_dev_err(hdev, "Enable tracing of link statistics events failed (%ld)", - PTR_ERR(skb)); - return PTR_ERR(skb); - } - kfree_skb(skb); - - bt_dev_info(hdev, "set debug features: trace_enable 0x%02x mask 0x%02x", - trace_enable, mask[3]); - return 0; } -static int btintel_reset_debug_features(struct hci_dev *hdev, - const struct intel_debug_features *features) -{ - u8 mask[11] = { 0x0a, 0x92, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - u8 trace_enable = 0x00; - struct sk_buff *skb; - - if (!features) { - bt_dev_warn(hdev, "Debug features not read"); - return -EINVAL; - } - - if (!(features->page1[0] & 0x3f)) { - bt_dev_info(hdev, "Telemetry exception format not supported"); - return 0; - } - - /* Should stop the trace before writing ddc event mask. */ - skb = __hci_cmd_sync(hdev, 0xfca1, 1, &trace_enable, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - bt_dev_err(hdev, "Stop tracing of link statistics events failed (%ld)", - PTR_ERR(skb)); - return PTR_ERR(skb); - } - kfree_skb(skb); - - skb = __hci_cmd_sync(hdev, 0xfc8b, 11, mask, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - bt_dev_err(hdev, "Setting Intel telemetry ddc write event mask failed (%ld)", - PTR_ERR(skb)); - return PTR_ERR(skb); - } - kfree_skb(skb); - - bt_dev_info(hdev, "reset debug features: trace_enable 0x%02x mask 0x%02x", - trace_enable, mask[3]); - - return 0; -} - -int btintel_set_quality_report(struct hci_dev *hdev, bool enable) -{ - struct intel_debug_features features; - int err; - - bt_dev_dbg(hdev, "enable %d", enable); - - /* Read the Intel supported features and if new exception formats - * supported, need to load the additional DDC config to enable. - */ - err = btintel_read_debug_features(hdev, &features); - if (err) - return err; - - /* Set or reset the debug features. */ - if (enable) - err = btintel_set_debug_features(hdev, &features); - else - err = btintel_reset_debug_features(hdev, &features); - - return err; -} -EXPORT_SYMBOL_GPL(btintel_set_quality_report); - static const struct firmware *btintel_legacy_rom_get_fw(struct hci_dev *hdev, struct intel_version *ver) { @@ -1976,6 +1893,7 @@ static int btintel_bootloader_setup(struct hci_dev *hdev, u32 boot_param; char ddcname[64]; int err; + struct intel_debug_features features; BT_DBG("%s", hdev->name); @@ -2016,7 +1934,14 @@ static int btintel_bootloader_setup(struct hci_dev *hdev, btintel_load_ddc_config(hdev, ddcname); } - hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); + /* Read the Intel supported features and if new exception formats + * supported, need to load the additional DDC config to enable. + */ + err = btintel_read_debug_features(hdev, &features); + if (!err) { + /* Set DDC mask for available debug features */ + btintel_set_debug_features(hdev, &features); + } /* Read the Intel version information after loading the FW */ err = btintel_read_version(hdev, &new_ver); @@ -2081,16 +2006,14 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev, if (ver->img_type == 0x03) { btintel_clear_flag(hdev, INTEL_BOOTLOADER); btintel_check_bdaddr(hdev); - } else { - /* - * Check for valid bd address in boot loader mode. Device - * will be marked as unconfigured if empty bd address is - * found. - */ - if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) { - bt_dev_info(hdev, "No device address configured"); - set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); - } + } + + /* If the OTP has no valid Bluetooth device address, then there will + * also be no valid address for the operational firmware. + */ + if (!bacmp(&ver->otp_bd_addr, BDADDR_ANY)) { + bt_dev_info(hdev, "No device address configured"); + set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); } btintel_get_fw_name_tlv(ver, fwname, sizeof(fwname), "sfi"); @@ -2160,102 +2083,13 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev, return err; } -static int btintel_get_codec_config_data(struct hci_dev *hdev, - __u8 link, struct bt_codec *codec, - __u8 *ven_len, __u8 **ven_data) -{ - int err = 0; - - if (!ven_data || !ven_len) - return -EINVAL; - - *ven_len = 0; - *ven_data = NULL; - - if (link != ESCO_LINK) { - bt_dev_err(hdev, "Invalid link type(%u)", link); - return -EINVAL; - } - - *ven_data = kmalloc(sizeof(__u8), GFP_KERNEL); - if (!*ven_data) { - err = -ENOMEM; - goto error; - } - - /* supports only CVSD and mSBC offload codecs */ - switch (codec->id) { - case 0x02: - **ven_data = 0x00; - break; - case 0x05: - **ven_data = 0x01; - break; - default: - err = -EINVAL; - bt_dev_err(hdev, "Invalid codec id(%u)", codec->id); - goto error; - } - /* codec and its capabilities are pre-defined to ids - * preset id = 0x00 represents CVSD codec with sampling rate 8K - * preset id = 0x01 represents mSBC codec with sampling rate 16K - */ - *ven_len = sizeof(__u8); - return err; - -error: - kfree(*ven_data); - *ven_data = NULL; - return err; -} - -static int btintel_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id) -{ - /* Intel uses 1 as data path id for all the usecases */ - *data_path_id = 1; - return 0; -} - -static int btintel_configure_offload(struct hci_dev *hdev) -{ - struct sk_buff *skb; - int err = 0; - struct intel_offload_use_cases *use_cases; - - skb = __hci_cmd_sync(hdev, 0xfc86, 0, NULL, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - bt_dev_err(hdev, "Reading offload use cases failed (%ld)", - PTR_ERR(skb)); - return PTR_ERR(skb); - } - - if (skb->len < sizeof(*use_cases)) { - err = -EIO; - goto error; - } - - use_cases = (void *)skb->data; - - if (use_cases->status) { - err = -bt_to_errno(skb->data[0]); - goto error; - } - - if (use_cases->preset[0] & 0x03) { - hdev->get_data_path_id = btintel_get_data_path_id; - hdev->get_codec_config_data = btintel_get_codec_config_data; - } -error: - kfree_skb(skb); - return err; -} - static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, struct intel_version_tlv *ver) { u32 boot_param; char ddcname[64]; int err; + struct intel_debug_features features; struct intel_version_tlv new_ver; bt_dev_dbg(hdev, ""); @@ -2291,10 +2125,14 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, */ btintel_load_ddc_config(hdev, ddcname); - /* Read supported use cases and set callbacks to fetch datapath id */ - btintel_configure_offload(hdev); - - hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT); + /* Read the Intel supported features and if new exception formats + * supported, need to load the additional DDC config to enable. + */ + err = btintel_read_debug_features(hdev, &features); + if (!err) { + /* Set DDC mask for available debug features */ + btintel_set_debug_features(hdev, &features); + } /* Read the Intel version information after loading the FW */ err = btintel_read_version_tlv(hdev, &new_ver); @@ -2401,9 +2239,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); - /* Set up the quality report callback for Intel devices */ - hdev->set_quality_report = btintel_set_quality_report; - /* For Legacy device, check the HW platform value and size */ if (skb->len == sizeof(ver) && skb->data[1] == 0x37) { bt_dev_dbg(hdev, "Read the legacy Intel version information"); @@ -2469,10 +2304,6 @@ static int btintel_setup_combined(struct hci_dev *hdev) goto exit_error; } - /* memset ver_tlv to start with clean state as few fields are exclusive - * to bootloader mode and are not populated in operational mode - */ - memset(&ver_tlv, 0, sizeof(ver_tlv)); /* For TLV type device, parse the tlv data */ err = btintel_parse_version_tlv(hdev, &ver_tlv, skb); if (err) { diff --git a/drivers/bluetooth/btintel.h b/drivers/bluetooth/btintel.h index c9b24e9299..704e3b7bcb 100644 --- a/drivers/bluetooth/btintel.h +++ b/drivers/bluetooth/btintel.h @@ -132,11 +132,6 @@ struct intel_debug_features { __u8 page1[16]; } __packed; -struct intel_offload_use_cases { - __u8 status; - __u8 preset[8]; -} __packed; - #define INTEL_HW_PLATFORM(cnvx_bt) ((u8)(((cnvx_bt) & 0x0000ff00) >> 8)) #define INTEL_HW_VARIANT(cnvx_bt) ((u8)(((cnvx_bt) & 0x003f0000) >> 16)) #define INTEL_CNVX_TOP_TYPE(cnvx_top) ((cnvx_top) & 0x00000fff) @@ -209,7 +204,6 @@ int btintel_configure_setup(struct hci_dev *hdev); void btintel_bootup(struct hci_dev *hdev, const void *ptr, unsigned int len); void btintel_secure_send_result(struct hci_dev *hdev, const void *ptr, unsigned int len); -int btintel_set_quality_report(struct hci_dev *hdev, bool enable); #else static inline int btintel_check_bdaddr(struct hci_dev *hdev) @@ -300,9 +294,4 @@ static inline void btintel_secure_send_result(struct hci_dev *hdev, const void *ptr, unsigned int len) { } - -static inline int btintel_set_quality_report(struct hci_dev *hdev, bool enable) -{ - return -ENODEV; -} #endif diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 181338f605..8b9d78ce6b 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -1,4 +1,4 @@ -/* +/** * Marvell Bluetooth driver * * Copyright (C) 2009, Marvell International Ltd. @@ -587,12 +587,12 @@ static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) return 0; } -static bool btmrvl_wakeup(struct hci_dev *hdev) +static bool btmrvl_prevent_wake(struct hci_dev *hdev) { struct btmrvl_private *priv = hci_get_drvdata(hdev); struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; - return device_may_wakeup(&card->func->dev); + return !device_may_wakeup(&card->func->dev); } /* @@ -696,7 +696,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv) hdev->send = btmrvl_send_frame; hdev->setup = btmrvl_setup; hdev->set_bdaddr = btmrvl_set_bdaddr; - hdev->wakeup = btmrvl_wakeup; + hdev->prevent_wake = btmrvl_prevent_wake; SET_HCIDEV_DEV(hdev, &card->func->dev); hdev->dev_type = priv->btmrvl_dev.dev_type; diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index b5ea8d3bff..1cbdeca1fd 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -27,32 +28,26 @@ #include #include "h4_recv.h" -#include "btmtk.h" #define VERSION "0.1" +#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" +#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" + #define MTKBTSDIO_AUTOSUSPEND_DELAY 8000 static bool enable_autosuspend; struct btmtksdio_data { const char *fwname; - u16 chipid; }; static const struct btmtksdio_data mt7663_data = { .fwname = FIRMWARE_MT7663, - .chipid = 0x7663, }; static const struct btmtksdio_data mt7668_data = { .fwname = FIRMWARE_MT7668, - .chipid = 0x7668, -}; - -static const struct btmtksdio_data mt7921_data = { - .fwname = FIRMWARE_MT7961, - .chipid = 0x7921, }; static const struct sdio_device_id btmtksdio_table[] = { @@ -60,8 +55,6 @@ static const struct sdio_device_id btmtksdio_table[] = { .driver_data = (kernel_ulong_t)&mt7663_data }, {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668), .driver_data = (kernel_ulong_t)&mt7668_data }, - {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961), - .driver_data = (kernel_ulong_t)&mt7921_data }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(sdio, btmtksdio_table); @@ -93,13 +86,28 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table); #define MTK_REG_CRDR 0x1c -#define MTK_REG_CRPLR 0x24 - #define MTK_SDIO_BLOCK_SIZE 256 #define BTMTKSDIO_TX_WAIT_VND_EVT 1 -#define BTMTKSDIO_HW_TX_READY 2 -#define BTMTKSDIO_FUNC_ENABLED 3 + +enum { + MTK_WMT_PATCH_DWNLD = 0x1, + MTK_WMT_TEST = 0x2, + MTK_WMT_WAKEUP = 0x3, + MTK_WMT_HIF = 0x4, + MTK_WMT_FUNC_CTRL = 0x6, + MTK_WMT_RST = 0x7, + MTK_WMT_SEMAPHORE = 0x17, +}; + +enum { + BTMTK_WMT_INVALID, + BTMTK_WMT_PATCH_UNDONE, + BTMTK_WMT_PATCH_DONE, + BTMTK_WMT_ON_UNDONE, + BTMTK_WMT_ON_DONE, + BTMTK_WMT_ON_PROGRESS, +}; struct mtkbtsdio_hdr { __le16 len; @@ -107,12 +115,50 @@ struct mtkbtsdio_hdr { u8 bt_type; } __packed; +struct mtk_wmt_hdr { + u8 dir; + u8 op; + __le16 dlen; + u8 flag; +} __packed; + +struct mtk_hci_wmt_cmd { + struct mtk_wmt_hdr hdr; + u8 data[256]; +} __packed; + +struct btmtk_hci_wmt_evt { + struct hci_event_hdr hhdr; + struct mtk_wmt_hdr whdr; +} __packed; + +struct btmtk_hci_wmt_evt_funcc { + struct btmtk_hci_wmt_evt hwhdr; + __be16 status; +} __packed; + +struct btmtk_tci_sleep { + u8 mode; + __le16 duration; + __le16 host_duration; + u8 host_wakeup_pin; + u8 time_compensation; +} __packed; + +struct btmtk_hci_wmt_params { + u8 op; + u8 flag; + u16 dlen; + const void *data; + u32 *status; +}; + struct btmtksdio_dev { struct hci_dev *hdev; struct sdio_func *func; struct device *dev; - struct work_struct txrx_work; + struct work_struct tx_work; unsigned long tx_state; struct sk_buff_head txq; @@ -126,35 +172,29 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc; - struct btmtk_hci_wmt_evt_reg *wmt_evt_reg; u32 hlen, status = BTMTK_WMT_INVALID; struct btmtk_hci_wmt_evt *wmt_evt; - struct btmtk_hci_wmt_cmd *wc; - struct btmtk_wmt_hdr *hdr; + struct mtk_hci_wmt_cmd wc; + struct mtk_wmt_hdr *hdr; int err; - /* Send the WMT command and wait until the WMT event returns */ hlen = sizeof(*hdr) + wmt_params->dlen; if (hlen > 255) return -EINVAL; - wc = kzalloc(hlen, GFP_KERNEL); - if (!wc) - return -ENOMEM; - - hdr = &wc->hdr; + hdr = (struct mtk_wmt_hdr *)&wc; hdr->dir = 1; hdr->op = wmt_params->op; hdr->dlen = cpu_to_le16(wmt_params->dlen + 1); hdr->flag = wmt_params->flag; - memcpy(wc->data, wmt_params->data, wmt_params->dlen); + memcpy(wc.data, wmt_params->data, wmt_params->dlen); set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); - err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc); + err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); if (err < 0) { clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); - goto err_free_wc; + return err; } /* The vendor specific WMT commands are all answered by a vendor @@ -171,14 +211,13 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, if (err == -EINTR) { bt_dev_err(hdev, "Execution of wmt command interrupted"); clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); - goto err_free_wc; + return err; } if (err) { bt_dev_err(hdev, "Execution of wmt command timed out"); clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state); - err = -ETIMEDOUT; - goto err_free_wc; + return -ETIMEDOUT; } /* Parse and handle the return WMT event */ @@ -191,13 +230,13 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, } switch (wmt_evt->whdr.op) { - case BTMTK_WMT_SEMAPHORE: + case MTK_WMT_SEMAPHORE: if (wmt_evt->whdr.flag == 2) status = BTMTK_WMT_PATCH_UNDONE; else status = BTMTK_WMT_PATCH_DONE; break; - case BTMTK_WMT_FUNC_CTRL: + case MTK_WMT_FUNC_CTRL: wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt; if (be16_to_cpu(wmt_evt_funcc->status) == 0x404) status = BTMTK_WMT_ON_DONE; @@ -206,19 +245,6 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, else status = BTMTK_WMT_ON_UNDONE; break; - case BTMTK_WMT_PATCH_DWNLD: - if (wmt_evt->whdr.flag == 2) - status = BTMTK_WMT_PATCH_DONE; - else if (wmt_evt->whdr.flag == 1) - status = BTMTK_WMT_PATCH_PROGRESS; - else - status = BTMTK_WMT_PATCH_UNDONE; - break; - case BTMTK_WMT_REGISTER: - wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt; - if (le16_to_cpu(wmt_evt->whdr.dlen) == 12) - status = le32_to_cpu(wmt_evt_reg->val); - break; } if (wmt_params->status) @@ -227,8 +253,6 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, err_free_skb: kfree_skb(bdev->evt_skb); bdev->evt_skb = NULL; -err_free_wc: - kfree(wc); return err; } @@ -255,7 +279,6 @@ static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev, sdio_hdr->reserved = cpu_to_le16(0); sdio_hdr->bt_type = hci_skb_pkt_type(skb); - clear_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data, round_up(skb->len, MTK_SDIO_BLOCK_SIZE)); if (err < 0) @@ -278,6 +301,32 @@ static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev) return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL); } +static void btmtksdio_tx_work(struct work_struct *work) +{ + struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev, + tx_work); + struct sk_buff *skb; + int err; + + pm_runtime_get_sync(bdev->dev); + + sdio_claim_host(bdev->func); + + while ((skb = skb_dequeue(&bdev->txq))) { + err = btmtksdio_tx_packet(bdev, skb); + if (err < 0) { + bdev->hdev->stat.err_tx++; + skb_queue_head(&bdev->txq, skb); + break; + } + } + + sdio_release_host(bdev->func); + + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); +} + static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); @@ -325,29 +374,8 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) return err; } -static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); - u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); - - switch (handle) { - case 0xfc6f: - /* Firmware dump from device: when the firmware hangs, the - * device can no longer suspend and thus disable auto-suspend. - */ - pm_runtime_forbid(bdev->dev); - fallthrough; - case 0x05ff: - case 0x05fe: - /* Firmware debug logging */ - return hci_recv_diag(hdev, skb); - } - - return hci_recv_frame(hdev, skb); -} - static const struct h4_recv_pkt mtk_recv_pkts[] = { - { H4_RECV_ACL, .recv = btmtksdio_recv_acl }, + { H4_RECV_ACL, .recv = hci_recv_frame }, { H4_RECV_SCO, .recv = hci_recv_frame }, { H4_RECV_EVENT, .recv = btmtksdio_recv_event }, }; @@ -449,90 +477,70 @@ static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size) return err; } -static void btmtksdio_txrx_work(struct work_struct *work) +static void btmtksdio_interrupt(struct sdio_func *func) { - struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev, - txrx_work); - unsigned long txrx_timeout; - u32 int_status, rx_size; - struct sk_buff *skb; - int err; + struct btmtksdio_dev *bdev = sdio_get_drvdata(func); + u32 int_status; + u16 rx_size; + + /* It is required that the host gets ownership from the device before + * accessing any register, however, if SDIO host is not being released, + * a potential deadlock probably happens in a circular wait between SDIO + * IRQ work and PM runtime work. So, we have to explicitly release SDIO + * host here and claim again after the PM runtime work is all done. + */ + sdio_release_host(bdev->func); pm_runtime_get_sync(bdev->dev); sdio_claim_host(bdev->func); /* Disable interrupt */ - sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); + sdio_writel(func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); - txrx_timeout = jiffies + 5 * HZ; + int_status = sdio_readl(func, MTK_REG_CHISR, NULL); - do { - int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL); + /* Ack an interrupt as soon as possible before any operation on + * hardware. + * + * Note that we don't ack any status during operations to avoid race + * condition between the host and the device such as it's possible to + * mistakenly ack RX_DONE for the next packet and then cause interrupts + * not be raised again but there is still pending data in the hardware + * FIFO. + */ + sdio_writel(func, int_status, MTK_REG_CHISR, NULL); - /* Ack an interrupt as soon as possible before any operation on - * hardware. - * - * Note that we don't ack any status during operations to avoid race - * condition between the host and the device such as it's possible to - * mistakenly ack RX_DONE for the next packet and then cause interrupts - * not be raised again but there is still pending data in the hardware - * FIFO. - */ - sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL); + if (unlikely(!int_status)) + bt_dev_err(bdev->hdev, "CHISR is 0"); - if (int_status & FW_OWN_BACK_INT) - bt_dev_dbg(bdev->hdev, "Get fw own back"); + if (int_status & FW_OWN_BACK_INT) + bt_dev_dbg(bdev->hdev, "Get fw own back"); - if (int_status & TX_EMPTY) - set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); + if (int_status & TX_EMPTY) + schedule_work(&bdev->tx_work); + else if (unlikely(int_status & TX_FIFO_OVERFLOW)) + bt_dev_warn(bdev->hdev, "Tx fifo overflow"); - else if (unlikely(int_status & TX_FIFO_OVERFLOW)) - bt_dev_warn(bdev->hdev, "Tx fifo overflow"); + if (int_status & RX_DONE_INT) { + rx_size = (int_status & RX_PKT_LEN) >> 16; - if (test_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state)) { - skb = skb_dequeue(&bdev->txq); - if (skb) { - err = btmtksdio_tx_packet(bdev, skb); - if (err < 0) { - bdev->hdev->stat.err_tx++; - skb_queue_head(&bdev->txq, skb); - } - } - } - - if (int_status & RX_DONE_INT) { - rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL); - rx_size = (rx_size & RX_PKT_LEN) >> 16; - if (btmtksdio_rx_packet(bdev, rx_size) < 0) - bdev->hdev->stat.err_rx++; - } - } while (int_status || time_is_before_jiffies(txrx_timeout)); + if (btmtksdio_rx_packet(bdev, rx_size) < 0) + bdev->hdev->stat.err_rx++; + } /* Enable interrupt */ - sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0); - - sdio_release_host(bdev->func); + sdio_writel(func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL); pm_runtime_mark_last_busy(bdev->dev); pm_runtime_put_autosuspend(bdev->dev); } -static void btmtksdio_interrupt(struct sdio_func *func) -{ - struct btmtksdio_dev *bdev = sdio_get_drvdata(func); - - /* Disable interrupt */ - sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0); - - schedule_work(&bdev->txrx_work); -} - static int btmtksdio_open(struct hci_dev *hdev) { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); - u32 status, val; int err; + u32 status; sdio_claim_host(bdev->func); @@ -540,8 +548,6 @@ static int btmtksdio_open(struct hci_dev *hdev) if (err < 0) goto err_release_host; - set_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); - /* Get ownership from the device */ sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err); if (err < 0) @@ -574,22 +580,13 @@ static int btmtksdio_open(struct hci_dev *hdev) /* SDIO CMD 5 allows the SDIO device back to idle state an * synchronous interrupt is supported in SDIO 4-bit mode */ - val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err); + sdio_writel(bdev->func, SDIO_INT_CTL | SDIO_RE_INIT_EN, + MTK_REG_CSDIOCSR, &err); if (err < 0) goto err_release_irq; - val |= SDIO_INT_CTL; - sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err); - if (err < 0) - goto err_release_irq; - - /* Explitly set write-1-clear method */ - val = sdio_readl(bdev->func, MTK_REG_CHCR, &err); - if (err < 0) - goto err_release_irq; - - val |= C_INT_CLR_CTRL; - sdio_writel(bdev->func, val, MTK_REG_CHCR, &err); + /* Setup write-1-clear for CHISR register */ + sdio_writel(bdev->func, C_INT_CLR_CTRL, MTK_REG_CHCR, &err); if (err < 0) goto err_release_irq; @@ -633,8 +630,6 @@ static int btmtksdio_close(struct hci_dev *hdev) sdio_release_irq(bdev->func); - cancel_work_sync(&bdev->txrx_work); - /* Return ownership to the device */ sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, NULL); @@ -643,7 +638,6 @@ static int btmtksdio_close(struct hci_dev *hdev) if (err < 0) bt_dev_err(bdev->hdev, "Cannot return ownership to device"); - clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state); sdio_disable_func(bdev->func); sdio_release_host(bdev->func); @@ -657,7 +651,7 @@ static int btmtksdio_flush(struct hci_dev *hdev) skb_queue_purge(&bdev->txq); - cancel_work_sync(&bdev->txrx_work); + cancel_work_sync(&bdev->tx_work); return 0; } @@ -669,7 +663,7 @@ static int btmtksdio_func_query(struct hci_dev *hdev) u8 param = 0; /* Query whether the function is enabled */ - wmt_params.op = BTMTK_WMT_FUNC_CTRL; + wmt_params.op = MTK_WMT_FUNC_CTRL; wmt_params.flag = 4; wmt_params.dlen = sizeof(param); wmt_params.data = ¶m; @@ -684,16 +678,111 @@ static int btmtksdio_func_query(struct hci_dev *hdev) return status; } -static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) +static int mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) { struct btmtk_hci_wmt_params wmt_params; + const struct firmware *fw; + const u8 *fw_ptr; + size_t fw_size; + int err, dlen; + u8 flag, param; + + err = request_firmware(&fw, fwname, &hdev->dev); + if (err < 0) { + bt_dev_err(hdev, "Failed to load firmware file (%d)", err); + return err; + } + + /* Power on data RAM the firmware relies on. */ + param = 1; + wmt_params.op = MTK_WMT_FUNC_CTRL; + wmt_params.flag = 3; + wmt_params.dlen = sizeof(param); + wmt_params.data = ¶m; + wmt_params.status = NULL; + + err = mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); + goto free_fw; + } + + fw_ptr = fw->data; + fw_size = fw->size; + + /* The size of patch header is 30 bytes, should be skip */ + if (fw_size < 30) { + err = -EINVAL; + goto free_fw; + } + + fw_size -= 30; + fw_ptr += 30; + flag = 1; + + wmt_params.op = MTK_WMT_PATCH_DWNLD; + wmt_params.status = NULL; + + while (fw_size > 0) { + dlen = min_t(int, 250, fw_size); + + /* Tell device the position in sequence */ + if (fw_size - dlen <= 0) + flag = 3; + else if (fw_size < fw->size - 30) + flag = 2; + + wmt_params.flag = flag; + wmt_params.dlen = dlen; + wmt_params.data = fw_ptr; + + err = mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", + err); + goto free_fw; + } + + fw_size -= dlen; + fw_ptr += dlen; + } + + wmt_params.op = MTK_WMT_RST; + wmt_params.flag = 4; + wmt_params.dlen = 0; + wmt_params.data = NULL; + wmt_params.status = NULL; + + /* Activate funciton the firmware providing to */ + err = mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt rst (%d)", err); + goto free_fw; + } + + /* Wait a few moments for firmware activation done */ + usleep_range(10000, 12000); + +free_fw: + release_firmware(fw); + return err; +} + +static int btmtksdio_setup(struct hci_dev *hdev) +{ + struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); + struct btmtk_hci_wmt_params wmt_params; + ktime_t calltime, delta, rettime; struct btmtk_tci_sleep tci_sleep; + unsigned long long duration; struct sk_buff *skb; int err, status; u8 param = 0x1; + calltime = ktime_get(); + /* Query whether the firmware is already download */ - wmt_params.op = BTMTK_WMT_SEMAPHORE; + wmt_params.op = MTK_WMT_SEMAPHORE; wmt_params.flag = 1; wmt_params.dlen = 0; wmt_params.data = NULL; @@ -711,7 +800,7 @@ static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) } /* Setup a firmware which the device definitely requires */ - err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync); + err = mtk_setup_firmware(hdev, bdev->data->fwname); if (err < 0) return err; @@ -734,7 +823,7 @@ static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) } /* Enable Bluetooth protocol */ - wmt_params.op = BTMTK_WMT_FUNC_CTRL; + wmt_params.op = MTK_WMT_FUNC_CTRL; wmt_params.flag = 0; wmt_params.dlen = sizeof(param); wmt_params.data = ¶m; @@ -763,116 +852,6 @@ static int mt76xx_setup(struct hci_dev *hdev, const char *fwname) } kfree_skb(skb); - return 0; -} - -static int mt79xx_setup(struct hci_dev *hdev, const char *fwname) -{ - struct btmtk_hci_wmt_params wmt_params; - u8 param = 0x1; - int err; - - err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync); - if (err < 0) { - bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err); - return err; - } - - /* Enable Bluetooth protocol */ - wmt_params.op = BTMTK_WMT_FUNC_CTRL; - wmt_params.flag = 0; - wmt_params.dlen = sizeof(param); - wmt_params.data = ¶m; - wmt_params.status = NULL; - - err = mtk_hci_wmt_sync(hdev, &wmt_params); - if (err < 0) { - bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err); - return err; - } - - hci_set_msft_opcode(hdev, 0xFD30); - hci_set_aosp_capable(hdev); - - return err; -} - -static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val) -{ - struct btmtk_hci_wmt_params wmt_params; - struct reg_read_cmd { - u8 type; - u8 rsv; - u8 num; - __le32 addr; - } __packed reg_read = { - .type = 1, - .num = 1, - }; - u32 status; - int err; - - reg_read.addr = cpu_to_le32(reg); - wmt_params.op = BTMTK_WMT_REGISTER; - wmt_params.flag = BTMTK_WMT_REG_READ; - wmt_params.dlen = sizeof(reg_read); - wmt_params.data = ®_read; - wmt_params.status = &status; - - err = mtk_hci_wmt_sync(hdev, &wmt_params); - if (err < 0) { - bt_dev_err(hdev, "Failed to read reg(%d)", err); - return err; - } - - *val = status; - - return err; -} - -static int btmtksdio_setup(struct hci_dev *hdev) -{ - struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); - ktime_t calltime, delta, rettime; - unsigned long long duration; - char fwname[64]; - int err, dev_id; - u32 fw_version = 0; - - calltime = ktime_get(); - set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); - - switch (bdev->data->chipid) { - case 0x7921: - err = btsdio_mtk_reg_read(hdev, 0x70010200, &dev_id); - if (err < 0) { - bt_dev_err(hdev, "Failed to get device id (%d)", err); - return err; - } - - err = btsdio_mtk_reg_read(hdev, 0x80021004, &fw_version); - if (err < 0) { - bt_dev_err(hdev, "Failed to get fw version (%d)", err); - return err; - } - - snprintf(fwname, sizeof(fwname), - "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", - dev_id & 0xffff, (fw_version & 0xff) + 1); - err = mt79xx_setup(hdev, fwname); - if (err < 0) - return err; - break; - case 0x7663: - case 0x7668: - err = mt76xx_setup(hdev, bdev->data->fwname); - if (err < 0) - return err; - break; - default: - return -ENODEV; - } - rettime = ktime_get(); delta = ktime_sub(rettime, calltime); duration = (unsigned long long)ktime_to_ns(delta) >> 10; @@ -912,7 +891,7 @@ static int btmtksdio_shutdown(struct hci_dev *hdev) pm_runtime_get_sync(bdev->dev); /* Disable the device */ - wmt_params.op = BTMTK_WMT_FUNC_CTRL; + wmt_params.op = MTK_WMT_FUNC_CTRL; wmt_params.flag = 0; wmt_params.dlen = sizeof(param); wmt_params.data = ¶m; @@ -953,7 +932,7 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) skb_queue_tail(&bdev->txq, skb); - schedule_work(&bdev->txrx_work); + schedule_work(&bdev->tx_work); return 0; } @@ -976,7 +955,7 @@ static int btmtksdio_probe(struct sdio_func *func, bdev->dev = &func->dev; bdev->func = func; - INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work); + INIT_WORK(&bdev->tx_work, btmtksdio_tx_work); skb_queue_head_init(&bdev->txq); /* Initialize and register HCI device */ @@ -997,8 +976,6 @@ static int btmtksdio_probe(struct sdio_func *func, hdev->setup = btmtksdio_setup; hdev->shutdown = btmtksdio_shutdown; hdev->send = btmtksdio_send_frame; - hdev->set_bdaddr = btmtk_set_bdaddr; - SET_HCIDEV_DEV(hdev, &func->dev); hdev->manufacturer = 70; @@ -1065,9 +1042,6 @@ static int btmtksdio_runtime_suspend(struct device *dev) if (!bdev) return 0; - if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) - return 0; - sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); sdio_claim_host(bdev->func); @@ -1097,9 +1071,6 @@ static int btmtksdio_runtime_resume(struct device *dev) if (!bdev) return 0; - if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) - return 0; - sdio_claim_host(bdev->func); sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err); @@ -1143,3 +1114,5 @@ MODULE_AUTHOR("Sean Wang "); MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(FIRMWARE_MT7663); +MODULE_FIRMWARE(FIRMWARE_MT7668); diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index c9064d34d8..be04d74037 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -6,7 +6,6 @@ */ #include #include -#include #include #include @@ -142,50 +141,6 @@ static int qca_read_fw_build_info(struct hci_dev *hdev) return err; } -static int qca_send_patch_config_cmd(struct hci_dev *hdev) -{ - const u8 cmd[] = { EDL_PATCH_CONFIG_CMD, 0x01, 0, 0, 0 }; - struct sk_buff *skb; - struct edl_event_hdr *edl; - int err; - - bt_dev_dbg(hdev, "QCA Patch config"); - - skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, sizeof(cmd), - cmd, HCI_EV_VENDOR, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - err = PTR_ERR(skb); - bt_dev_err(hdev, "Sending QCA Patch config failed (%d)", err); - return err; - } - - if (skb->len != 2) { - bt_dev_err(hdev, "QCA Patch config cmd size mismatch len %d", skb->len); - err = -EILSEQ; - goto out; - } - - edl = (struct edl_event_hdr *)(skb->data); - if (!edl) { - bt_dev_err(hdev, "QCA Patch config with no header"); - err = -EILSEQ; - goto out; - } - - if (edl->cresp != EDL_PATCH_CONFIG_RES_EVT || edl->rtype != EDL_PATCH_CONFIG_CMD) { - bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp, - edl->rtype); - err = -EIO; - goto out; - } - - err = 0; - -out: - kfree_skb(skb); - return err; -} - static int qca_send_reset(struct hci_dev *hdev) { struct sk_buff *skb; @@ -596,9 +551,6 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, */ rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); - if (soc_type == QCA_WCN6750) - qca_send_patch_config_cmd(hdev); - /* Download rampatch file */ config.type = TLV_TYPE_PATCH; if (qca_is_wcn399x(soc_type)) { diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 61e9a50e66..30afa7703a 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -13,7 +13,6 @@ #define EDL_PATCH_TLV_REQ_CMD (0x1E) #define EDL_GET_BUILD_INFO_CMD (0x20) #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) -#define EDL_PATCH_CONFIG_CMD (0x28) #define MAX_SIZE_PER_TLV_SEGMENT (243) #define QCA_PRE_SHUTDOWN_CMD (0xFC08) #define QCA_DISABLE_LOGGING (0xFC17) @@ -25,7 +24,6 @@ #define EDL_CMD_EXE_STATUS_EVT (0x00) #define EDL_SET_BAUDRATE_RSP_EVT (0x92) #define EDL_NVM_ACCESS_CODE_EVT (0x0B) -#define EDL_PATCH_CONFIG_RES_EVT (0x00) #define QCA_DISABLE_LOGGING_SUB_OP (0x14) #define EDL_TAG_ID_HCI (17) diff --git a/drivers/bluetooth/btrsi.c b/drivers/bluetooth/btrsi.c index 634cf8f5ed..8646b6dd11 100644 --- a/drivers/bluetooth/btrsi.c +++ b/drivers/bluetooth/btrsi.c @@ -19,6 +19,7 @@ #include #include #include +#include #define RSI_DMA_ALIGN 8 #define RSI_FRAME_DESC_SIZE 16 diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index c2bdd1e606..1f8afa0244 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -59,7 +59,6 @@ struct id_table { __u8 hci_bus; bool config_needed; bool has_rom_version; - bool has_msft_ext; char *fw_name; char *cfg_name; }; @@ -122,7 +121,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8821A, 0xc, 0x8, HCI_USB), .config_needed = false, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8821c_fw.bin", .cfg_name = "rtl_bt/rtl8821c_config" }, @@ -137,7 +135,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_UART), .config_needed = false, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8761b_fw.bin", .cfg_name = "rtl_bt/rtl8761b_config" }, @@ -152,7 +149,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_UART), .config_needed = true, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8822cs_fw.bin", .cfg_name = "rtl_bt/rtl8822cs_config" }, @@ -160,7 +156,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_USB), .config_needed = false, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8822cu_fw.bin", .cfg_name = "rtl_bt/rtl8822cu_config" }, @@ -168,7 +163,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8822B, 0xb, 0x7, HCI_USB), .config_needed = true, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8822b_fw.bin", .cfg_name = "rtl_bt/rtl8822b_config" }, @@ -176,7 +170,6 @@ static const struct id_table ic_id_table[] = { { IC_INFO(RTL_ROM_LMP_8852A, 0xa, 0xb, HCI_USB), .config_needed = false, .has_rom_version = true, - .has_msft_ext = true, .fw_name = "rtl_bt/rtl8852au_fw.bin", .cfg_name = "rtl_bt/rtl8852au_config" }, }; @@ -601,10 +594,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, hci_rev = le16_to_cpu(resp->hci_rev); lmp_subver = le16_to_cpu(resp->lmp_subver); - btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, - hdev->bus); - - if (!btrtl_dev->ic_info) + if (resp->hci_ver == 0x8 && le16_to_cpu(resp->hci_rev) == 0x826c && + resp->lmp_ver == 0x8 && le16_to_cpu(resp->lmp_subver) == 0xa99e) btrtl_dev->drop_fw = true; if (btrtl_dev->drop_fw) { @@ -643,13 +634,13 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, hci_ver = resp->hci_ver; hci_rev = le16_to_cpu(resp->hci_rev); lmp_subver = le16_to_cpu(resp->lmp_subver); - - btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, - hdev->bus); } out_free: kfree_skb(skb); + btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, + hdev->bus); + if (!btrtl_dev->ic_info) { rtl_dev_info(hdev, "unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x", lmp_subver, hci_rev, hci_ver); @@ -693,8 +684,12 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, /* The following chips supports the Microsoft vendor extension, * therefore set the corresponding VsMsftOpCode. */ - if (btrtl_dev->ic_info->has_msft_ext) + switch (lmp_subver) { + case RTL_ROM_LMP_8822B: + case RTL_ROM_LMP_8852A: hci_set_msft_opcode(hdev, 0xFCF0); + break; + } return btrtl_dev; @@ -751,7 +746,6 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev) case CHIP_ID_8852A: set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); - hci_set_aosp_capable(hdev); break; default: rtl_dev_dbg(hdev, "Central-peripheral role not enabled."); diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 795be33f28..199e8f7d42 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -295,8 +295,6 @@ static int btsdio_probe(struct sdio_func *func, switch (func->device) { case SDIO_DEVICE_ID_BROADCOM_43341: case SDIO_DEVICE_ID_BROADCOM_43430: - case SDIO_DEVICE_ID_BROADCOM_4345: - case SDIO_DEVICE_ID_BROADCOM_43455: case SDIO_DEVICE_ID_BROADCOM_4356: return -ENODEV; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c30d131da7..ac90392cce 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -25,13 +24,13 @@ #include "btintel.h" #include "btbcm.h" #include "btrtl.h" -#include "btmtk.h" #define VERSION "0.8" static bool disable_scofix; static bool force_scofix; static bool enable_autosuspend = IS_ENABLED(CONFIG_BT_HCIBTUSB_AUTOSUSPEND); + static bool reset = true; static struct usb_driver btusb_driver; @@ -582,13 +581,8 @@ struct btusb_data { unsigned long flags; - bool poll_sync; - int intr_interval; - struct work_struct work; - struct work_struct waker; - struct delayed_work rx_work; - - struct sk_buff_head acl_q; + struct work_struct work; + struct work_struct waker; struct usb_anchor deferred; struct usb_anchor tx_anchor; @@ -699,33 +693,11 @@ static void btusb_rtl_cmd_timeout(struct hci_dev *hdev) static void btusb_qca_cmd_timeout(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); - struct gpio_desc *reset_gpio = data->reset_gpio; int err; if (++data->cmd_timeout_cnt < 5) return; - if (reset_gpio) { - bt_dev_err(hdev, "Reset qca device via bt_en gpio"); - - /* Toggle the hard reset line. The qca bt device is going to - * yank itself off the USB and then replug. The cleanup is handled - * correctly on the way out (standard USB disconnect), and the new - * device is detected cleanly and bound to the driver again like - * it should be. - */ - if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) { - bt_dev_err(hdev, "last reset failed? Not resetting again"); - return; - } - - gpiod_set_value_cansleep(reset_gpio, 0); - msleep(200); - gpiod_set_value_cansleep(reset_gpio, 1); - - return; - } - bt_dev_err(hdev, "Multiple cmd timeouts seen. Resetting usb device."); /* This is not an unbalanced PM reference since the device will reset */ err = usb_autopm_get_interface(data->intf); @@ -753,16 +725,6 @@ static inline void btusb_free_frags(struct btusb_data *data) spin_unlock_irqrestore(&data->rxlock, flags); } -static int btusb_recv_event(struct btusb_data *data, struct sk_buff *skb) -{ - if (data->intr_interval) { - /* Trigger dequeue immediatelly if an event is received */ - schedule_delayed_work(&data->rx_work, 0); - } - - return data->recv_event(data->hdev, skb); -} - static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; @@ -808,7 +770,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) if (!hci_skb_expect(skb)) { /* Complete frame */ - btusb_recv_event(data, skb); + data->recv_event(data->hdev, skb); skb = NULL; } } @@ -819,20 +781,6 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count) return err; } -static int btusb_recv_acl(struct btusb_data *data, struct sk_buff *skb) -{ - /* Only queue ACL packet if intr_interval is set as it means - * force_poll_sync has been enabled. - */ - if (!data->intr_interval) - return data->recv_acl(data->hdev, skb); - - skb_queue_tail(&data->acl_q, skb); - schedule_delayed_work(&data->rx_work, data->intr_interval); - - return 0; -} - static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count) { struct sk_buff *skb; @@ -880,7 +828,7 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count) if (!hci_skb_expect(skb)) { /* Complete frame */ - btusb_recv_acl(data, skb); + data->recv_acl(data->hdev, skb); skb = NULL; } } @@ -986,8 +934,6 @@ static void btusb_intr_complete(struct urb *urb) if (err != -EPERM && err != -ENODEV) bt_dev_err(hdev, "urb %p failed to resubmit (%d)", urb, -err); - if (err != -EPERM) - hci_cmd_sync_cancel(hdev, -err); usb_unanchor_urb(urb); } } @@ -1031,33 +977,9 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) if (err != -EPERM && err != -ENODEV) bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err); - if (err != -EPERM) - hci_cmd_sync_cancel(hdev, -err); usb_unanchor_urb(urb); } - /* Only initialize intr_interval if URB poll sync is enabled */ - if (!data->poll_sync) - goto done; - - /* The units are frames (milliseconds) for full and low speed devices, - * and microframes (1/8 millisecond) for highspeed and SuperSpeed - * devices. - * - * This is done once on open/resume so it shouldn't change even if - * force_poll_sync changes. - */ - switch (urb->dev->speed) { - case USB_SPEED_SUPER_PLUS: - case USB_SPEED_SUPER: /* units are 125us */ - data->intr_interval = usecs_to_jiffies(urb->interval * 125); - break; - default: - data->intr_interval = msecs_to_jiffies(urb->interval); - break; - } - -done: usb_free_urb(urb); return err; @@ -1410,13 +1332,10 @@ static void btusb_tx_complete(struct urb *urb) if (!test_bit(HCI_RUNNING, &hdev->flags)) goto done; - if (!urb->status) { + if (!urb->status) hdev->stat.byte_tx += urb->transfer_buffer_length; - } else { - if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) - hci_cmd_sync_cancel(hdev, -urb->status); + else hdev->stat.err_tx++; - } done: spin_lock_irqsave(&data->txlock, flags); @@ -1520,12 +1439,9 @@ static int btusb_close(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - cancel_delayed_work(&data->rx_work); cancel_work_sync(&data->work); cancel_work_sync(&data->waker); - skb_queue_purge(&data->acl_q); - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); clear_bit(BTUSB_BULK_RUNNING, &data->flags); clear_bit(BTUSB_INTR_RUNNING, &data->flags); @@ -1557,10 +1473,6 @@ static int btusb_flush(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - cancel_delayed_work(&data->rx_work); - - skb_queue_purge(&data->acl_q); - usb_kill_anchored_urbs(&data->tx_anchor); btusb_free_frags(data); @@ -1924,17 +1836,6 @@ static void btusb_waker(struct work_struct *work) usb_autopm_put_interface(data->intf); } -static void btusb_rx_work(struct work_struct *work) -{ - struct btusb_data *data = container_of(work, struct btusb_data, - rx_work.work); - struct sk_buff *skb; - - /* Dequeue ACL data received during the interval */ - while ((skb = skb_dequeue(&data->acl_q))) - data->recv_acl(data->hdev, skb); -} - static int btusb_setup_bcm92035(struct hci_dev *hdev) { struct sk_buff *skb; @@ -2240,6 +2141,105 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb) #define MTK_BT_RST_DONE 0x00000100 #define MTK_BT_RESET_WAIT_MS 100 #define MTK_BT_RESET_NUM_TRIES 10 +#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" +#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" + +#define HCI_WMT_MAX_EVENT_SIZE 64 +/* It is for mt79xx download rom patch*/ +#define MTK_FW_ROM_PATCH_HEADER_SIZE 32 +#define MTK_FW_ROM_PATCH_GD_SIZE 64 +#define MTK_FW_ROM_PATCH_SEC_MAP_SIZE 64 +#define MTK_SEC_MAP_COMMON_SIZE 12 +#define MTK_SEC_MAP_NEED_SEND_SIZE 52 + +enum { + BTMTK_WMT_PATCH_DWNLD = 0x1, + BTMTK_WMT_FUNC_CTRL = 0x6, + BTMTK_WMT_RST = 0x7, + BTMTK_WMT_SEMAPHORE = 0x17, +}; + +enum { + BTMTK_WMT_INVALID, + BTMTK_WMT_PATCH_UNDONE, + BTMTK_WMT_PATCH_PROGRESS, + BTMTK_WMT_PATCH_DONE, + BTMTK_WMT_ON_UNDONE, + BTMTK_WMT_ON_DONE, + BTMTK_WMT_ON_PROGRESS, +}; + +struct btmtk_wmt_hdr { + u8 dir; + u8 op; + __le16 dlen; + u8 flag; +} __packed; + +struct btmtk_hci_wmt_cmd { + struct btmtk_wmt_hdr hdr; + u8 data[]; +} __packed; + +struct btmtk_hci_wmt_evt { + struct hci_event_hdr hhdr; + struct btmtk_wmt_hdr whdr; +} __packed; + +struct btmtk_hci_wmt_evt_funcc { + struct btmtk_hci_wmt_evt hwhdr; + __be16 status; +} __packed; + +struct btmtk_tci_sleep { + u8 mode; + __le16 duration; + __le16 host_duration; + u8 host_wakeup_pin; + u8 time_compensation; +} __packed; + +struct btmtk_hci_wmt_params { + u8 op; + u8 flag; + u16 dlen; + const void *data; + u32 *status; +}; + +struct btmtk_patch_header { + u8 datetime[16]; + u8 platform[4]; + __le16 hwver; + __le16 swver; + __le32 magicnum; +} __packed; + +struct btmtk_global_desc { + __le32 patch_ver; + __le32 sub_sys; + __le32 feature_opt; + __le32 section_num; +} __packed; + +struct btmtk_section_map { + __le32 sectype; + __le32 secoffset; + __le32 secsize; + union { + __le32 u4SecSpec[13]; + struct { + __le32 dlAddr; + __le32 dlsize; + __le32 seckeyidx; + __le32 alignlen; + __le32 sectype; + __le32 dlmodecrctype; + __le32 crc; + __le32 reserved[6]; + } bin_info_spec; + }; +} __packed; static void btusb_mtk_wmt_recv(struct urb *urb) { @@ -2495,6 +2495,210 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, return err; } +static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname) +{ + struct btmtk_hci_wmt_params wmt_params; + struct btmtk_global_desc *globaldesc = NULL; + struct btmtk_section_map *sectionmap; + const struct firmware *fw; + const u8 *fw_ptr; + const u8 *fw_bin_ptr; + int err, dlen, i, status; + u8 flag, first_block, retry; + u32 section_num, dl_size, section_offset; + u8 cmd[64]; + + err = request_firmware(&fw, fwname, &hdev->dev); + if (err < 0) { + bt_dev_err(hdev, "Failed to load firmware file (%d)", err); + return err; + } + + fw_ptr = fw->data; + fw_bin_ptr = fw_ptr; + globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE); + section_num = le32_to_cpu(globaldesc->section_num); + + for (i = 0; i < section_num; i++) { + first_block = 1; + fw_ptr = fw_bin_ptr; + sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE + + MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i); + + section_offset = le32_to_cpu(sectionmap->secoffset); + dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize); + + if (dl_size > 0) { + retry = 20; + while (retry > 0) { + cmd[0] = 0; /* 0 means legacy dl mode. */ + memcpy(cmd + 1, + fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE + + MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i + + MTK_SEC_MAP_COMMON_SIZE, + MTK_SEC_MAP_NEED_SEND_SIZE + 1); + + wmt_params.op = BTMTK_WMT_PATCH_DWNLD; + wmt_params.status = &status; + wmt_params.flag = 0; + wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1; + wmt_params.data = &cmd; + + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", + err); + goto err_release_fw; + } + + if (status == BTMTK_WMT_PATCH_UNDONE) { + break; + } else if (status == BTMTK_WMT_PATCH_PROGRESS) { + msleep(100); + retry--; + } else if (status == BTMTK_WMT_PATCH_DONE) { + goto next_section; + } else { + bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)", + status); + err = -EIO; + goto err_release_fw; + } + } + + fw_ptr += section_offset; + wmt_params.op = BTMTK_WMT_PATCH_DWNLD; + wmt_params.status = NULL; + + while (dl_size > 0) { + dlen = min_t(int, 250, dl_size); + if (first_block == 1) { + flag = 1; + first_block = 0; + } else if (dl_size - dlen <= 0) { + flag = 3; + } else { + flag = 2; + } + + wmt_params.flag = flag; + wmt_params.dlen = dlen; + wmt_params.data = fw_ptr; + + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", + err); + goto err_release_fw; + } + + dl_size -= dlen; + fw_ptr += dlen; + } + } +next_section: + continue; + } + /* Wait a few moments for firmware activation done */ + usleep_range(100000, 120000); + +err_release_fw: + release_firmware(fw); + + return err; +} + +static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) +{ + struct btmtk_hci_wmt_params wmt_params; + const struct firmware *fw; + const u8 *fw_ptr; + size_t fw_size; + int err, dlen; + u8 flag, param; + + err = request_firmware(&fw, fwname, &hdev->dev); + if (err < 0) { + bt_dev_err(hdev, "Failed to load firmware file (%d)", err); + return err; + } + + /* Power on data RAM the firmware relies on. */ + param = 1; + wmt_params.op = BTMTK_WMT_FUNC_CTRL; + wmt_params.flag = 3; + wmt_params.dlen = sizeof(param); + wmt_params.data = ¶m; + wmt_params.status = NULL; + + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); + goto err_release_fw; + } + + fw_ptr = fw->data; + fw_size = fw->size; + + /* The size of patch header is 30 bytes, should be skip */ + if (fw_size < 30) { + err = -EINVAL; + goto err_release_fw; + } + + fw_size -= 30; + fw_ptr += 30; + flag = 1; + + wmt_params.op = BTMTK_WMT_PATCH_DWNLD; + wmt_params.status = NULL; + + while (fw_size > 0) { + dlen = min_t(int, 250, fw_size); + + /* Tell device the position in sequence */ + if (fw_size - dlen <= 0) + flag = 3; + else if (fw_size < fw->size - 30) + flag = 2; + + wmt_params.flag = flag; + wmt_params.dlen = dlen; + wmt_params.data = fw_ptr; + + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", + err); + goto err_release_fw; + } + + fw_size -= dlen; + fw_ptr += dlen; + } + + wmt_params.op = BTMTK_WMT_RST; + wmt_params.flag = 4; + wmt_params.dlen = 0; + wmt_params.data = NULL; + wmt_params.status = NULL; + + /* Activate funciton the firmware providing to */ + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to send wmt rst (%d)", err); + goto err_release_fw; + } + + /* Wait a few moments for firmware activation done */ + usleep_range(10000, 12000); + +err_release_fw: + release_firmware(fw); + + return err; +} + static int btusb_mtk_func_query(struct hci_dev *hdev) { struct btmtk_hci_wmt_params wmt_params; @@ -2652,8 +2856,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev) snprintf(fw_bin_name, sizeof(fw_bin_name), "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", dev_id & 0xffff, (fw_version & 0xff) + 1); - err = btmtk_setup_firmware_79xx(hdev, fw_bin_name, - btusb_mtk_hci_wmt_sync); + err = btusb_mtk_setup_firmware_79xx(hdev, fw_bin_name); if (err < 0) { bt_dev_err(hdev, "Failed to set up firmware (%d)", err); return err; @@ -2704,8 +2907,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev) } /* Setup a firmware which the device definitely requires */ - err = btmtk_setup_firmware(hdev, fwname, - btusb_mtk_hci_wmt_sync); + err = btusb_mtk_setup_firmware(hdev, fwname); if (err < 0) return err; @@ -2866,6 +3068,9 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) return hci_recv_frame(hdev, skb); } +MODULE_FIRMWARE(FIRMWARE_MT7663); +MODULE_FIRMWARE(FIRMWARE_MT7668); + #ifdef CONFIG_PM /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */ static int marvell_config_oob_wake(struct hci_dev *hdev) @@ -2989,15 +3194,11 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev, #define QCA_DFU_TIMEOUT 3000 #define QCA_FLAG_MULTI_NVM 0x80 -#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200 -#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211 - struct qca_version { __le32 rom_version; __le32 patch_version; __le32 ram_version; - __u8 chip_id; - __u8 platform_id; + __le16 board_id; __le16 flag; __u8 reserved[4]; } __packed; @@ -3024,7 +3225,6 @@ static const struct qca_device_info qca_devices_table[] = { { 0x00000302, 28, 4, 16 }, /* Rome 3.2 */ { 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */ { 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */ - { 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */ }; static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request, @@ -3179,50 +3379,6 @@ static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev, return err; } -static void btusb_generate_qca_nvm_name(char *fwname, size_t max_size, - const struct qca_version *ver) -{ - u32 rom_version = le32_to_cpu(ver->rom_version); - u16 flag = le16_to_cpu(ver->flag); - - if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) { - /* The board_id should be split into two bytes - * The 1st byte is chip ID, and the 2nd byte is platform ID - * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID - * we have several platforms, and platform IDs are continuously added - * Platform ID: - * 0x00 is for Mobile - * 0x01 is for X86 - * 0x02 is for Automotive - * 0x03 is for Consumer electronic - */ - u16 board_id = (ver->chip_id << 8) + ver->platform_id; - const char *variant; - - switch (le32_to_cpu(ver->ram_version)) { - case WCN6855_2_0_RAM_VERSION_GF: - case WCN6855_2_1_RAM_VERSION_GF: - variant = "_gf"; - break; - default: - variant = ""; - break; - } - - if (board_id == 0) { - snprintf(fwname, max_size, "qca/nvm_usb_%08x%s.bin", - rom_version, variant); - } else { - snprintf(fwname, max_size, "qca/nvm_usb_%08x%s_%04x.bin", - rom_version, variant, board_id); - } - } else { - snprintf(fwname, max_size, "qca/nvm_usb_%08x.bin", - rom_version); - } - -} - static int btusb_setup_qca_load_nvm(struct hci_dev *hdev, struct qca_version *ver, const struct qca_device_info *info) @@ -3231,7 +3387,20 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev, char fwname[64]; int err; - btusb_generate_qca_nvm_name(fwname, sizeof(fwname), ver); + if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) { + /* if boardid equal 0, use default nvm without surfix */ + if (le16_to_cpu(ver->board_id) == 0x0) { + snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin", + le32_to_cpu(ver->rom_version)); + } else { + snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin", + le32_to_cpu(ver->rom_version), + le16_to_cpu(ver->board_id)); + } + } else { + snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin", + le32_to_cpu(ver->rom_version)); + } err = request_firmware(&fw, fwname, &hdev->dev); if (err) { @@ -3475,11 +3644,11 @@ static void btusb_check_needs_reset_resume(struct usb_interface *intf) interface_to_usbdev(intf)->quirks |= USB_QUIRK_RESET_RESUME; } -static bool btusb_wakeup(struct hci_dev *hdev) +static bool btusb_prevent_wake(struct hci_dev *hdev) { struct btusb_data *data = hci_get_drvdata(hdev); - return device_may_wakeup(&data->udev->dev); + return !device_may_wakeup(&data->udev->dev); } static int btusb_shutdown_qca(struct hci_dev *hdev) @@ -3496,49 +3665,6 @@ static int btusb_shutdown_qca(struct hci_dev *hdev) return 0; } -static ssize_t force_poll_sync_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct btusb_data *data = file->private_data; - char buf[3]; - - buf[0] = data->poll_sync ? 'Y' : 'N'; - buf[1] = '\n'; - buf[2] = '\0'; - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static ssize_t force_poll_sync_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct btusb_data *data = file->private_data; - bool enable; - int err; - - err = kstrtobool_from_user(user_buf, count, &enable); - if (err) - return err; - - /* Only allow changes while the adapter is down */ - if (test_bit(HCI_UP, &data->hdev->flags)) - return -EPERM; - - if (data->poll_sync == enable) - return -EALREADY; - - data->poll_sync = enable; - - return count; -} - -static const struct file_operations force_poll_sync_fops = { - .open = simple_open, - .read = force_poll_sync_read, - .write = force_poll_sync_write, - .llseek = default_llseek, -}; - static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -3622,10 +3748,6 @@ static int btusb_probe(struct usb_interface *intf, INIT_WORK(&data->work, btusb_work); INIT_WORK(&data->waker, btusb_waker); - INIT_DELAYED_WORK(&data->rx_work, btusb_rx_work); - - skb_queue_head_init(&data->acl_q); - init_usb_anchor(&data->deferred); init_usb_anchor(&data->tx_anchor); spin_lock_init(&data->txlock); @@ -3683,7 +3805,7 @@ static int btusb_probe(struct usb_interface *intf, hdev->flush = btusb_flush; hdev->send = btusb_send_frame; hdev->notify = btusb_notify; - hdev->wakeup = btusb_wakeup; + hdev->prevent_wake = btusb_prevent_wake; #ifdef CONFIG_PM err = btusb_config_oob_wake(hdev); @@ -3753,7 +3875,6 @@ static int btusb_probe(struct usb_interface *intf, hdev->shutdown = btusb_mtk_shutdown; hdev->manufacturer = 70; hdev->cmd_timeout = btusb_mtk_cmd_timeout; - hdev->set_bdaddr = btmtk_set_bdaddr; set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); data->recv_acl = btusb_recv_acl_mtk; } @@ -3894,9 +4015,6 @@ static int btusb_probe(struct usb_interface *intf, usb_set_intfdata(intf, data); - debugfs_create_file("force_poll_sync", 0644, hdev->debugfs, data, - &force_poll_sync_fops); - return 0; out_free_dev: diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index d634a27bc8..7abf99f0ee 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -1513,6 +1513,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = { { .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm4334-bt" }, { .compatible = "brcm,bcm4345c5" }, + { .compatible = "brcm,bcm4330-bt" }, { .compatible = "brcm,bcm43438-bt", .data = &bcm43438_device_data }, { .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data }, { .compatible = "brcm,bcm4335a0" }, diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index dc2641172c..6091727c8b 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -817,6 +817,7 @@ static int h5_serdev_probe(struct serdev_device *serdev) struct device *dev = &serdev->dev; struct h5 *h5; const struct h5_device_data *data; + int err; h5 = devm_kzalloc(dev, sizeof(*h5), GFP_KERNEL); if (!h5) @@ -860,7 +861,11 @@ static int h5_serdev_probe(struct serdev_device *serdev) if (IS_ERR(h5->device_wake_gpio)) return PTR_ERR(h5->device_wake_gpio); - return hci_uart_register_device(&h5->serdev_hu, &h5p); + err = hci_uart_register_device(&h5->serdev_hu, &h5p); + if (err) + return err; + + return 0; } static void h5_serdev_remove(struct serdev_device *serdev) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index f537673ede..5ed2cfa7da 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -479,9 +479,6 @@ static int hci_uart_tty_open(struct tty_struct *tty) BT_DBG("tty %p", tty); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Error if the tty has no write op instead of leaving an exploitable * hole */ @@ -739,13 +736,14 @@ static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags) * Arguments: * * tty pointer to tty instance data + * file pointer to open file object for device * cmd IOCTL command code * arg argument for IOCTL call (cmd dependent) * * Return Value: Command dependent */ -static int hci_uart_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg) +static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { struct hci_uart *hu = tty->disc_data; int err = 0; @@ -792,7 +790,7 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, unsigned int cmd, break; default: - err = n_tty_ioctl_helper(tty, cmd, arg); + err = n_tty_ioctl_helper(tty, file, cmd, arg); break; } diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index f6e91fb432..8eb7fddfb9 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1577,7 +1577,7 @@ static void qca_cmd_timeout(struct hci_dev *hdev) mutex_unlock(&qca->hci_memdump_lock); } -static bool qca_wakeup(struct hci_dev *hdev) +static bool qca_prevent_wake(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); bool wakeup; @@ -1730,7 +1730,6 @@ static int qca_setup(struct hci_uart *hu) if (qca_is_wcn399x(soc_type) || qca_is_wcn6750(soc_type)) { set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); - hci_set_aosp_capable(hdev); ret = qca_read_soc_version(hdev, &ver, soc_type); if (ret) @@ -1765,7 +1764,7 @@ static int qca_setup(struct hci_uart *hu) qca_debugfs_init(hdev); hu->hdev->hw_error = qca_hw_error; hu->hdev->cmd_timeout = qca_cmd_timeout; - hu->hdev->wakeup = qca_wakeup; + hu->hdev->prevent_wake = qca_prevent_wake; } else if (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */ set_bit(QCA_ROM_FW, &qca->flags); diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index c443c3b0a4..8469f9876d 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -38,12 +37,6 @@ struct vhci_data { struct mutex open_mutex; struct delayed_work open_timeout; - struct work_struct suspend_work; - - bool suspended; - bool wakeup; - __u16 msft_opcode; - bool aosp_capable; }; static int vhci_open_dev(struct hci_dev *hdev) @@ -80,204 +73,6 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } -static int vhci_get_data_path_id(struct hci_dev *hdev, u8 *data_path_id) -{ - *data_path_id = 0; - return 0; -} - -static int vhci_get_codec_config_data(struct hci_dev *hdev, __u8 type, - struct bt_codec *codec, __u8 *vnd_len, - __u8 **vnd_data) -{ - if (type != ESCO_LINK) - return -EINVAL; - - *vnd_len = 0; - *vnd_data = NULL; - return 0; -} - -static bool vhci_wakeup(struct hci_dev *hdev) -{ - struct vhci_data *data = hci_get_drvdata(hdev); - - return data->wakeup; -} - -static ssize_t force_suspend_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct vhci_data *data = file->private_data; - char buf[3]; - - buf[0] = data->suspended ? 'Y' : 'N'; - buf[1] = '\n'; - buf[2] = '\0'; - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static void vhci_suspend_work(struct work_struct *work) -{ - struct vhci_data *data = container_of(work, struct vhci_data, - suspend_work); - - if (data->suspended) - hci_suspend_dev(data->hdev); - else - hci_resume_dev(data->hdev); -} - -static ssize_t force_suspend_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct vhci_data *data = file->private_data; - bool enable; - int err; - - err = kstrtobool_from_user(user_buf, count, &enable); - if (err) - return err; - - if (data->suspended == enable) - return -EALREADY; - - data->suspended = enable; - - schedule_work(&data->suspend_work); - - return count; -} - -static const struct file_operations force_suspend_fops = { - .open = simple_open, - .read = force_suspend_read, - .write = force_suspend_write, - .llseek = default_llseek, -}; - -static ssize_t force_wakeup_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct vhci_data *data = file->private_data; - char buf[3]; - - buf[0] = data->wakeup ? 'Y' : 'N'; - buf[1] = '\n'; - buf[2] = '\0'; - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static ssize_t force_wakeup_write(struct file *file, - const char __user *user_buf, size_t count, - loff_t *ppos) -{ - struct vhci_data *data = file->private_data; - bool enable; - int err; - - err = kstrtobool_from_user(user_buf, count, &enable); - if (err) - return err; - - if (data->wakeup == enable) - return -EALREADY; - - data->wakeup = enable; - - return count; -} - -static const struct file_operations force_wakeup_fops = { - .open = simple_open, - .read = force_wakeup_read, - .write = force_wakeup_write, - .llseek = default_llseek, -}; - -static int msft_opcode_set(void *data, u64 val) -{ - struct vhci_data *vhci = data; - - if (val > 0xffff || hci_opcode_ogf(val) != 0x3f) - return -EINVAL; - - if (vhci->msft_opcode) - return -EALREADY; - - vhci->msft_opcode = val; - - return 0; -} - -static int msft_opcode_get(void *data, u64 *val) -{ - struct vhci_data *vhci = data; - - *val = vhci->msft_opcode; - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(msft_opcode_fops, msft_opcode_get, msft_opcode_set, - "%llu\n"); - -static ssize_t aosp_capable_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct vhci_data *vhci = file->private_data; - char buf[3]; - - buf[0] = vhci->aosp_capable ? 'Y' : 'N'; - buf[1] = '\n'; - buf[2] = '\0'; - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static ssize_t aosp_capable_write(struct file *file, - const char __user *user_buf, size_t count, - loff_t *ppos) -{ - struct vhci_data *vhci = file->private_data; - bool enable; - int err; - - err = kstrtobool_from_user(user_buf, count, &enable); - if (err) - return err; - - if (!enable) - return -EINVAL; - - if (vhci->aosp_capable) - return -EALREADY; - - vhci->aosp_capable = enable; - - return count; -} - -static const struct file_operations aosp_capable_fops = { - .open = simple_open, - .read = aosp_capable_read, - .write = aosp_capable_write, - .llseek = default_llseek, -}; - -static int vhci_setup(struct hci_dev *hdev) -{ - struct vhci_data *vhci = hci_get_drvdata(hdev); - - if (vhci->msft_opcode) - hci_set_msft_opcode(hdev, vhci->msft_opcode); - - if (vhci->aosp_capable) - hci_set_aosp_capable(hdev); - - return 0; -} - static int __vhci_create_device(struct vhci_data *data, __u8 opcode) { struct hci_dev *hdev; @@ -317,11 +112,6 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) hdev->close = vhci_close_dev; hdev->flush = vhci_flush; hdev->send = vhci_send_frame; - hdev->get_data_path_id = vhci_get_data_path_id; - hdev->get_codec_config_data = vhci_get_codec_config_data; - hdev->wakeup = vhci_wakeup; - hdev->setup = vhci_setup; - set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); /* bit 6 is for external configuration */ if (opcode & 0x40) @@ -341,20 +131,6 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) return -EBUSY; } - debugfs_create_file("force_suspend", 0644, hdev->debugfs, data, - &force_suspend_fops); - - debugfs_create_file("force_wakeup", 0644, hdev->debugfs, data, - &force_wakeup_fops); - - if (IS_ENABLED(CONFIG_BT_MSFTEXT)) - debugfs_create_file("msft_opcode", 0644, hdev->debugfs, data, - &msft_opcode_fops); - - if (IS_ENABLED(CONFIG_BT_AOSPEXT)) - debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data, - &aosp_capable_fops); - hci_skb_pkt_type(skb) = HCI_VENDOR_PKT; skb_put_u8(skb, 0xff); @@ -544,7 +320,6 @@ static int vhci_open(struct inode *inode, struct file *file) mutex_init(&data->open_mutex); INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout); - INIT_WORK(&data->suspend_work, vhci_suspend_work); file->private_data = data; nonseekable_open(inode, file); @@ -560,7 +335,6 @@ static int vhci_release(struct inode *inode, struct file *file) struct hci_dev *hdev; cancel_delayed_work_sync(&data->open_timeout); - flush_work(&data->suspend_work); hdev = data->hdev; diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 3c68e174a1..a4cf3d692d 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -30,7 +30,7 @@ config ARM_INTEGRATOR_LM found on the ARM Integrator AP (Application Platform) config BRCMSTB_GISB_ARB - tristate "Broadcom STB GISB bus arbiter" + bool "Broadcom STB GISB bus arbiter" depends on ARM || ARM64 || MIPS default ARCH_BRCMSTB || BMIPS_GENERIC help diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c index 183d5cc37d..6551286a60 100644 --- a/drivers/bus/brcmstb_gisb.c +++ b/drivers/bus/brcmstb_gisb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2014-2021 Broadcom + * Copyright (C) 2014-2017 Broadcom */ #include @@ -485,7 +485,7 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); #ifdef CONFIG_MIPS - mips_set_be_handler(brcmstb_bus_error_handler); + board_be_handler = brcmstb_bus_error_handler; #endif if (list_is_singular(&brcmstb_gisb_arb_device_list)) { @@ -536,7 +536,6 @@ static struct platform_driver brcmstb_gisb_arb_driver = { .name = "brcm-gisb-arb", .of_match_table = brcmstb_gisb_arb_of_match, .pm = &brcmstb_gisb_arb_pm_ops, - .suppress_bind_attrs = true, }, }; @@ -547,7 +546,3 @@ static int __init brcm_gisb_driver_init(void) } module_init(brcm_gisb_driver_init); - -MODULE_AUTHOR("Broadcom"); -MODULE_DESCRIPTION("Broadcom STB GISB arbiter driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile index 8929462455..4ae292a30e 100644 --- a/drivers/bus/fsl-mc/Makefile +++ b/drivers/bus/fsl-mc/Makefile @@ -15,8 +15,7 @@ mc-bus-driver-objs := fsl-mc-bus.o \ dprc-driver.o \ fsl-mc-allocator.o \ fsl-mc-msi.o \ - dpmcp.o \ - obj-api.o + dpmcp.o # MC userspace support obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o diff --git a/drivers/bus/fsl-mc/dprc-driver.c b/drivers/bus/fsl-mc/dprc-driver.c index 5e70f9775a..315e830b6e 100644 --- a/drivers/bus/fsl-mc/dprc-driver.c +++ b/drivers/bus/fsl-mc/dprc-driver.c @@ -400,7 +400,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg) struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); struct fsl_mc_io *mc_io = mc_dev->mc_io; - int irq = mc_dev->irqs[0]->virq; + struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc; dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n", irq_num, smp_processor_id()); @@ -409,7 +409,7 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg) return IRQ_HANDLED; mutex_lock(&mc_bus->scan_mutex); - if (irq != (u32)irq_num) + if (!msi_desc || msi_desc->irq != (u32)irq_num) goto out; status = 0; @@ -521,7 +521,7 @@ static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) * function that programs the MSI physically in the device */ error = devm_request_threaded_irq(&mc_dev->dev, - irq->virq, + irq->msi_desc->irq, dprc_irq0_handler, dprc_irq0_handler_thread, IRQF_NO_SUSPEND | IRQF_ONESHOT, @@ -771,7 +771,7 @@ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev) (void)disable_dprc_irq(mc_dev); - devm_free_irq(&mc_dev->dev, irq->virq, &mc_dev->dev); + devm_free_irq(&mc_dev->dev, irq->msi_desc->irq, &mc_dev->dev); fsl_mc_free_irqs(mc_dev); } diff --git a/drivers/bus/fsl-mc/fsl-mc-allocator.c b/drivers/bus/fsl-mc/fsl-mc-allocator.c index dced427ca8..6c51355691 100644 --- a/drivers/bus/fsl-mc/fsl-mc-allocator.c +++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c @@ -350,6 +350,7 @@ int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev, unsigned int irq_count) { unsigned int i; + struct msi_desc *msi_desc; struct fsl_mc_device_irq *irq_resources; struct fsl_mc_device_irq *mc_dev_irq; int error; @@ -387,12 +388,16 @@ int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev, mc_dev_irq->resource.type = res_pool->type; mc_dev_irq->resource.data = mc_dev_irq; mc_dev_irq->resource.parent_pool = res_pool; - mc_dev_irq->virq = msi_get_virq(&mc_bus_dev->dev, i); - mc_dev_irq->resource.id = mc_dev_irq->virq; INIT_LIST_HEAD(&mc_dev_irq->resource.node); list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list); } + for_each_msi_entry(msi_desc, &mc_bus_dev->dev) { + mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index]; + mc_dev_irq->msi_desc = msi_desc; + mc_dev_irq->resource.id = msi_desc->irq; + } + res_pool->max_count = irq_count; res_pool->free_count = irq_count; mc_bus->irq_resources = irq_resources; diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c index 5e0e4393ce..cf974870ba 100644 --- a/drivers/bus/fsl-mc/fsl-mc-msi.c +++ b/drivers/bus/fsl-mc/fsl-mc-msi.c @@ -29,7 +29,7 @@ static irq_hw_number_t fsl_mc_domain_calc_hwirq(struct fsl_mc_device *dev, * Make the base hwirq value for ICID*10000 so it is readable * as a decimal value in /proc/interrupts. */ - return (irq_hw_number_t)(desc->msi_index + (dev->icid * 10000)); + return (irq_hw_number_t)(desc->fsl_mc.msi_index + (dev->icid * 10000)); } static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg, @@ -58,11 +58,11 @@ static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info) } static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev, - struct fsl_mc_device_irq *mc_dev_irq, - struct msi_desc *msi_desc) + struct fsl_mc_device_irq *mc_dev_irq) { int error; struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev; + struct msi_desc *msi_desc = mc_dev_irq->msi_desc; struct dprc_irq_cfg irq_cfg; /* @@ -122,14 +122,14 @@ static void fsl_mc_msi_write_msg(struct irq_data *irq_data, struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(msi_desc->dev); struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); struct fsl_mc_device_irq *mc_dev_irq = - &mc_bus->irq_resources[msi_desc->msi_index]; + &mc_bus->irq_resources[msi_desc->fsl_mc.msi_index]; msi_desc->msg = *msg; /* * Program the MSI (paddr, value) pair in the device: */ - __fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq, msi_desc); + __fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq); } static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info) @@ -170,7 +170,6 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode, fsl_mc_msi_update_dom_ops(info); if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) fsl_mc_msi_update_chip_ops(info); - info->flags |= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | MSI_FLAG_FREE_MSI_DESCS; domain = msi_create_irq_domain(fwnode, info, parent); if (domain) @@ -211,21 +210,61 @@ struct irq_domain *fsl_mc_find_msi_domain(struct device *dev) return msi_domain; } -int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) +static void fsl_mc_msi_free_descs(struct device *dev) +{ + struct msi_desc *desc, *tmp; + + list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { + list_del(&desc->list); + free_msi_entry(desc); + } +} + +static int fsl_mc_msi_alloc_descs(struct device *dev, unsigned int irq_count) + +{ + unsigned int i; + int error; + struct msi_desc *msi_desc; + + for (i = 0; i < irq_count; i++) { + msi_desc = alloc_msi_entry(dev, 1, NULL); + if (!msi_desc) { + dev_err(dev, "Failed to allocate msi entry\n"); + error = -ENOMEM; + goto cleanup_msi_descs; + } + + msi_desc->fsl_mc.msi_index = i; + INIT_LIST_HEAD(&msi_desc->list); + list_add_tail(&msi_desc->list, dev_to_msi_list(dev)); + } + + return 0; + +cleanup_msi_descs: + fsl_mc_msi_free_descs(dev); + return error; +} + +int fsl_mc_msi_domain_alloc_irqs(struct device *dev, + unsigned int irq_count) { struct irq_domain *msi_domain; int error; - msi_domain = dev_get_msi_domain(dev); - if (!msi_domain) + if (!list_empty(dev_to_msi_list(dev))) return -EINVAL; - error = msi_setup_device_data(dev); - if (error) + error = fsl_mc_msi_alloc_descs(dev, irq_count); + if (error < 0) return error; - if (msi_first_desc(dev, MSI_DESC_ALL)) - return -EINVAL; + msi_domain = dev_get_msi_domain(dev); + if (!msi_domain) { + error = -EINVAL; + goto cleanup_msi_descs; + } /* * NOTE: Calling this function will trigger the invocation of the @@ -233,8 +272,15 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) */ error = msi_domain_alloc_irqs(msi_domain, dev, irq_count); - if (error) + if (error) { dev_err(dev, "Failed to allocate IRQs\n"); + goto cleanup_msi_descs; + } + + return 0; + +cleanup_msi_descs: + fsl_mc_msi_free_descs(dev); return error; } @@ -247,4 +293,9 @@ void fsl_mc_msi_domain_free_irqs(struct device *dev) return; msi_domain_free_irqs(msi_domain, dev); + + if (list_empty(dev_to_msi_list(dev))) + return; + + fsl_mc_msi_free_descs(dev); } diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h index b3520ea1b9..1958fa0653 100644 --- a/drivers/bus/fsl-mc/fsl-mc-private.h +++ b/drivers/bus/fsl-mc/fsl-mc-private.h @@ -48,6 +48,7 @@ struct dpmng_rsp_get_version { /* DPMCP command IDs */ #define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) +#define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) #define DPMCP_CMDID_RESET DPMCP_CMD(0x005) struct dpmcp_cmd_open { @@ -90,6 +91,7 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, /* DPRC command IDs */ #define DPRC_CMDID_CLOSE DPRC_CMD(0x800) +#define DPRC_CMDID_OPEN DPRC_CMD(0x805) #define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) #define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) @@ -451,6 +453,7 @@ int dprc_get_connection(struct fsl_mc_io *mc_io, /* Command IDs */ #define DPBP_CMDID_CLOSE DPBP_CMD(0x800) +#define DPBP_CMDID_OPEN DPBP_CMD(0x804) #define DPBP_CMDID_ENABLE DPBP_CMD(0x002) #define DPBP_CMDID_DISABLE DPBP_CMD(0x003) @@ -489,6 +492,7 @@ struct dpbp_rsp_get_attributes { /* Command IDs */ #define DPCON_CMDID_CLOSE DPCON_CMD(0x800) +#define DPCON_CMDID_OPEN DPCON_CMD(0x808) #define DPCON_CMDID_ENABLE DPCON_CMD(0x002) #define DPCON_CMDID_DISABLE DPCON_CMD(0x003) @@ -520,41 +524,6 @@ struct dpcon_cmd_set_notification { __le64 user_ctx; }; -/* - * Generic FSL MC API - */ - -/* generic command versioning */ -#define OBJ_CMD_BASE_VERSION 1 -#define OBJ_CMD_ID_OFFSET 4 - -#define OBJ_CMD(id) (((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION) - -/* open command codes */ -#define DPRTC_CMDID_OPEN OBJ_CMD(0x810) -#define DPNI_CMDID_OPEN OBJ_CMD(0x801) -#define DPSW_CMDID_OPEN OBJ_CMD(0x802) -#define DPIO_CMDID_OPEN OBJ_CMD(0x803) -#define DPBP_CMDID_OPEN OBJ_CMD(0x804) -#define DPRC_CMDID_OPEN OBJ_CMD(0x805) -#define DPDMUX_CMDID_OPEN OBJ_CMD(0x806) -#define DPCI_CMDID_OPEN OBJ_CMD(0x807) -#define DPCON_CMDID_OPEN OBJ_CMD(0x808) -#define DPSECI_CMDID_OPEN OBJ_CMD(0x809) -#define DPAIOP_CMDID_OPEN OBJ_CMD(0x80a) -#define DPMCP_CMDID_OPEN OBJ_CMD(0x80b) -#define DPMAC_CMDID_OPEN OBJ_CMD(0x80c) -#define DPDCEI_CMDID_OPEN OBJ_CMD(0x80d) -#define DPDMAI_CMDID_OPEN OBJ_CMD(0x80e) -#define DPDBG_CMDID_OPEN OBJ_CMD(0x80f) - -/* Generic object command IDs */ -#define OBJ_CMDID_CLOSE OBJ_CMD(0x800) -#define OBJ_CMDID_RESET OBJ_CMD(0x005) - -struct fsl_mc_obj_cmd_open { - __le32 obj_id; -}; /** * struct fsl_mc_resource_pool - Pool of MC resources of a given diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index bccb275b65..28bb65a561 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c @@ -21,7 +21,6 @@ struct imx_weim_devtype { unsigned int cs_stride; unsigned int wcr_offset; unsigned int wcr_bcm; - unsigned int wcr_cont_bclk; }; static const struct imx_weim_devtype imx1_weim_devtype = { @@ -42,7 +41,6 @@ static const struct imx_weim_devtype imx50_weim_devtype = { .cs_stride = 0x18, .wcr_offset = 0x90, .wcr_bcm = BIT(0), - .wcr_cont_bclk = BIT(3), }; static const struct imx_weim_devtype imx51_weim_devtype = { @@ -208,20 +206,8 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) { if (devtype->wcr_bcm) { reg = readl(base + devtype->wcr_offset); - reg |= devtype->wcr_bcm; - - if (of_property_read_bool(pdev->dev.of_node, - "fsl,continuous-burst-clk")) { - if (devtype->wcr_cont_bclk) { - reg |= devtype->wcr_cont_bclk; - } else { - dev_err(&pdev->dev, - "continuous burst clk not supported.\n"); - return -EINVAL; - } - } - - writel(reg, base + devtype->wcr_offset); + writel(reg | devtype->wcr_bcm, + base + devtype->wcr_offset); } else { dev_err(&pdev->dev, "burst clk mode not supported.\n"); return -EINVAL; diff --git a/drivers/bus/mhi/core/boot.c b/drivers/bus/mhi/core/boot.c index 74295d3cc6..0a972620a4 100644 --- a/drivers/bus/mhi/core/boot.c +++ b/drivers/bus/mhi/core/boot.c @@ -417,7 +417,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) } /* wait for ready on pass through or any other execution environment */ - if (!MHI_FW_LOAD_CAPABLE(mhi_cntrl->ee)) + if (mhi_cntrl->ee != MHI_EE_EDL && mhi_cntrl->ee != MHI_EE_PBL) goto fw_load_ready_state; fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ? diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 046f407dc5..f1ec344175 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -79,8 +79,7 @@ static const char * const mhi_pm_state_str[] = { const char *to_mhi_pm_state_str(enum mhi_pm_state state) { - unsigned long pm_state = state; - int index = find_last_bit(&pm_state, 32); + int index = find_last_bit((unsigned long *)&state, 32); if (index >= ARRAY_SIZE(mhi_pm_state_str)) return "Invalid State"; diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h index e2e10474a9..3a732afaf7 100644 --- a/drivers/bus/mhi/core/internal.h +++ b/drivers/bus/mhi/core/internal.h @@ -390,8 +390,7 @@ extern const char * const mhi_ee_str[MHI_EE_MAX]; #define MHI_IN_PBL(ee) (ee == MHI_EE_PBL || ee == MHI_EE_PTHRU || \ ee == MHI_EE_EDL) -#define MHI_POWER_UP_CAPABLE(ee) (MHI_IN_PBL(ee) || ee == MHI_EE_AMSS) -#define MHI_FW_LOAD_CAPABLE(ee) (ee == MHI_EE_PBL || ee == MHI_EE_EDL) + #define MHI_IN_MISSION_MODE(ee) (ee == MHI_EE_AMSS || ee == MHI_EE_WFW || \ ee == MHI_EE_FP) @@ -682,12 +681,8 @@ void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl); void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, struct image_info *img_info); void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); - -/* Automatically allocate and queue inbound buffers */ -#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, - struct mhi_chan *mhi_chan, unsigned int flags); - + struct mhi_chan *mhi_chan); int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index ffde617f93..b15c5bc37d 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -1065,7 +1065,7 @@ void mhi_ctrl_ev_task(unsigned long data) return; } - /* Process ctrl events */ + /* Process ctrl events events */ ret = mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); /* @@ -1430,7 +1430,7 @@ static void mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, } int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, - struct mhi_chan *mhi_chan, unsigned int flags) + struct mhi_chan *mhi_chan) { int ret = 0; struct device *dev = &mhi_chan->mhi_dev->dev; @@ -1455,9 +1455,6 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, if (ret) goto error_pm_state; - if (mhi_chan->dir == DMA_FROM_DEVICE) - mhi_chan->pre_alloc = !!(flags & MHI_CH_INBOUND_ALLOC_BUFS); - /* Pre-allocate buffer for xfer ring */ if (mhi_chan->pre_alloc) { int nr_el = get_nr_avail_ring_elements(mhi_cntrl, @@ -1467,7 +1464,6 @@ int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, while (nr_el--) { void *buf; struct mhi_buf_info info = { }; - buf = kmalloc(len, GFP_KERNEL); if (!buf) { ret = -ENOMEM; @@ -1613,7 +1609,8 @@ void mhi_reset_chan(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan) read_unlock_bh(&mhi_cntrl->pm_lock); } -static int __mhi_prepare_for_transfer(struct mhi_device *mhi_dev, unsigned int flags) +/* Move channel to start state */ +int mhi_prepare_for_transfer(struct mhi_device *mhi_dev) { int ret, dir; struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; @@ -1624,7 +1621,7 @@ static int __mhi_prepare_for_transfer(struct mhi_device *mhi_dev, unsigned int f if (!mhi_chan) continue; - ret = mhi_prepare_channel(mhi_cntrl, mhi_chan, flags); + ret = mhi_prepare_channel(mhi_cntrl, mhi_chan); if (ret) goto error_open_chan; } @@ -1642,19 +1639,8 @@ static int __mhi_prepare_for_transfer(struct mhi_device *mhi_dev, unsigned int f return ret; } - -int mhi_prepare_for_transfer(struct mhi_device *mhi_dev) -{ - return __mhi_prepare_for_transfer(mhi_dev, 0); -} EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer); -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev) -{ - return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS); -} -EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue); - void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index 4aae0baea0..bb9a2043f3 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -42,7 +42,7 @@ * L3: LD_ERR_FATAL_DETECT <--> LD_ERR_FATAL_DETECT * LD_ERR_FATAL_DETECT -> DISABLE */ -static const struct mhi_pm_transitions dev_state_transitions[] = { +static struct mhi_pm_transitions const dev_state_transitions[] = { /* L0 States */ { MHI_PM_DISABLE, @@ -1079,7 +1079,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) write_unlock_irq(&mhi_cntrl->pm_lock); /* Confirm that the device is in valid exec env */ - if (!MHI_POWER_UP_CAPABLE(current_ee)) { + if (!MHI_IN_PBL(current_ee) && current_ee != MHI_EE_AMSS) { dev_err(dev, "%s is not a valid EE for power on\n", TO_MHI_EXEC_STR(current_ee)); ret = -EIO; diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c index b79895810c..d340d6864e 100644 --- a/drivers/bus/mhi/pci_generic.c +++ b/drivers/bus/mhi/pci_generic.c @@ -405,50 +405,7 @@ static const struct mhi_pci_dev_info mhi_mv31_info = { .mru_default = 32768, }; -static const struct mhi_channel_config mhi_sierra_em919x_channels[] = { - MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0), - MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 256, 0), - MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 0), - MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 0), - MHI_CHANNEL_CONFIG_UL(12, "MBIM", 128, 0), - MHI_CHANNEL_CONFIG_DL(13, "MBIM", 128, 0), - MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), - MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), - MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0), - MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), - MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 512, 1), - MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 512, 2), -}; - -static struct mhi_event_config modem_sierra_em919x_mhi_events[] = { - /* first ring is control+data and DIAG ring */ - MHI_EVENT_CONFIG_CTRL(0, 2048), - /* Hardware channels request dedicated hardware event rings */ - MHI_EVENT_CONFIG_HW_DATA(1, 2048, 100), - MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101) -}; - -static const struct mhi_controller_config modem_sierra_em919x_config = { - .max_channels = 128, - .timeout_ms = 24000, - .num_channels = ARRAY_SIZE(mhi_sierra_em919x_channels), - .ch_cfg = mhi_sierra_em919x_channels, - .num_events = ARRAY_SIZE(modem_sierra_em919x_mhi_events), - .event_cfg = modem_sierra_em919x_mhi_events, -}; - -static const struct mhi_pci_dev_info mhi_sierra_em919x_info = { - .name = "sierra-em919x", - .config = &modem_sierra_em919x_config, - .bar_num = MHI_PCI_DEFAULT_BAR_NUM, - .dma_data_width = 32, - .sideband_wake = false, -}; - static const struct pci_device_id mhi_pci_id_table[] = { - /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200), - .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0306), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx55_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), @@ -468,9 +425,6 @@ static const struct pci_device_id mhi_pci_id_table[] = { /* DW5930e (sdx55), Non-eSIM, It's also T99W175 */ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0b1), .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, - /* T99W175 (sdx55), Based on Qualcomm new baseline */ - { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0bf), - .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, /* MV31-W (Cinterion) */ { PCI_DEVICE(0x1269, 0x00b3), .driver_data = (kernel_ulong_t) &mhi_mv31_info }, @@ -577,12 +531,18 @@ static int mhi_pci_claim(struct mhi_controller *mhi_cntrl, mhi_cntrl->regs = pcim_iomap_table(pdev)[bar_num]; mhi_cntrl->reg_len = pci_resource_len(pdev, bar_num); - err = dma_set_mask_and_coherent(&pdev->dev, dma_mask); + err = pci_set_dma_mask(pdev, dma_mask); if (err) { dev_err(&pdev->dev, "Cannot set proper DMA mask\n"); return err; } + err = pci_set_consistent_dma_mask(pdev, dma_mask); + if (err) { + dev_err(&pdev->dev, "set consistent dma mask failed\n"); + return err; + } + pci_set_master(pdev); return 0; diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index db61204561..ea0424922d 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -914,7 +914,6 @@ int mvebu_mbus_add_window_remap_by_id(unsigned int target, return mvebu_mbus_alloc_window(s, base, size, remap, target, attribute); } -EXPORT_SYMBOL_GPL(mvebu_mbus_add_window_remap_by_id); int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute, phys_addr_t base, size_t size) @@ -922,7 +921,6 @@ int mvebu_mbus_add_window_by_id(unsigned int target, unsigned int attribute, return mvebu_mbus_add_window_remap_by_id(target, attribute, base, size, MVEBU_MBUS_NO_REMAP); } -EXPORT_SYMBOL_GPL(mvebu_mbus_add_window_by_id); int mvebu_mbus_del_window(phys_addr_t base, size_t size) { @@ -935,7 +933,6 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size) mvebu_mbus_disable_window(&mbus_state, win); return 0; } -EXPORT_SYMBOL_GPL(mvebu_mbus_del_window); void mvebu_mbus_get_pcie_mem_aperture(struct resource *res) { @@ -943,7 +940,6 @@ void mvebu_mbus_get_pcie_mem_aperture(struct resource *res) return; *res = mbus_state.pcie_mem_aperture; } -EXPORT_SYMBOL_GPL(mvebu_mbus_get_pcie_mem_aperture); void mvebu_mbus_get_pcie_io_aperture(struct resource *res) { @@ -951,7 +947,6 @@ void mvebu_mbus_get_pcie_io_aperture(struct resource *res) return; *res = mbus_state.pcie_io_aperture; } -EXPORT_SYMBOL_GPL(mvebu_mbus_get_pcie_io_aperture); int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr) { diff --git a/drivers/bus/sun50i-de2.c b/drivers/bus/sun50i-de2.c index 414f29cded..672518741f 100644 --- a/drivers/bus/sun50i-de2.c +++ b/drivers/bus/sun50i-de2.c @@ -15,9 +15,10 @@ static int sun50i_de2_bus_probe(struct platform_device *pdev) int ret; ret = sunxi_sram_claim(&pdev->dev); - if (ret) - return dev_err_probe(&pdev->dev, ret, - "Couldn't map SRAM to device\n"); + if (ret) { + dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); + return ret; + } of_platform_populate(np, NULL, NULL, &pdev->dev); diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c index 35b59f92fa..a6570789f7 100644 --- a/drivers/bus/tegra-gmi.c +++ b/drivers/bus/tegra-gmi.c @@ -13,11 +13,8 @@ #include #include #include -#include #include -#include - #define TEGRA_GMI_CONFIG 0x00 #define TEGRA_GMI_CONFIG_GO BIT(31) #define TEGRA_GMI_BUS_WIDTH_32BIT BIT(30) @@ -57,10 +54,9 @@ static int tegra_gmi_enable(struct tegra_gmi *gmi) { int err; - pm_runtime_enable(gmi->dev); - err = pm_runtime_resume_and_get(gmi->dev); - if (err) { - pm_runtime_disable(gmi->dev); + err = clk_prepare_enable(gmi->clk); + if (err < 0) { + dev_err(gmi->dev, "failed to enable clock: %d\n", err); return err; } @@ -87,9 +83,7 @@ static void tegra_gmi_disable(struct tegra_gmi *gmi) writel(config, gmi->base + TEGRA_GMI_CONFIG); reset_control_assert(gmi->rst); - - pm_runtime_put_sync_suspend(gmi->dev); - pm_runtime_force_suspend(gmi->dev); + clk_disable_unprepare(gmi->clk); } static int tegra_gmi_parse_dt(struct tegra_gmi *gmi) @@ -219,7 +213,6 @@ static int tegra_gmi_probe(struct platform_device *pdev) if (!gmi) return -ENOMEM; - platform_set_drvdata(pdev, gmi); gmi->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -239,10 +232,6 @@ static int tegra_gmi_probe(struct platform_device *pdev) return PTR_ERR(gmi->rst); } - err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); - if (err) - return err; - err = tegra_gmi_parse_dt(gmi); if (err) return err; @@ -258,6 +247,8 @@ static int tegra_gmi_probe(struct platform_device *pdev) return err; } + platform_set_drvdata(pdev, gmi); + return 0; } @@ -271,34 +262,6 @@ static int tegra_gmi_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused tegra_gmi_runtime_resume(struct device *dev) -{ - struct tegra_gmi *gmi = dev_get_drvdata(dev); - int err; - - err = clk_prepare_enable(gmi->clk); - if (err < 0) { - dev_err(gmi->dev, "failed to enable clock: %d\n", err); - return err; - } - - return 0; -} - -static int __maybe_unused tegra_gmi_runtime_suspend(struct device *dev) -{ - struct tegra_gmi *gmi = dev_get_drvdata(dev); - - clk_disable_unprepare(gmi->clk); - - return 0; -} - -static const struct dev_pm_ops tegra_gmi_pm = { - SET_RUNTIME_PM_OPS(tegra_gmi_runtime_suspend, tegra_gmi_runtime_resume, - NULL) -}; - static const struct of_device_id tegra_gmi_id_table[] = { { .compatible = "nvidia,tegra20-gmi", }, { .compatible = "nvidia,tegra30-gmi", }, @@ -312,7 +275,6 @@ static struct platform_driver tegra_gmi_driver = { .driver = { .name = "tegra-gmi", .of_match_table = tegra_gmi_id_table, - .pm = &tegra_gmi_pm, }, }; module_platform_driver(tegra_gmi_driver); diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 54c0ee6dda..ebf22929ff 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -140,7 +140,6 @@ struct sysc { struct ti_sysc_cookie cookie; const char *name; u32 revision; - u32 sysconfig; unsigned int reserved:1; unsigned int enabled:1; unsigned int needs_resume:1; @@ -157,7 +156,6 @@ struct sysc { static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, bool is_child); -static int sysc_reset(struct sysc *ddata); static void sysc_write(struct sysc *ddata, int offset, u32 value) { @@ -1145,8 +1143,7 @@ static int sysc_enable_module(struct device *dev) best_mode = fls(ddata->cfg.midlemodes) - 1; if (best_mode > SYSC_IDLE_MASK) { dev_err(dev, "%s: invalid midlemode\n", __func__); - error = -EINVAL; - goto save_context; + return -EINVAL; } if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY) @@ -1164,16 +1161,13 @@ static int sysc_enable_module(struct device *dev) sysc_write_sysconfig(ddata, reg); } - error = 0; - -save_context: - /* Save context and flush posted write */ - ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + /* Flush posted write */ + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); if (ddata->module_enable_quirk) ddata->module_enable_quirk(ddata); - return error; + return 0; } static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode) @@ -1230,10 +1224,8 @@ static int sysc_disable_module(struct device *dev) set_sidle: /* Set SIDLE mode */ idlemodes = ddata->cfg.sidlemodes; - if (!idlemodes || regbits->sidle_shift < 0) { - ret = 0; - goto save_context; - } + if (!idlemodes || regbits->sidle_shift < 0) + return 0; if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE) { best_mode = SYSC_IDLE_FORCE; @@ -1241,8 +1233,7 @@ static int sysc_disable_module(struct device *dev) ret = sysc_best_idle_mode(idlemodes, &best_mode); if (ret) { dev_err(dev, "%s: invalid sidlemode\n", __func__); - ret = -EINVAL; - goto save_context; + return ret; } } @@ -1253,13 +1244,10 @@ static int sysc_disable_module(struct device *dev) reg |= 1 << regbits->autoidle_shift; sysc_write_sysconfig(ddata, reg); - ret = 0; + /* Flush posted write */ + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); -save_context: - /* Save context and flush posted write */ - ddata->sysconfig = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); - - return ret; + return 0; } static int __maybe_unused sysc_runtime_suspend_legacy(struct device *dev, @@ -1397,40 +1385,13 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) return error; } -/* - * Checks if device context was lost. Assumes the sysconfig register value - * after lost context is different from the configured value. Only works for - * enabled devices. - * - * Eventually we may want to also add support to using the context lost - * registers that some SoCs have. - */ -static int sysc_check_context(struct sysc *ddata) -{ - u32 reg; - - if (!ddata->enabled) - return -ENODATA; - - reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); - if (reg == ddata->sysconfig) - return 0; - - return -EACCES; -} - static int sysc_reinit_module(struct sysc *ddata, bool leave_enabled) { struct device *dev = ddata->dev; int error; + /* Disable target module if it is enabled */ if (ddata->enabled) { - /* Nothing to do if enabled and context not lost */ - error = sysc_check_context(ddata); - if (!error) - return 0; - - /* Disable target module if it is enabled */ error = sysc_runtime_suspend(dev); if (error) dev_warn(dev, "reinit suspend failed: %i\n", error); @@ -1441,15 +1402,6 @@ static int sysc_reinit_module(struct sysc *ddata, bool leave_enabled) if (error) dev_warn(dev, "reinit resume failed: %i\n", error); - /* Some modules like am335x gpmc need reset and restore of sysconfig */ - if (ddata->cfg.quirks & SYSC_QUIRK_RESET_ON_CTX_LOST) { - error = sysc_reset(ddata); - if (error) - dev_warn(dev, "reinit reset failed: %i\n", error); - - sysc_write_sysconfig(ddata, ddata->sysconfig); - } - if (leave_enabled) return error; @@ -1539,6 +1491,10 @@ struct sysc_revision_quirk { static const struct sysc_revision_quirk sysc_revision_quirks[] = { /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ + SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff, + SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET), + SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, @@ -1572,10 +1528,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_CLKDM_NOAUTO), SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, SYSC_QUIRK_CLKDM_NOAUTO), - SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff, - SYSC_QUIRK_OPT_CLKS_IN_RESET), SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff, - SYSC_QUIRK_REINIT_ON_CTX_LOST | SYSC_QUIRK_RESET_ON_CTX_LOST | SYSC_QUIRK_GPMC_DEBUG), SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, SYSC_QUIRK_OPT_CLKS_NEEDED), @@ -1611,8 +1564,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, - 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | - SYSC_MODULE_QUIRK_OTG), + 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | SYSC_QUIRK_REINIT_ON_CTX_LOST), @@ -1680,7 +1632,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK("sdio", 0, 0, 0x10, -ENODEV, 0x40202301, 0xffff0ff0, 0), SYSC_QUIRK("sdio", 0, 0x2fc, 0x110, 0x114, 0x31010000, 0xffffffff, 0), SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, 0), - SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, 0), SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40000902, 0xffffffff, 0), SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40002903, 0xffffffff, 0), SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x24, -ENODEV, 0x00000000, 0xffffffff, 0), @@ -1972,22 +1923,6 @@ static void sysc_module_lock_quirk_rtc(struct sysc *ddata) sysc_quirk_rtc(ddata, true); } -/* OTG omap2430 glue layer up to omap4 needs OTG_FORCESTDBY configured */ -static void sysc_module_enable_quirk_otg(struct sysc *ddata) -{ - int offset = 0x414; /* OTG_FORCESTDBY */ - - sysc_write(ddata, offset, 0); -} - -static void sysc_module_disable_quirk_otg(struct sysc *ddata) -{ - int offset = 0x414; /* OTG_FORCESTDBY */ - u32 val = BIT(0); /* ENABLEFORCE */ - - sysc_write(ddata, offset, val); -} - /* 36xx SGX needs a quirk for to bypass OCP IPG interrupt logic */ static void sysc_module_enable_quirk_sgx(struct sysc *ddata) { @@ -2070,11 +2005,6 @@ static void sysc_init_module_quirks(struct sysc *ddata) return; } - if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_OTG) { - ddata->module_enable_quirk = sysc_module_enable_quirk_otg; - ddata->module_disable_quirk = sysc_module_disable_quirk_otg; - } - if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX) ddata->module_enable_quirk = sysc_module_enable_quirk_sgx; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 1b57d4666e..bd2e5b1560 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -344,12 +344,6 @@ static void cdrom_sysctl_register(void); static LIST_HEAD(cdrom_list); -static void signal_media_change(struct cdrom_device_info *cdi) -{ - cdi->mc_flags = 0x3; /* set media changed bits, on both queues */ - cdi->last_media_change_ms = ktime_to_ms(ktime_get()); -} - int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) { @@ -622,7 +616,6 @@ int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi) ENSURE(cdo, generic_packet, CDC_GENERIC_PACKET); cdi->mc_flags = 0; cdi->options = CDO_USE_FFLAGS; - cdi->last_media_change_ms = ktime_to_ms(ktime_get()); if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY)) cdi->options |= (int) CDO_AUTO_CLOSE; @@ -871,7 +864,7 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) { struct packet_command cgc; char buffer[32]; - int mmc3_profile; + int ret, mmc3_profile; init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); @@ -881,7 +874,7 @@ static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ cgc.quiet = 1; - if (cdi->ops->generic_packet(cdi, &cgc)) + if ((ret = cdi->ops->generic_packet(cdi, &cgc))) mmc3_profile = 0xffff; else mmc3_profile = (buffer[6] << 8) | buffer[7]; @@ -1428,7 +1421,8 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) cdi->ops->check_events(cdi, 0, slot); if (slot == CDSL_NONE) { - signal_media_change(cdi); + /* set media changed bits, on both queues */ + cdi->mc_flags = 0x3; return cdrom_load_unload(cdi, -1); } @@ -1461,7 +1455,7 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) slot = curslot; /* set media changed bits on both queues */ - signal_media_change(cdi); + cdi->mc_flags = 0x3; if ((ret = cdrom_load_unload(cdi, slot))) return ret; @@ -1527,7 +1521,7 @@ int media_changed(struct cdrom_device_info *cdi, int queue) cdi->ioctl_events = 0; if (changed) { - signal_media_change(cdi); + cdi->mc_flags = 0x3; /* set bit on both queues */ ret |= 1; cdi->media_written = 0; } @@ -2342,49 +2336,6 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, return ret; } -/* - * Media change detection with timing information. - * - * arg is a pointer to a cdrom_timed_media_change_info struct. - * arg->last_media_change may be set by calling code to signal - * the timestamp (in ms) of the last known media change (by the caller). - * Upon successful return, ioctl call will set arg->last_media_change - * to the latest media change timestamp known by the kernel/driver - * and set arg->has_changed to 1 if that timestamp is more recent - * than the timestamp set by the caller. - */ -static int cdrom_ioctl_timed_media_change(struct cdrom_device_info *cdi, - unsigned long arg) -{ - int ret; - struct cdrom_timed_media_change_info __user *info; - struct cdrom_timed_media_change_info tmp_info; - - if (!CDROM_CAN(CDC_MEDIA_CHANGED)) - return -ENOSYS; - - info = (struct cdrom_timed_media_change_info __user *)arg; - cd_dbg(CD_DO_IOCTL, "entering CDROM_TIMED_MEDIA_CHANGE\n"); - - ret = cdrom_ioctl_media_changed(cdi, CDSL_CURRENT); - if (ret < 0) - return ret; - - if (copy_from_user(&tmp_info, info, sizeof(tmp_info)) != 0) - return -EFAULT; - - tmp_info.media_flags = 0; - if (tmp_info.last_media_change - cdi->last_media_change_ms < 0) - tmp_info.media_flags |= MEDIA_CHANGED_FLAG; - - tmp_info.last_media_change = cdi->last_media_change_ms; - - if (copy_to_user(info, &tmp_info, sizeof(*info)) != 0) - return -EFAULT; - - return 0; -} - static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, unsigned long arg) { @@ -3362,8 +3313,6 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, return cdrom_ioctl_eject_sw(cdi, arg); case CDROM_MEDIA_CHANGED: return cdrom_ioctl_media_changed(cdi, arg); - case CDROM_TIMED_MEDIA_CHANGE: - return cdrom_ioctl_timed_media_change(cdi, arg); case CDROM_SET_OPTIONS: return cdrom_ioctl_set_options(cdi, arg); case CDROM_CLEAR_OPTIONS: @@ -3691,6 +3640,27 @@ static struct ctl_table cdrom_table[] = { }, { } }; + +static struct ctl_table cdrom_cdrom_table[] = { + { + .procname = "cdrom", + .maxlen = 0, + .mode = 0555, + .child = cdrom_table, + }, + { } +}; + +/* Make sure that /proc/sys/dev is there */ +static struct ctl_table cdrom_root_table[] = { + { + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .child = cdrom_cdrom_table, + }, + { } +}; static struct ctl_table_header *cdrom_sysctl_header; static void cdrom_sysctl_register(void) @@ -3700,7 +3670,7 @@ static void cdrom_sysctl_register(void) if (!atomic_add_unless(&initialized, 1, 1)) return; - cdrom_sysctl_header = register_sysctl("dev/cdrom", cdrom_table); + cdrom_sysctl_header = register_sysctl_table(cdrom_root_table); /* set the defaults */ cdrom_sysctl_settings.autoclose = autoclose; diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index faead41709..8e1fe75af9 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -719,7 +719,6 @@ static void probe_gdrom_setupdisk(void) gd.disk->major = gdrom_major; gd.disk->first_minor = 1; gd.disk->minors = 1; - gd.disk->flags |= GENHD_FL_NO_PART; strcpy(gd.disk->disk_name, GDROM_DEV_NAME); } @@ -806,14 +805,9 @@ static int probe_gdrom(struct platform_device *devptr) err = -ENOMEM; goto probe_fail_free_irqs; } - err = add_disk(gd.disk); - if (err) - goto probe_fail_add_disk; - + add_disk(gd.disk); return 0; -probe_fail_add_disk: - kfree(gd.toc); probe_fail_free_irqs: free_irq(HW_EVENT_GDROM_DMA, &gd); free_irq(HW_EVENT_GDROM_CMD, &gd); diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 188298252b..bc17883bc6 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -175,14 +175,6 @@ config COMMON_CLK_CDCE706 help This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. -config COMMON_CLK_TPS68470 - tristate "Clock Driver for TI TPS68470 PMIC" - depends on I2C - depends on INTEL_SKL_INT3472 || COMPILE_TEST - select REGMAP_I2C - help - This driver supports the clocks provided by the TPS68470 PMIC. - config COMMON_CLK_CDCE925 tristate "Clock driver for TI CDCE913/925/937/949 devices" depends on I2C @@ -235,13 +227,6 @@ config COMMON_CLK_GEMINI This driver supports the SoC clocks on the Cortina Systems Gemini platform, also known as SL3516 or CS3516. -config COMMON_CLK_LAN966X - bool "Generic Clock Controller driver for LAN966X SoC" - help - This driver provides support for Generic Clock Controller(GCK) on - LAN966X SoC. GCK generates and supplies clock to various peripherals - within the SoC. - config COMMON_CLK_ASPEED bool "Clock driver for Aspeed BMC SoCs" depends on ARCH_ASPEED || COMPILE_TEST @@ -360,6 +345,16 @@ config COMMON_CLK_STM32MP157 help Support for stm32mp157 SoC family clocks +config COMMON_CLK_STM32MP157_SCMI + bool "stm32mp157 Clock driver with Trusted Firmware" + depends on COMMON_CLK_STM32MP157 + select COMMON_CLK_SCMI + select ARM_SCMI_PROTOCOL + default y + help + Support for stm32mp157 SoC family clocks with Trusted Firmware using + SCMI protocol. + config COMMON_CLK_STM32F def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746) help @@ -423,13 +418,11 @@ source "drivers/clk/samsung/Kconfig" source "drivers/clk/sifive/Kconfig" source "drivers/clk/socfpga/Kconfig" source "drivers/clk/sprd/Kconfig" -source "drivers/clk/starfive/Kconfig" source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/ti/Kconfig" source "drivers/clk/uniphier/Kconfig" -source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" source "drivers/clk/xilinx/Kconfig" source "drivers/clk/zynqmp/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cdca6b4b8f..a1d8cd6635 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o obj-$(CONFIG_LMK04832) += clk-lmk04832.o -obj-$(CONFIG_COMMON_CLK_LAN966X) += clk-lan966x.o obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o obj-$(CONFIG_COMMON_CLK_HIFIBERRY_DACPRO) += clk-hifiberry-dacpro.o obj-$(CONFIG_COMMON_CLK_HIFIBERRY_DACPLUSHD) += clk-hifiberry-dachd.o @@ -67,7 +66,6 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o -obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o @@ -114,15 +112,13 @@ obj-y += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-y += sprd/ obj-$(CONFIG_ARCH_STI) += st/ -obj-$(CONFIG_SOC_STARFIVE) += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ -obj-y += sunxi-ng/ +obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-y += versatile/ -obj-$(CONFIG_COMMON_CLK_VISCONTI) += visconti/ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_X86) += x86/ endif diff --git a/drivers/clk/actions/owl-factor.c b/drivers/clk/actions/owl-factor.c index 64f316cf7c..f15e2621fa 100644 --- a/drivers/clk/actions/owl-factor.c +++ b/drivers/clk/actions/owl-factor.c @@ -10,6 +10,7 @@ #include #include +#include #include "owl-factor.h" diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c index fff4fdda97..428a6f4b9e 100644 --- a/drivers/clk/at91/at91rm9200.c +++ b/drivers/clk/at91/at91rm9200.c @@ -152,7 +152,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) "masterck_pres", &at91rm9200_master_layout, &rm9200_mck_characteristics, - &rm9200_mck_lock, CLK_SET_RATE_GATE, 0); + &rm9200_mck_lock, CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c index 79802f864e..b29843bea2 100644 --- a/drivers/clk/at91/at91sam9260.c +++ b/drivers/clk/at91/at91sam9260.c @@ -429,7 +429,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, &at91rm9200_master_layout, data->mck_characteristics, &at91sam9260_mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c index 7ed984f805..15da0dfe3e 100644 --- a/drivers/clk/at91/at91sam9g45.c +++ b/drivers/clk/at91/at91sam9g45.c @@ -164,7 +164,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) &at91rm9200_master_layout, &mck_characteristics, &at91sam9g45_mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c index 63cc58944b..7fe435f4b4 100644 --- a/drivers/clk/at91/at91sam9n12.c +++ b/drivers/clk/at91/at91sam9n12.c @@ -191,7 +191,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) &at91sam9x5_master_layout, &mck_characteristics, &at91sam9n12_mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c index 4d4faf6c61..ecbabf5162 100644 --- a/drivers/clk/at91/at91sam9rl.c +++ b/drivers/clk/at91/at91sam9rl.c @@ -132,7 +132,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) "masterck_pres", &at91rm9200_master_layout, &sam9rl_mck_characteristics, - &sam9rl_mck_lock, CLK_SET_RATE_GATE, 0); + &sam9rl_mck_lock, CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c index bd8007b4f3..5cce48c64e 100644 --- a/drivers/clk/at91/at91sam9x5.c +++ b/drivers/clk/at91/at91sam9x5.c @@ -210,7 +210,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, "masterck_pres", &at91sam9x5_master_layout, &mck_characteristics, &mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 23cc8297ec..b656d25a97 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -27,7 +27,6 @@ struct clk_generated { u32 id; u32 gckdiv; const struct clk_pcr_layout *layout; - struct at91_clk_pms pms; u8 parent_id; int chg_pid; }; @@ -35,35 +34,25 @@ struct clk_generated { #define to_clk_generated(hw) \ container_of(hw, struct clk_generated, hw) -static int clk_generated_set(struct clk_generated *gck, int status) +static int clk_generated_enable(struct clk_hw *hw) { + struct clk_generated *gck = to_clk_generated(hw); unsigned long flags; - unsigned int enable = status ? AT91_PMC_PCR_GCKEN : 0; + + pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", + __func__, gck->gckdiv, gck->parent_id); spin_lock_irqsave(gck->lock, flags); regmap_write(gck->regmap, gck->layout->offset, (gck->id & gck->layout->pid_mask)); regmap_update_bits(gck->regmap, gck->layout->offset, AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | - gck->layout->cmd | enable, + gck->layout->cmd | AT91_PMC_PCR_GCKEN, field_prep(gck->layout->gckcss_mask, gck->parent_id) | gck->layout->cmd | FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | - enable); + AT91_PMC_PCR_GCKEN); spin_unlock_irqrestore(gck->lock, flags); - - return 0; -} - -static int clk_generated_enable(struct clk_hw *hw) -{ - struct clk_generated *gck = to_clk_generated(hw); - - pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", - __func__, gck->gckdiv, gck->parent_id); - - clk_generated_set(gck, 1); - return 0; } @@ -256,23 +245,6 @@ static int clk_generated_set_rate(struct clk_hw *hw, return 0; } -static int clk_generated_save_context(struct clk_hw *hw) -{ - struct clk_generated *gck = to_clk_generated(hw); - - gck->pms.status = clk_generated_is_enabled(&gck->hw); - - return 0; -} - -static void clk_generated_restore_context(struct clk_hw *hw) -{ - struct clk_generated *gck = to_clk_generated(hw); - - if (gck->pms.status) - clk_generated_set(gck, gck->pms.status); -} - static const struct clk_ops generated_ops = { .enable = clk_generated_enable, .disable = clk_generated_disable, @@ -282,8 +254,6 @@ static const struct clk_ops generated_ops = { .get_parent = clk_generated_get_parent, .set_parent = clk_generated_set_parent, .set_rate = clk_generated_set_rate, - .save_context = clk_generated_save_context, - .restore_context = clk_generated_restore_context, }; /** @@ -350,6 +320,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, if (ret) { kfree(gck); hw = ERR_PTR(ret); + } else { + pmc_register_id(id); } return hw; diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index 8601b27c1a..cfae2f59df 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -28,7 +28,6 @@ struct clk_main_osc { struct clk_hw hw; struct regmap *regmap; - struct at91_clk_pms pms; }; #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) @@ -38,7 +37,6 @@ struct clk_main_rc_osc { struct regmap *regmap; unsigned long frequency; unsigned long accuracy; - struct at91_clk_pms pms; }; #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw) @@ -53,7 +51,6 @@ struct clk_rm9200_main { struct clk_sam9x5_main { struct clk_hw hw; struct regmap *regmap; - struct at91_clk_pms pms; u8 parent; }; @@ -123,29 +120,10 @@ static int clk_main_osc_is_prepared(struct clk_hw *hw) return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp); } -static int clk_main_osc_save_context(struct clk_hw *hw) -{ - struct clk_main_osc *osc = to_clk_main_osc(hw); - - osc->pms.status = clk_main_osc_is_prepared(hw); - - return 0; -} - -static void clk_main_osc_restore_context(struct clk_hw *hw) -{ - struct clk_main_osc *osc = to_clk_main_osc(hw); - - if (osc->pms.status) - clk_main_osc_prepare(hw); -} - static const struct clk_ops main_osc_ops = { .prepare = clk_main_osc_prepare, .unprepare = clk_main_osc_unprepare, .is_prepared = clk_main_osc_is_prepared, - .save_context = clk_main_osc_save_context, - .restore_context = clk_main_osc_restore_context, }; struct clk_hw * __init @@ -262,31 +240,12 @@ static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw, return osc->accuracy; } -static int clk_main_rc_osc_save_context(struct clk_hw *hw) -{ - struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); - - osc->pms.status = clk_main_rc_osc_is_prepared(hw); - - return 0; -} - -static void clk_main_rc_osc_restore_context(struct clk_hw *hw) -{ - struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); - - if (osc->pms.status) - clk_main_rc_osc_prepare(hw); -} - static const struct clk_ops main_rc_osc_ops = { .prepare = clk_main_rc_osc_prepare, .unprepare = clk_main_rc_osc_unprepare, .is_prepared = clk_main_rc_osc_is_prepared, .recalc_rate = clk_main_rc_osc_recalc_rate, .recalc_accuracy = clk_main_rc_osc_recalc_accuracy, - .save_context = clk_main_rc_osc_save_context, - .restore_context = clk_main_rc_osc_restore_context, }; struct clk_hw * __init @@ -506,37 +465,12 @@ static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) return clk_main_parent_select(status); } -static int clk_sam9x5_main_save_context(struct clk_hw *hw) -{ - struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - - clkmain->pms.status = clk_main_rc_osc_is_prepared(&clkmain->hw); - clkmain->pms.parent = clk_sam9x5_main_get_parent(&clkmain->hw); - - return 0; -} - -static void clk_sam9x5_main_restore_context(struct clk_hw *hw) -{ - struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - int ret; - - ret = clk_sam9x5_main_set_parent(hw, clkmain->pms.parent); - if (ret) - return; - - if (clkmain->pms.status) - clk_sam9x5_main_prepare(hw); -} - static const struct clk_ops sam9x5_main_ops = { .prepare = clk_sam9x5_main_prepare, .is_prepared = clk_sam9x5_main_is_prepared, .recalc_rate = clk_sam9x5_main_recalc_rate, .set_parent = clk_sam9x5_main_set_parent, .get_parent = clk_sam9x5_main_get_parent, - .save_context = clk_sam9x5_main_save_context, - .restore_context = clk_sam9x5_main_restore_context, }; struct clk_hw * __init diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index b2d0a7f4f7..04d0dd8385 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -18,7 +17,15 @@ #define MASTER_DIV_SHIFT 8 #define MASTER_DIV_MASK 0x7 +#define PMC_MCR 0x30 +#define PMC_MCR_ID_MSK GENMASK(3, 0) +#define PMC_MCR_CMD BIT(7) +#define PMC_MCR_DIV GENMASK(10, 8) +#define PMC_MCR_CSS GENMASK(20, 16) #define PMC_MCR_CSS_SHIFT (16) +#define PMC_MCR_EN BIT(28) + +#define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK) #define MASTER_MAX_ID 4 @@ -30,19 +37,14 @@ struct clk_master { spinlock_t *lock; const struct clk_master_layout *layout; const struct clk_master_characteristics *characteristics; - struct at91_clk_pms pms; u32 *mux_table; u32 mckr; int chg_pid; u8 id; u8 parent; u8 div; - u32 safe_div; }; -/* MCK div reference to be used by notifier. */ -static struct clk_master *master_div; - static inline bool clk_master_ready(struct clk_master *master) { unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY; @@ -110,244 +112,97 @@ static unsigned long clk_master_div_recalc_rate(struct clk_hw *hw, return rate; } -static int clk_master_div_save_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - struct clk_hw *parent_hw = clk_hw_get_parent(hw); - unsigned long flags; - unsigned int mckr, div; - - spin_lock_irqsave(master->lock, flags); - regmap_read(master->regmap, master->layout->offset, &mckr); - spin_unlock_irqrestore(master->lock, flags); - - mckr &= master->layout->mask; - div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - div = master->characteristics->divisors[div]; - - master->pms.parent_rate = clk_hw_get_rate(parent_hw); - master->pms.rate = DIV_ROUND_CLOSEST(master->pms.parent_rate, div); - - return 0; -} - -static void clk_master_div_restore_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - unsigned long flags; - unsigned int mckr; - u8 div; - - spin_lock_irqsave(master->lock, flags); - regmap_read(master->regmap, master->layout->offset, &mckr); - spin_unlock_irqrestore(master->lock, flags); - - mckr &= master->layout->mask; - div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - div = master->characteristics->divisors[div]; - - if (div != DIV_ROUND_CLOSEST(master->pms.parent_rate, master->pms.rate)) - pr_warn("MCKR DIV not configured properly by firmware!\n"); -} - static const struct clk_ops master_div_ops = { .prepare = clk_master_prepare, .is_prepared = clk_master_is_prepared, .recalc_rate = clk_master_div_recalc_rate, - .save_context = clk_master_div_save_context, - .restore_context = clk_master_div_restore_context, }; -/* This function must be called with lock acquired. */ -static int clk_master_div_set(struct clk_master *master, - unsigned long parent_rate, int div) +static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) { + struct clk_master *master = to_clk_master(hw); const struct clk_master_characteristics *characteristics = master->characteristics; - unsigned long rate = parent_rate; - unsigned int max_div = 0, div_index = 0, max_div_index = 0; - unsigned int i, mckr, tmp; - int ret; + unsigned long flags; + int div, i; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + if (div > ARRAY_SIZE(characteristics->divisors)) + return -EINVAL; for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { if (!characteristics->divisors[i]) break; - if (div == characteristics->divisors[i]) - div_index = i; - - if (max_div < characteristics->divisors[i]) { - max_div = characteristics->divisors[i]; - max_div_index = i; + if (div == characteristics->divisors[i]) { + div = i; + break; } } - if (div > max_div) - div_index = max_div_index; - - ret = regmap_read(master->regmap, master->layout->offset, &mckr); - if (ret) - return ret; - - mckr &= master->layout->mask; - tmp = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - if (tmp == div_index) - return 0; - - rate /= characteristics->divisors[div_index]; - if (rate < characteristics->output.min) - pr_warn("master clk div is underclocked"); - else if (rate > characteristics->output.max) - pr_warn("master clk div is overclocked"); - - mckr &= ~(MASTER_DIV_MASK << MASTER_DIV_SHIFT); - mckr |= (div_index << MASTER_DIV_SHIFT); - ret = regmap_write(master->regmap, master->layout->offset, mckr); - if (ret) - return ret; + if (i == ARRAY_SIZE(characteristics->divisors)) + return -EINVAL; + spin_lock_irqsave(master->lock, flags); + regmap_update_bits(master->regmap, master->layout->offset, + (MASTER_DIV_MASK << MASTER_DIV_SHIFT), + (div << MASTER_DIV_SHIFT)); while (!clk_master_ready(master)) cpu_relax(); - - master->div = characteristics->divisors[div_index]; + spin_unlock_irqrestore(master->lock, flags); return 0; } -static unsigned long clk_master_div_recalc_rate_chg(struct clk_hw *hw, - unsigned long parent_rate) +static int clk_master_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_master *master = to_clk_master(hw); + const struct clk_master_characteristics *characteristics = + master->characteristics; + struct clk_hw *parent; + unsigned long parent_rate, tmp_rate, best_rate = 0; + int i, best_diff = INT_MIN, tmp_diff; - return DIV_ROUND_CLOSEST_ULL(parent_rate, master->div); -} + parent = clk_hw_get_parent(hw); + if (!parent) + return -EINVAL; -static void clk_master_div_restore_context_chg(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - unsigned long flags; - int ret; + parent_rate = clk_hw_get_rate(parent); + if (!parent_rate) + return -EINVAL; - spin_lock_irqsave(master->lock, flags); - ret = clk_master_div_set(master, master->pms.parent_rate, - DIV_ROUND_CLOSEST(master->pms.parent_rate, - master->pms.rate)); - spin_unlock_irqrestore(master->lock, flags); - if (ret) - pr_warn("Failed to restore MCK DIV clock\n"); + for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { + if (!characteristics->divisors[i]) + break; + + tmp_rate = DIV_ROUND_CLOSEST_ULL(parent_rate, + characteristics->divisors[i]); + tmp_diff = abs(tmp_rate - req->rate); + + if (!best_rate || best_diff > tmp_diff) { + best_diff = tmp_diff; + best_rate = tmp_rate; + } + + if (!best_diff) + break; + } + + req->best_parent_rate = best_rate; + req->best_parent_hw = parent; + req->rate = best_rate; + + return 0; } static const struct clk_ops master_div_ops_chg = { .prepare = clk_master_prepare, .is_prepared = clk_master_is_prepared, - .recalc_rate = clk_master_div_recalc_rate_chg, - .save_context = clk_master_div_save_context, - .restore_context = clk_master_div_restore_context_chg, -}; - -static int clk_master_div_notifier_fn(struct notifier_block *notifier, - unsigned long code, void *data) -{ - const struct clk_master_characteristics *characteristics = - master_div->characteristics; - struct clk_notifier_data *cnd = data; - unsigned long flags, new_parent_rate, new_rate; - unsigned int mckr, div, new_div = 0; - int ret, i; - long tmp_diff; - long best_diff = -1; - - spin_lock_irqsave(master_div->lock, flags); - switch (code) { - case PRE_RATE_CHANGE: - /* - * We want to avoid any overclocking of MCK DIV domain. To do - * this we set a safe divider (the underclocking is not of - * interest as we can go as low as 32KHz). The relation - * b/w this clock and its parents are as follows: - * - * FRAC PLL -> DIV PLL -> MCK DIV - * - * With the proper safe divider we should be good even with FRAC - * PLL at its maximum value. - */ - ret = regmap_read(master_div->regmap, master_div->layout->offset, - &mckr); - if (ret) { - ret = NOTIFY_STOP_MASK; - goto unlock; - } - - mckr &= master_div->layout->mask; - div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - - /* Switch to safe divider. */ - clk_master_div_set(master_div, - cnd->old_rate * characteristics->divisors[div], - master_div->safe_div); - break; - - case POST_RATE_CHANGE: - /* - * At this point we want to restore MCK DIV domain to its maximum - * allowed rate. - */ - ret = regmap_read(master_div->regmap, master_div->layout->offset, - &mckr); - if (ret) { - ret = NOTIFY_STOP_MASK; - goto unlock; - } - - mckr &= master_div->layout->mask; - div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - new_parent_rate = cnd->new_rate * characteristics->divisors[div]; - - for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { - if (!characteristics->divisors[i]) - break; - - new_rate = DIV_ROUND_CLOSEST_ULL(new_parent_rate, - characteristics->divisors[i]); - - tmp_diff = characteristics->output.max - new_rate; - if (tmp_diff < 0) - continue; - - if (best_diff < 0 || best_diff > tmp_diff) { - new_div = characteristics->divisors[i]; - best_diff = tmp_diff; - } - - if (!tmp_diff) - break; - } - - if (!new_div) { - ret = NOTIFY_STOP_MASK; - goto unlock; - } - - /* Update the div to preserve MCK DIV clock rate. */ - clk_master_div_set(master_div, new_parent_rate, - new_div); - - ret = NOTIFY_OK; - break; - - default: - ret = NOTIFY_DONE; - break; - } - -unlock: - spin_unlock_irqrestore(master_div->lock, flags); - - return ret; -} - -static struct notifier_block clk_master_div_notifier = { - .notifier_call = clk_master_div_notifier_fn, + .recalc_rate = clk_master_div_recalc_rate, + .determine_rate = clk_master_div_determine_rate, + .set_rate = clk_master_div_set_rate, }; static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, @@ -417,8 +272,7 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_master *master = to_clk_master(hw); unsigned long flags; - unsigned int pres, mckr, tmp; - int ret; + unsigned int pres; pres = DIV_ROUND_CLOSEST(parent_rate, rate); if (pres > MASTER_PRES_MAX) @@ -430,27 +284,15 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, pres = ffs(pres) - 1; spin_lock_irqsave(master->lock, flags); - ret = regmap_read(master->regmap, master->layout->offset, &mckr); - if (ret) - goto unlock; - - mckr &= master->layout->mask; - tmp = (mckr >> master->layout->pres_shift) & MASTER_PRES_MASK; - if (pres == tmp) - goto unlock; - - mckr &= ~(MASTER_PRES_MASK << master->layout->pres_shift); - mckr |= (pres << master->layout->pres_shift); - ret = regmap_write(master->regmap, master->layout->offset, mckr); - if (ret) - goto unlock; + regmap_update_bits(master->regmap, master->layout->offset, + (MASTER_PRES_MASK << master->layout->pres_shift), + (pres << master->layout->pres_shift)); while (!clk_master_ready(master)) cpu_relax(); -unlock: spin_unlock_irqrestore(master->lock, flags); - return ret; + return 0; } static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, @@ -466,7 +308,6 @@ static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, regmap_read(master->regmap, master->layout->offset, &val); spin_unlock_irqrestore(master->lock, flags); - val &= master->layout->mask; pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; if (pres == MASTER_PRES_MAX && characteristics->have_div3_pres) pres = 3; @@ -486,73 +327,14 @@ static u8 clk_master_pres_get_parent(struct clk_hw *hw) regmap_read(master->regmap, master->layout->offset, &mckr); spin_unlock_irqrestore(master->lock, flags); - mckr &= master->layout->mask; - return mckr & AT91_PMC_CSS; } -static int clk_master_pres_save_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - struct clk_hw *parent_hw = clk_hw_get_parent(hw); - unsigned long flags; - unsigned int val, pres; - - spin_lock_irqsave(master->lock, flags); - regmap_read(master->regmap, master->layout->offset, &val); - spin_unlock_irqrestore(master->lock, flags); - - val &= master->layout->mask; - pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; - if (pres == MASTER_PRES_MAX && master->characteristics->have_div3_pres) - pres = 3; - else - pres = (1 << pres); - - master->pms.parent = val & AT91_PMC_CSS; - master->pms.parent_rate = clk_hw_get_rate(parent_hw); - master->pms.rate = DIV_ROUND_CLOSEST_ULL(master->pms.parent_rate, pres); - - return 0; -} - -static void clk_master_pres_restore_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - unsigned long flags; - unsigned int val, pres; - - spin_lock_irqsave(master->lock, flags); - regmap_read(master->regmap, master->layout->offset, &val); - spin_unlock_irqrestore(master->lock, flags); - - val &= master->layout->mask; - pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; - if (pres == MASTER_PRES_MAX && master->characteristics->have_div3_pres) - pres = 3; - else - pres = (1 << pres); - - if (master->pms.rate != - DIV_ROUND_CLOSEST_ULL(master->pms.parent_rate, pres) || - (master->pms.parent != (val & AT91_PMC_CSS))) - pr_warn("MCKR PRES was not configured properly by firmware!\n"); -} - -static void clk_master_pres_restore_context_chg(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - - clk_master_pres_set_rate(hw, master->pms.rate, master->pms.parent_rate); -} - static const struct clk_ops master_pres_ops = { .prepare = clk_master_prepare, .is_prepared = clk_master_is_prepared, .recalc_rate = clk_master_pres_recalc_rate, .get_parent = clk_master_pres_get_parent, - .save_context = clk_master_pres_save_context, - .restore_context = clk_master_pres_restore_context, }; static const struct clk_ops master_pres_ops_chg = { @@ -562,8 +344,6 @@ static const struct clk_ops master_pres_ops_chg = { .recalc_rate = clk_master_pres_recalc_rate, .get_parent = clk_master_pres_get_parent, .set_rate = clk_master_pres_set_rate, - .save_context = clk_master_pres_save_context, - .restore_context = clk_master_pres_restore_context_chg, }; static struct clk_hw * __init @@ -578,8 +358,6 @@ at91_clk_register_master_internal(struct regmap *regmap, struct clk_master *master; struct clk_init_data init; struct clk_hw *hw; - unsigned int mckr; - unsigned long irqflags; int ret; if (!name || !num_parents || !parent_names || !lock) @@ -602,16 +380,6 @@ at91_clk_register_master_internal(struct regmap *regmap, master->chg_pid = chg_pid; master->lock = lock; - if (ops == &master_div_ops_chg) { - spin_lock_irqsave(master->lock, irqflags); - regmap_read(master->regmap, master->layout->offset, &mckr); - spin_unlock_irqrestore(master->lock, irqflags); - - mckr &= layout->mask; - mckr = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; - master->div = characteristics->divisors[mckr]; - } - hw = &master->hw; ret = clk_hw_register(NULL, &master->hw); if (ret) { @@ -648,29 +416,19 @@ at91_clk_register_master_div(struct regmap *regmap, const char *name, const char *parent_name, const struct clk_master_layout *layout, const struct clk_master_characteristics *characteristics, - spinlock_t *lock, u32 flags, u32 safe_div) + spinlock_t *lock, u32 flags) { const struct clk_ops *ops; - struct clk_hw *hw; if (flags & CLK_SET_RATE_GATE) ops = &master_div_ops; else ops = &master_div_ops_chg; - hw = at91_clk_register_master_internal(regmap, name, 1, - &parent_name, layout, - characteristics, ops, - lock, flags, -EINVAL); - - if (!IS_ERR(hw) && safe_div) { - master_div = to_clk_master(hw); - master_div->safe_div = safe_div; - clk_notifier_register(hw->clk, - &clk_master_div_notifier); - } - - return hw; + return at91_clk_register_master_internal(regmap, name, 1, + &parent_name, layout, + characteristics, ops, + lock, flags, -EINVAL); } static unsigned long @@ -781,40 +539,30 @@ static int clk_sama7g5_master_set_parent(struct clk_hw *hw, u8 index) return 0; } -static void clk_sama7g5_master_set(struct clk_master *master, - unsigned int status) +static int clk_sama7g5_master_enable(struct clk_hw *hw) { + struct clk_master *master = to_clk_master(hw); unsigned long flags; unsigned int val, cparent; - unsigned int enable = status ? AT91_PMC_MCR_V2_EN : 0; - unsigned int parent = master->parent << PMC_MCR_CSS_SHIFT; - unsigned int div = master->div << MASTER_DIV_SHIFT; spin_lock_irqsave(master->lock, flags); - regmap_write(master->regmap, AT91_PMC_MCR_V2, - AT91_PMC_MCR_V2_ID(master->id)); - regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); - regmap_update_bits(master->regmap, AT91_PMC_MCR_V2, - enable | AT91_PMC_MCR_V2_CSS | AT91_PMC_MCR_V2_DIV | - AT91_PMC_MCR_V2_CMD | AT91_PMC_MCR_V2_ID_MSK, - enable | parent | div | AT91_PMC_MCR_V2_CMD | - AT91_PMC_MCR_V2_ID(master->id)); + regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id)); + regmap_read(master->regmap, PMC_MCR, &val); + regmap_update_bits(master->regmap, PMC_MCR, + PMC_MCR_EN | PMC_MCR_CSS | PMC_MCR_DIV | + PMC_MCR_CMD | PMC_MCR_ID_MSK, + PMC_MCR_EN | (master->parent << PMC_MCR_CSS_SHIFT) | + (master->div << MASTER_DIV_SHIFT) | + PMC_MCR_CMD | PMC_MCR_ID(master->id)); - cparent = (val & AT91_PMC_MCR_V2_CSS) >> PMC_MCR_CSS_SHIFT; + cparent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; /* Wait here only if parent is being changed. */ while ((cparent != master->parent) && !clk_master_ready(master)) cpu_relax(); spin_unlock_irqrestore(master->lock, flags); -} - -static int clk_sama7g5_master_enable(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - - clk_sama7g5_master_set(master, 1); return 0; } @@ -826,12 +574,10 @@ static void clk_sama7g5_master_disable(struct clk_hw *hw) spin_lock_irqsave(master->lock, flags); - regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); - regmap_update_bits(master->regmap, AT91_PMC_MCR_V2, - AT91_PMC_MCR_V2_EN | AT91_PMC_MCR_V2_CMD | - AT91_PMC_MCR_V2_ID_MSK, - AT91_PMC_MCR_V2_CMD | - AT91_PMC_MCR_V2_ID(master->id)); + regmap_write(master->regmap, PMC_MCR, master->id); + regmap_update_bits(master->regmap, PMC_MCR, + PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK, + PMC_MCR_CMD | PMC_MCR_ID(master->id)); spin_unlock_irqrestore(master->lock, flags); } @@ -844,12 +590,12 @@ static int clk_sama7g5_master_is_enabled(struct clk_hw *hw) spin_lock_irqsave(master->lock, flags); - regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); - regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); + regmap_write(master->regmap, PMC_MCR, master->id); + regmap_read(master->regmap, PMC_MCR, &val); spin_unlock_irqrestore(master->lock, flags); - return !!(val & AT91_PMC_MCR_V2_EN); + return !!(val & PMC_MCR_EN); } static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, @@ -874,23 +620,6 @@ static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_sama7g5_master_save_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - - master->pms.status = clk_sama7g5_master_is_enabled(hw); - - return 0; -} - -static void clk_sama7g5_master_restore_context(struct clk_hw *hw) -{ - struct clk_master *master = to_clk_master(hw); - - if (master->pms.status) - clk_sama7g5_master_set(master, master->pms.status); -} - static const struct clk_ops sama7g5_master_ops = { .enable = clk_sama7g5_master_enable, .disable = clk_sama7g5_master_disable, @@ -900,8 +629,6 @@ static const struct clk_ops sama7g5_master_ops = { .set_rate = clk_sama7g5_master_set_rate, .get_parent = clk_sama7g5_master_get_parent, .set_parent = clk_sama7g5_master_set_parent, - .save_context = clk_sama7g5_master_save_context, - .restore_context = clk_sama7g5_master_restore_context, }; struct clk_hw * __init @@ -945,10 +672,10 @@ at91_clk_sama7g5_register_master(struct regmap *regmap, master->mux_table = mux_table; spin_lock_irqsave(master->lock, flags); - regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); - regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); - master->parent = (val & AT91_PMC_MCR_V2_CSS) >> PMC_MCR_CSS_SHIFT; - master->div = (val & AT91_PMC_MCR_V2_DIV) >> MASTER_DIV_SHIFT; + regmap_write(master->regmap, PMC_MCR, master->id); + regmap_read(master->regmap, PMC_MCR, &val); + master->parent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; + master->div = (val & PMC_MCR_DIV) >> MASTER_DIV_SHIFT; spin_unlock_irqrestore(master->lock, flags); hw = &master->hw; diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index e14fa5ac73..7a27ba8e05 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -37,7 +37,6 @@ struct clk_sam9x5_peripheral { u32 id; u32 div; const struct clk_pcr_layout *layout; - struct at91_clk_pms pms; bool auto_div; int chg_pid; }; @@ -156,11 +155,10 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) periph->div = shift; } -static int clk_sam9x5_peripheral_set(struct clk_sam9x5_peripheral *periph, - unsigned int status) +static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) { + struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); unsigned long flags; - unsigned int enable = status ? AT91_PMC_PCR_EN : 0; if (periph->id < PERIPHERAL_ID_MIN) return 0; @@ -170,21 +168,15 @@ static int clk_sam9x5_peripheral_set(struct clk_sam9x5_peripheral *periph, (periph->id & periph->layout->pid_mask)); regmap_update_bits(periph->regmap, periph->layout->offset, periph->layout->div_mask | periph->layout->cmd | - enable, + AT91_PMC_PCR_EN, field_prep(periph->layout->div_mask, periph->div) | - periph->layout->cmd | enable); + periph->layout->cmd | + AT91_PMC_PCR_EN); spin_unlock_irqrestore(periph->lock, flags); return 0; } -static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) -{ - struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - - return clk_sam9x5_peripheral_set(periph, 1); -} - static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) { struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); @@ -401,23 +393,6 @@ static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw, return -EINVAL; } -static int clk_sam9x5_peripheral_save_context(struct clk_hw *hw) -{ - struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - - periph->pms.status = clk_sam9x5_peripheral_is_enabled(hw); - - return 0; -} - -static void clk_sam9x5_peripheral_restore_context(struct clk_hw *hw) -{ - struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - - if (periph->pms.status) - clk_sam9x5_peripheral_set(periph, periph->pms.status); -} - static const struct clk_ops sam9x5_peripheral_ops = { .enable = clk_sam9x5_peripheral_enable, .disable = clk_sam9x5_peripheral_disable, @@ -425,8 +400,6 @@ static const struct clk_ops sam9x5_peripheral_ops = { .recalc_rate = clk_sam9x5_peripheral_recalc_rate, .round_rate = clk_sam9x5_peripheral_round_rate, .set_rate = clk_sam9x5_peripheral_set_rate, - .save_context = clk_sam9x5_peripheral_save_context, - .restore_context = clk_sam9x5_peripheral_restore_context, }; static const struct clk_ops sam9x5_peripheral_chg_ops = { @@ -436,8 +409,6 @@ static const struct clk_ops sam9x5_peripheral_chg_ops = { .recalc_rate = clk_sam9x5_peripheral_recalc_rate, .determine_rate = clk_sam9x5_peripheral_determine_rate, .set_rate = clk_sam9x5_peripheral_set_rate, - .save_context = clk_sam9x5_peripheral_save_context, - .restore_context = clk_sam9x5_peripheral_restore_context, }; struct clk_hw * __init @@ -489,6 +460,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, hw = ERR_PTR(ret); } else { clk_sam9x5_peripheral_autodiv(periph); + pmc_register_id(id); } return hw; diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 249d6a53ce..6ed986d3ee 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -40,7 +40,6 @@ struct clk_pll { u16 mul; const struct clk_pll_layout *layout; const struct clk_pll_characteristics *characteristics; - struct at91_clk_pms pms; }; static inline bool clk_pll_ready(struct regmap *regmap, int id) @@ -261,42 +260,6 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_pll_save_context(struct clk_hw *hw) -{ - struct clk_pll *pll = to_clk_pll(hw); - struct clk_hw *parent_hw = clk_hw_get_parent(hw); - - pll->pms.parent_rate = clk_hw_get_rate(parent_hw); - pll->pms.rate = clk_pll_recalc_rate(&pll->hw, pll->pms.parent_rate); - pll->pms.status = clk_pll_ready(pll->regmap, PLL_REG(pll->id)); - - return 0; -} - -static void clk_pll_restore_context(struct clk_hw *hw) -{ - struct clk_pll *pll = to_clk_pll(hw); - unsigned long calc_rate; - unsigned int pllr, pllr_out, pllr_count; - u8 out = 0; - - if (pll->characteristics->out) - out = pll->characteristics->out[pll->range]; - - regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); - - calc_rate = (pll->pms.parent_rate / PLL_DIV(pllr)) * - (PLL_MUL(pllr, pll->layout) + 1); - pllr_count = (pllr >> PLL_COUNT_SHIFT) & PLL_MAX_COUNT; - pllr_out = (pllr >> PLL_OUT_SHIFT) & out; - - if (pll->pms.rate != calc_rate || - pll->pms.status != clk_pll_ready(pll->regmap, PLL_REG(pll->id)) || - pllr_count != PLL_MAX_COUNT || - (out && pllr_out != out)) - pr_warn("PLLAR was not configured properly by firmware\n"); -} - static const struct clk_ops pll_ops = { .prepare = clk_pll_prepare, .unprepare = clk_pll_unprepare, @@ -304,8 +267,6 @@ static const struct clk_ops pll_ops = { .recalc_rate = clk_pll_recalc_rate, .round_rate = clk_pll_round_rate, .set_rate = clk_pll_set_rate, - .save_context = clk_pll_save_context, - .restore_context = clk_pll_restore_context, }; struct clk_hw * __init diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 6c4b259d31..fcf8f6a1c2 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -24,7 +24,6 @@ struct clk_programmable { u32 *mux_table; u8 id; const struct clk_programmable_layout *layout; - struct at91_clk_pms pms; }; #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw) @@ -178,38 +177,12 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int clk_programmable_save_context(struct clk_hw *hw) -{ - struct clk_programmable *prog = to_clk_programmable(hw); - struct clk_hw *parent_hw = clk_hw_get_parent(hw); - - prog->pms.parent = clk_programmable_get_parent(hw); - prog->pms.parent_rate = clk_hw_get_rate(parent_hw); - prog->pms.rate = clk_programmable_recalc_rate(hw, prog->pms.parent_rate); - - return 0; -} - -static void clk_programmable_restore_context(struct clk_hw *hw) -{ - struct clk_programmable *prog = to_clk_programmable(hw); - int ret; - - ret = clk_programmable_set_parent(hw, prog->pms.parent); - if (ret) - return; - - clk_programmable_set_rate(hw, prog->pms.rate, prog->pms.parent_rate); -} - static const struct clk_ops programmable_ops = { .recalc_rate = clk_programmable_recalc_rate, .determine_rate = clk_programmable_determine_rate, .get_parent = clk_programmable_get_parent, .set_parent = clk_programmable_set_parent, .set_rate = clk_programmable_set_rate, - .save_context = clk_programmable_save_context, - .restore_context = clk_programmable_restore_context, }; struct clk_hw * __init @@ -248,6 +221,8 @@ at91_clk_register_programmable(struct regmap *regmap, if (ret) { kfree(prog); hw = ERR_PTR(ret); + } else { + pmc_register_pck(id); } return hw; diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index d757003004..1f52409475 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -5,7 +5,6 @@ */ #include -#include #include #include #include @@ -39,24 +38,19 @@ struct sam9x60_pll_core { struct sam9x60_frac { struct sam9x60_pll_core core; - struct at91_clk_pms pms; u32 frac; u16 mul; }; struct sam9x60_div { struct sam9x60_pll_core core; - struct at91_clk_pms pms; u8 div; - u8 safe_div; }; #define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw) #define to_sam9x60_frac(core) container_of(core, struct sam9x60_frac, core) #define to_sam9x60_div(core) container_of(core, struct sam9x60_div, core) -static struct sam9x60_div *notifier_div; - static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) { unsigned int status; @@ -81,8 +75,9 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw, DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22)); } -static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) +static int sam9x60_frac_pll_prepare(struct clk_hw *hw) { + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); struct sam9x60_frac *frac = to_sam9x60_frac(core); struct regmap *regmap = core->regmap; unsigned int val, cfrac, cmul; @@ -146,13 +141,6 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) return 0; } -static int sam9x60_frac_pll_prepare(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - - return sam9x60_frac_pll_set(core); -} - static void sam9x60_frac_pll_unprepare(struct clk_hw *hw) { struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); @@ -292,25 +280,6 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, return ret; } -static int sam9x60_frac_pll_save_context(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - struct sam9x60_frac *frac = to_sam9x60_frac(core); - - frac->pms.status = sam9x60_pll_ready(core->regmap, core->id); - - return 0; -} - -static void sam9x60_frac_pll_restore_context(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - struct sam9x60_frac *frac = to_sam9x60_frac(core); - - if (frac->pms.status) - sam9x60_frac_pll_set(core); -} - static const struct clk_ops sam9x60_frac_pll_ops = { .prepare = sam9x60_frac_pll_prepare, .unprepare = sam9x60_frac_pll_unprepare, @@ -318,8 +287,6 @@ static const struct clk_ops sam9x60_frac_pll_ops = { .recalc_rate = sam9x60_frac_pll_recalc_rate, .round_rate = sam9x60_frac_pll_round_rate, .set_rate = sam9x60_frac_pll_set_rate, - .save_context = sam9x60_frac_pll_save_context, - .restore_context = sam9x60_frac_pll_restore_context, }; static const struct clk_ops sam9x60_frac_pll_ops_chg = { @@ -329,32 +296,11 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { .recalc_rate = sam9x60_frac_pll_recalc_rate, .round_rate = sam9x60_frac_pll_round_rate, .set_rate = sam9x60_frac_pll_set_rate_chg, - .save_context = sam9x60_frac_pll_save_context, - .restore_context = sam9x60_frac_pll_restore_context, }; -/* This function should be called with spinlock acquired. */ -static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, - bool enable) -{ - struct regmap *regmap = core->regmap; - u32 ena_msk = enable ? core->layout->endiv_mask : 0; - u32 ena_val = enable ? (1 << core->layout->endiv_shift) : 0; - - regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, - core->layout->div_mask | ena_msk, - (div << core->layout->div_shift) | ena_val); - - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, - AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, - AT91_PMC_PLL_UPDT_UPDATE | core->id); - - while (!sam9x60_pll_ready(regmap, core->id)) - cpu_relax(); -} - -static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) +static int sam9x60_div_pll_prepare(struct clk_hw *hw) { + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); struct sam9x60_div *div = to_sam9x60_div(core); struct regmap *regmap = core->regmap; unsigned long flags; @@ -370,7 +316,17 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) if (!!(val & core->layout->endiv_mask) && cdiv == div->div) goto unlock; - sam9x60_div_pll_set_div(core, div->div, 1); + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, + core->layout->div_mask | core->layout->endiv_mask, + (div->div << core->layout->div_shift) | + (1 << core->layout->endiv_shift)); + + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); + + while (!sam9x60_pll_ready(regmap, core->id)) + cpu_relax(); unlock: spin_unlock_irqrestore(core->lock, flags); @@ -378,13 +334,6 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) return 0; } -static int sam9x60_div_pll_prepare(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - - return sam9x60_div_pll_set(core); -} - static void sam9x60_div_pll_unprepare(struct clk_hw *hw) { struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); @@ -516,7 +465,16 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, if (cdiv == div->div) goto unlock; - sam9x60_div_pll_set_div(core, div->div, 0); + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, + core->layout->div_mask, + (div->div << core->layout->div_shift)); + + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, + AT91_PMC_PLL_UPDT_UPDATE | core->id); + + while (!sam9x60_pll_ready(regmap, core->id)) + cpu_relax(); unlock: spin_unlock_irqrestore(core->lock, irqflags); @@ -524,67 +482,6 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, return 0; } -static int sam9x60_div_pll_save_context(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - struct sam9x60_div *div = to_sam9x60_div(core); - - div->pms.status = sam9x60_div_pll_is_prepared(hw); - - return 0; -} - -static void sam9x60_div_pll_restore_context(struct clk_hw *hw) -{ - struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); - struct sam9x60_div *div = to_sam9x60_div(core); - - if (div->pms.status) - sam9x60_div_pll_set(core); -} - -static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier, - unsigned long code, void *data) -{ - struct sam9x60_div *div = notifier_div; - struct sam9x60_pll_core core = div->core; - struct regmap *regmap = core.regmap; - unsigned long irqflags; - u32 val, cdiv; - int ret = NOTIFY_DONE; - - if (code != PRE_RATE_CHANGE) - return ret; - - /* - * We switch to safe divider to avoid overclocking of other domains - * feed by us while the frac PLL (our parent) is changed. - */ - div->div = div->safe_div; - - spin_lock_irqsave(core.lock, irqflags); - regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, - core.id); - regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); - cdiv = (val & core.layout->div_mask) >> core.layout->div_shift; - - /* Stop if nothing changed. */ - if (cdiv == div->safe_div) - goto unlock; - - sam9x60_div_pll_set_div(&core, div->div, 0); - ret = NOTIFY_OK; - -unlock: - spin_unlock_irqrestore(core.lock, irqflags); - - return ret; -} - -static struct notifier_block sam9x60_div_pll_notifier = { - .notifier_call = sam9x60_div_pll_notifier_fn, -}; - static const struct clk_ops sam9x60_div_pll_ops = { .prepare = sam9x60_div_pll_prepare, .unprepare = sam9x60_div_pll_unprepare, @@ -592,8 +489,6 @@ static const struct clk_ops sam9x60_div_pll_ops = { .recalc_rate = sam9x60_div_pll_recalc_rate, .round_rate = sam9x60_div_pll_round_rate, .set_rate = sam9x60_div_pll_set_rate, - .save_context = sam9x60_div_pll_save_context, - .restore_context = sam9x60_div_pll_restore_context, }; static const struct clk_ops sam9x60_div_pll_ops_chg = { @@ -603,8 +498,6 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = { .recalc_rate = sam9x60_div_pll_recalc_rate, .round_rate = sam9x60_div_pll_round_rate, .set_rate = sam9x60_div_pll_set_rate_chg, - .save_context = sam9x60_div_pll_save_context, - .restore_context = sam9x60_div_pll_restore_context, }; struct clk_hw * __init @@ -694,8 +587,7 @@ struct clk_hw * __init sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, const char *name, const char *parent_name, u8 id, const struct clk_pll_characteristics *characteristics, - const struct clk_pll_layout *layout, u32 flags, - u32 safe_div) + const struct clk_pll_layout *layout, u32 flags) { struct sam9x60_div *div; struct clk_hw *hw; @@ -704,13 +596,9 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, unsigned int val; int ret; - /* We only support one changeable PLL. */ - if (id > PLL_MAX_ID || !lock || (safe_div && notifier_div)) + if (id > PLL_MAX_ID || !lock) return ERR_PTR(-EINVAL); - if (safe_div >= PLL_DIV_MAX) - safe_div = PLL_DIV_MAX - 1; - div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) return ERR_PTR(-ENOMEM); @@ -730,7 +618,6 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, div->core.layout = layout; div->core.regmap = regmap; div->core.lock = lock; - div->safe_div = safe_div; spin_lock_irqsave(div->core.lock, irqflags); @@ -746,9 +633,6 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, if (ret) { kfree(div); hw = ERR_PTR(ret); - } else if (div->safe_div) { - notifier_div = div; - clk_notifier_register(hw->clk, &sam9x60_div_pll_notifier); } return hw; diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 80720fd1a9..f83ec0de86 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c @@ -20,7 +20,6 @@ struct clk_system { struct clk_hw hw; struct regmap *regmap; - struct at91_clk_pms pms; u8 id; }; @@ -78,29 +77,10 @@ static int clk_system_is_prepared(struct clk_hw *hw) return !!(status & (1 << sys->id)); } -static int clk_system_save_context(struct clk_hw *hw) -{ - struct clk_system *sys = to_clk_system(hw); - - sys->pms.status = clk_system_is_prepared(hw); - - return 0; -} - -static void clk_system_restore_context(struct clk_hw *hw) -{ - struct clk_system *sys = to_clk_system(hw); - - if (sys->pms.status) - clk_system_prepare(&sys->hw); -} - static const struct clk_ops system_ops = { .prepare = clk_system_prepare, .unprepare = clk_system_unprepare, .is_prepared = clk_system_is_prepared, - .save_context = clk_system_save_context, - .restore_context = clk_system_restore_context, }; struct clk_hw * __init diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index b0696a928a..31d5c45e30 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -24,7 +24,6 @@ struct at91sam9x5_clk_usb { struct clk_hw hw; struct regmap *regmap; - struct at91_clk_pms pms; u32 usbs_mask; u8 num_parents; }; @@ -149,38 +148,12 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static int at91sam9x5_usb_save_context(struct clk_hw *hw) -{ - struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct clk_hw *parent_hw = clk_hw_get_parent(hw); - - usb->pms.parent = at91sam9x5_clk_usb_get_parent(hw); - usb->pms.parent_rate = clk_hw_get_rate(parent_hw); - usb->pms.rate = at91sam9x5_clk_usb_recalc_rate(hw, usb->pms.parent_rate); - - return 0; -} - -static void at91sam9x5_usb_restore_context(struct clk_hw *hw) -{ - struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - int ret; - - ret = at91sam9x5_clk_usb_set_parent(hw, usb->pms.parent); - if (ret) - return; - - at91sam9x5_clk_usb_set_rate(hw, usb->pms.rate, usb->pms.parent_rate); -} - static const struct clk_ops at91sam9x5_usb_ops = { .recalc_rate = at91sam9x5_clk_usb_recalc_rate, .determine_rate = at91sam9x5_clk_usb_determine_rate, .get_parent = at91sam9x5_clk_usb_get_parent, .set_parent = at91sam9x5_clk_usb_set_parent, .set_rate = at91sam9x5_clk_usb_set_rate, - .save_context = at91sam9x5_usb_save_context, - .restore_context = at91sam9x5_usb_restore_context, }; static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c index a22c10d9a1..df9f3fc3b6 100644 --- a/drivers/clk/at91/clk-utmi.c +++ b/drivers/clk/at91/clk-utmi.c @@ -23,7 +23,6 @@ struct clk_utmi { struct clk_hw hw; struct regmap *regmap_pmc; struct regmap *regmap_sfr; - struct at91_clk_pms pms; }; #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) @@ -114,30 +113,11 @@ static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, return UTMI_RATE; } -static int clk_utmi_save_context(struct clk_hw *hw) -{ - struct clk_utmi *utmi = to_clk_utmi(hw); - - utmi->pms.status = clk_utmi_is_prepared(hw); - - return 0; -} - -static void clk_utmi_restore_context(struct clk_hw *hw) -{ - struct clk_utmi *utmi = to_clk_utmi(hw); - - if (utmi->pms.status) - clk_utmi_prepare(hw); -} - static const struct clk_ops utmi_ops = { .prepare = clk_utmi_prepare, .unprepare = clk_utmi_unprepare, .is_prepared = clk_utmi_is_prepared, .recalc_rate = clk_utmi_recalc_rate, - .save_context = clk_utmi_save_context, - .restore_context = clk_utmi_restore_context, }; static struct clk_hw * __init @@ -252,29 +232,10 @@ static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw) return 0; } -static int clk_utmi_sama7g5_save_context(struct clk_hw *hw) -{ - struct clk_utmi *utmi = to_clk_utmi(hw); - - utmi->pms.status = clk_utmi_sama7g5_is_prepared(hw); - - return 0; -} - -static void clk_utmi_sama7g5_restore_context(struct clk_hw *hw) -{ - struct clk_utmi *utmi = to_clk_utmi(hw); - - if (utmi->pms.status) - clk_utmi_sama7g5_prepare(hw); -} - static const struct clk_ops sama7g5_utmi_ops = { .prepare = clk_utmi_sama7g5_prepare, .is_prepared = clk_utmi_sama7g5_is_prepared, .recalc_rate = clk_utmi_recalc_rate, - .save_context = clk_utmi_sama7g5_save_context, - .restore_context = clk_utmi_sama7g5_restore_context, }; struct clk_hw * __init diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c index ca2dbb65b9..a97b99c2dc 100644 --- a/drivers/clk/at91/dt-compat.c +++ b/drivers/clk/at91/dt-compat.c @@ -399,7 +399,7 @@ of_at91_clk_master_setup(struct device_node *np, hw = at91_clk_register_master_div(regmap, name, "masterck_pres", layout, characteristics, - &mck_lock, CLK_SET_RATE_GATE, 0); + &mck_lock, CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto out_free_characteristics; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 5aa9c1f1c8..b40035b011 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -3,12 +3,10 @@ * Copyright (C) 2013 Boris BREZILLON */ -#include #include #include #include #include -#include #include #include #include @@ -16,6 +14,8 @@ #include +#include + #include "pmc.h" #define PMC_MAX_IDS 128 @@ -111,46 +111,151 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, } #ifdef CONFIG_PM +static struct regmap *pmcreg; -/* Address in SECURAM that say if we suspend to backup mode. */ -static void __iomem *at91_pmc_backup_suspend; +static u8 registered_ids[PMC_MAX_IDS]; +static u8 registered_pcks[PMC_MAX_PCKS]; -static int at91_pmc_suspend(void) +static struct { - unsigned int backup; + u32 scsr; + u32 pcsr0; + u32 uckr; + u32 mor; + u32 mcfr; + u32 pllar; + u32 mckr; + u32 usb; + u32 imr; + u32 pcsr1; + u32 pcr[PMC_MAX_IDS]; + u32 audio_pll0; + u32 audio_pll1; + u32 pckr[PMC_MAX_PCKS]; +} pmc_cache; - if (!at91_pmc_backup_suspend) - return 0; +/* + * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored + * without alteration in the table, and 0 is for unused clocks. + */ +void pmc_register_id(u8 id) +{ + int i; - backup = readl_relaxed(at91_pmc_backup_suspend); - if (!backup) - return 0; - - return clk_save_context(); + for (i = 0; i < PMC_MAX_IDS; i++) { + if (registered_ids[i] == 0) { + registered_ids[i] = id; + break; + } + if (registered_ids[i] == id) + break; + } } -static void at91_pmc_resume(void) +/* + * As Programmable Clock 0 is valid on AT91 chips, there is an offset + * of 1 between the stored value and the real clock ID. + */ +void pmc_register_pck(u8 pck) { - unsigned int backup; + int i; - if (!at91_pmc_backup_suspend) - return; + for (i = 0; i < PMC_MAX_PCKS; i++) { + if (registered_pcks[i] == 0) { + registered_pcks[i] = pck + 1; + break; + } + if (registered_pcks[i] == (pck + 1)) + break; + } +} - backup = readl_relaxed(at91_pmc_backup_suspend); - if (!backup) - return; +static int pmc_suspend(void) +{ + int i; + u8 num; - clk_restore_context(); + regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr); + regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0); + regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr); + regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor); + regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr); + regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar); + regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr); + regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb); + regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr); + regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1); + + for (i = 0; registered_ids[i]; i++) { + regmap_write(pmcreg, AT91_PMC_PCR, + (registered_ids[i] & AT91_PMC_PCR_PID_MASK)); + regmap_read(pmcreg, AT91_PMC_PCR, + &pmc_cache.pcr[registered_ids[i]]); + } + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]); + } + + return 0; +} + +static bool pmc_ready(unsigned int mask) +{ + unsigned int status; + + regmap_read(pmcreg, AT91_PMC_SR, &status); + + return ((status & mask) == mask) ? 1 : 0; +} + +static void pmc_resume(void) +{ + int i; + u8 num; + u32 tmp; + u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA; + + regmap_read(pmcreg, AT91_PMC_MCKR, &tmp); + if (pmc_cache.mckr != tmp) + pr_warn("MCKR was not configured properly by the firmware\n"); + regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp); + if (pmc_cache.pllar != tmp) + pr_warn("PLLAR was not configured properly by the firmware\n"); + + regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr); + regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0); + regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr); + regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor); + regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr); + regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb); + regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr); + regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1); + + for (i = 0; registered_ids[i]; i++) { + regmap_write(pmcreg, AT91_PMC_PCR, + pmc_cache.pcr[registered_ids[i]] | + AT91_PMC_PCR_CMD); + } + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]); + } + + if (pmc_cache.uckr & AT91_PMC_UPLLEN) + mask |= AT91_PMC_LOCKU; + + while (!pmc_ready(mask)) + cpu_relax(); } static struct syscore_ops pmc_syscore_ops = { - .suspend = at91_pmc_suspend, - .resume = at91_pmc_resume, + .suspend = pmc_suspend, + .resume = pmc_resume, }; -static const struct of_device_id pmc_dt_ids[] = { +static const struct of_device_id sama5d2_pmc_dt_ids[] = { { .compatible = "atmel,sama5d2-pmc" }, - { .compatible = "microchip,sama7g5-pmc", }, { /* sentinel */ } }; @@ -158,7 +263,7 @@ static int __init pmc_register_ops(void) { struct device_node *np; - np = of_find_matching_node(NULL, pmc_dt_ids); + np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); if (!np) return -ENODEV; @@ -166,23 +271,11 @@ static int __init pmc_register_ops(void) of_node_put(np); return -ENODEV; } + + pmcreg = device_node_to_regmap(np); of_node_put(np); - - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); - if (!np) - return -ENODEV; - - if (!of_device_is_available(np)) { - of_node_put(np); - return -ENODEV; - } - of_node_put(np); - - at91_pmc_backup_suspend = of_iomap(np, 0); - if (!at91_pmc_backup_suspend) { - pr_warn("%s(): unable to map securam\n", __func__); - return -ENOMEM; - } + if (IS_ERR(pmcreg)) + return PTR_ERR(pmcreg); register_syscore_ops(&pmc_syscore_ops); diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 3a1bf6194c..a49076c804 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -13,8 +13,6 @@ #include #include -#include - extern spinlock_t pmc_pcr_lock; struct pmc_data { @@ -100,20 +98,6 @@ struct clk_pcr_layout { u32 pid_mask; }; -/** - * struct at91_clk_pms - Power management state for AT91 clock - * @rate: clock rate - * @parent_rate: clock parent rate - * @status: clock status (enabled or disabled) - * @parent: clock parent index - */ -struct at91_clk_pms { - unsigned long rate; - unsigned long parent_rate; - unsigned int status; - unsigned int parent; -}; - #define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) #define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) @@ -182,7 +166,7 @@ at91_clk_register_master_div(struct regmap *regmap, const char *name, const char *parent_names, const struct clk_master_layout *layout, const struct clk_master_characteristics *characteristics, - spinlock_t *lock, u32 flags, u32 safe_div); + spinlock_t *lock, u32 flags); struct clk_hw * __init at91_clk_sama7g5_register_master(struct regmap *regmap, @@ -214,8 +198,7 @@ struct clk_hw * __init sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, const char *name, const char *parent_name, u8 id, const struct clk_pll_characteristics *characteristics, - const struct clk_pll_layout *layout, u32 flags, - u32 safe_div); + const struct clk_pll_layout *layout, u32 flags); struct clk_hw * __init sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, @@ -265,4 +248,12 @@ struct clk_hw * __init at91_clk_sama7g5_register_utmi(struct regmap *regmap, const char *name, const char *parent_name); +#ifdef CONFIG_PM +void pmc_register_id(u8 id); +void pmc_register_pck(u8 pck); +#else +static inline void pmc_register_id(u8 id) {} +static inline void pmc_register_pck(u8 pck) {} +#endif + #endif /* __PMC_H_ */ diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index 5c264185f2..5f6fa89571 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -242,7 +242,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) * This feeds CPU. It should not * be disabled. */ - CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0); + CLK_IS_CRITICAL | CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; @@ -260,7 +260,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) &pll_div_layout, CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | - CLK_SET_RATE_PARENT, 0); + CLK_SET_RATE_PARENT); if (IS_ERR(hw)) goto err_free; @@ -279,7 +279,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) hw = at91_clk_register_master_div(regmap, "masterck_div", "masterck_pres", &sam9x60_master_layout, &mck_characteristics, &mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c index d027294a00..3d1f78176c 100644 --- a/drivers/clk/at91/sama5d2.c +++ b/drivers/clk/at91/sama5d2.c @@ -249,7 +249,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) "masterck_pres", &at91sam9x5_master_layout, &mck_characteristics, &mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c index 339d0f382f..d376257807 100644 --- a/drivers/clk/at91/sama5d3.c +++ b/drivers/clk/at91/sama5d3.c @@ -184,7 +184,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) "masterck_pres", &at91sam9x5_master_layout, &mck_characteristics, &mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c index 4af75b1e39..5cbaac68da 100644 --- a/drivers/clk/at91/sama5d4.c +++ b/drivers/clk/at91/sama5d4.c @@ -199,7 +199,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) "masterck_pres", &at91sam9x5_master_layout, &mck_characteristics, &mck_lock, - CLK_SET_RATE_GATE, 0); + CLK_SET_RATE_GATE); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c index 369dfafabb..019e712f90 100644 --- a/drivers/clk/at91/sama7g5.c +++ b/drivers/clk/at91/sama7g5.c @@ -127,8 +127,6 @@ static const struct clk_pll_characteristics pll_characteristics = { * @t: clock type * @f: clock flags * @eid: export index in sama7g5->chws[] array - * @safe_div: intermediate divider need to be set on PRE_RATE_CHANGE - * notification */ static const struct { const char *n; @@ -138,7 +136,6 @@ static const struct { unsigned long f; u8 t; u8 eid; - u8 safe_div; } sama7g5_plls[][PLL_ID_MAX] = { [PLL_ID_CPU] = { { .n = "cpupll_fracck", @@ -159,12 +156,7 @@ static const struct { .t = PLL_TYPE_DIV, /* This feeds CPU. It should not be disabled. */ .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, - .eid = PMC_CPUPLL, - /* - * Safe div=15 should be safe even for switching b/w 1GHz and - * 90MHz (frac pll might go up to 1.2GHz). - */ - .safe_div = 15, }, + .eid = PMC_CPUPLL, }, }, [PLL_ID_SYS] = { @@ -385,7 +377,6 @@ static const struct { u8 id; } sama7g5_periphck[] = { { .n = "pioA_clk", .p = "mck0", .id = 11, }, - { .n = "securam_clk", .p = "mck0", .id = 18, }, { .n = "sfr_clk", .p = "mck1", .id = 19, }, { .n = "hsmc_clk", .p = "mck1", .id = 21, }, { .n = "xdmac0_clk", .p = "mck1", .id = 22, }, @@ -850,7 +841,7 @@ static const struct { /* MCK0 characteristics. */ static const struct clk_master_characteristics mck0_characteristics = { - .output = { .min = 32768, .max = 200000000 }, + .output = { .min = 50000000, .max = 200000000 }, .divisors = { 1, 2, 4, 3, 5 }, .have_div3_pres = 1, }; @@ -975,8 +966,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) sama7g5_plls[i][j].p, i, sama7g5_plls[i][j].c, sama7g5_plls[i][j].l, - sama7g5_plls[i][j].f, - sama7g5_plls[i][j].safe_div); + sama7g5_plls[i][j].f); break; default: @@ -994,7 +984,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) parent_names[0] = "cpupll_divpmcck"; hw = at91_clk_register_master_div(regmap, "mck0", "cpupll_divpmcck", &mck0_layout, &mck0_characteristics, - &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5); + &pmc_mck0_lock, 0); if (IS_ERR(hw)) goto err_free; diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index b9c5f904f5..510a996563 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -42,29 +42,6 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, return rate_ops->recalc_rate(rate_hw, parent_rate); } -static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw, - struct clk_rate_request *req, - struct clk_hw *parent_hw, - const struct clk_ops *rate_ops) -{ - long rate; - - req->best_parent_hw = parent_hw; - req->best_parent_rate = clk_hw_get_rate(parent_hw); - - if (rate_ops->determine_rate) - return rate_ops->determine_rate(rate_hw, req); - - rate = rate_ops->round_rate(rate_hw, req->rate, - &req->best_parent_rate); - if (rate < 0) - return rate; - - req->rate = rate; - - return 0; -} - static int clk_composite_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -74,57 +51,51 @@ static int clk_composite_determine_rate(struct clk_hw *hw, struct clk_hw *rate_hw = composite->rate_hw; struct clk_hw *mux_hw = composite->mux_hw; struct clk_hw *parent; + unsigned long parent_rate; + long tmp_rate, best_rate = 0; unsigned long rate_diff; unsigned long best_rate_diff = ULONG_MAX; - unsigned long best_rate = 0; - int i, ret; + long rate; + int i; - if (rate_hw && rate_ops && - (rate_ops->determine_rate || rate_ops->round_rate) && + if (rate_hw && rate_ops && rate_ops->round_rate && mux_hw && mux_ops && mux_ops->set_parent) { req->best_parent_hw = NULL; if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { - struct clk_rate_request tmp_req = *req; - parent = clk_hw_get_parent(mux_hw); + req->best_parent_hw = parent; + req->best_parent_rate = clk_hw_get_rate(parent); - ret = clk_composite_determine_rate_for_parent(rate_hw, - &tmp_req, - parent, - rate_ops); - if (ret) - return ret; - - req->rate = tmp_req.rate; - req->best_parent_hw = tmp_req.best_parent_hw; - req->best_parent_rate = tmp_req.best_parent_rate; + rate = rate_ops->round_rate(rate_hw, req->rate, + &req->best_parent_rate); + if (rate < 0) + return rate; + req->rate = rate; return 0; } for (i = 0; i < clk_hw_get_num_parents(mux_hw); i++) { - struct clk_rate_request tmp_req = *req; - parent = clk_hw_get_parent_by_index(mux_hw, i); if (!parent) continue; - ret = clk_composite_determine_rate_for_parent(rate_hw, - &tmp_req, - parent, - rate_ops); - if (ret) + parent_rate = clk_hw_get_rate(parent); + + tmp_rate = rate_ops->round_rate(rate_hw, req->rate, + &parent_rate); + if (tmp_rate < 0) continue; - rate_diff = abs(req->rate - tmp_req.rate); + rate_diff = abs(req->rate - tmp_rate); if (!rate_diff || !req->best_parent_hw || best_rate_diff > rate_diff) { req->best_parent_hw = parent; - req->best_parent_rate = tmp_req.best_parent_rate; + req->best_parent_rate = parent_rate; best_rate_diff = rate_diff; - best_rate = tmp_req.rate; + best_rate = tmp_rate; } if (!rate_diff) @@ -391,7 +362,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name, return ERR_CAST(hw); return hw->clk; } -EXPORT_SYMBOL_GPL(clk_register_composite); struct clk *clk_register_composite_pdata(struct device *dev, const char *name, const struct clk_parent_data *parent_data, diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 6428380760..070dc47e95 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -223,37 +222,3 @@ void clk_hw_unregister_gate(struct clk_hw *hw) kfree(gate); } EXPORT_SYMBOL_GPL(clk_hw_unregister_gate); - -static void devm_clk_hw_release_gate(struct device *dev, void *res) -{ - clk_hw_unregister_gate(*(struct clk_hw **)res); -} - -struct clk_hw *__devm_clk_hw_register_gate(struct device *dev, - struct device_node *np, const char *name, - const char *parent_name, const struct clk_hw *parent_hw, - const struct clk_parent_data *parent_data, - unsigned long flags, - void __iomem *reg, u8 bit_idx, - u8 clk_gate_flags, spinlock_t *lock) -{ - struct clk_hw **ptr, *hw; - - ptr = devres_alloc(devm_clk_hw_release_gate, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - hw = __clk_hw_register_gate(dev, np, name, parent_name, parent_hw, - parent_data, flags, reg, bit_idx, - clk_gate_flags, lock); - - if (!IS_ERR(hw)) { - *ptr = hw; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } - - return hw; -} -EXPORT_SYMBOL_GPL(__devm_clk_hw_register_gate); diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 93fa8c9e11..57e4597cdf 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1,15 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * clk-si5351.c: Skyworks / Silicon Labs Si5351A/B/C I2C Clock Generator + * clk-si5351.c: Silicon Laboratories Si5351A/B/C I2C Clock Generator * * Sebastian Hesselbarth * Rabeeh Khoury * * References: * [1] "Si5351A/B/C Data Sheet" - * https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si5351-B.pdf - * [2] "AN619: Manually Generating an Si5351 Register Map" - * https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/application-notes/AN619.pdf + * https://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf + * [2] "Manually Generating an Si5351 Register Map" + * https://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf */ #include diff --git a/drivers/clk/clk-si5351.h b/drivers/clk/clk-si5351.h index e9e2bfdaae..73dc8effc5 100644 --- a/drivers/clk/clk-si5351.h +++ b/drivers/clk/clk-si5351.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * clk-si5351.h: Skyworks / Silicon Labs Si5351A/B/C I2C Clock Generator + * clk-si5351.h: Silicon Laboratories Si5351A/B/C I2C Clock Generator * * Sebastian Hesselbarth * Rabeeh Khoury diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 863274aa50..4bd1fe7d8a 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -2253,6 +2253,8 @@ static int stm32_rcc_reset_init(struct device *dev, void __iomem *base, const struct stm32_rcc_match_data *data = match->data; struct stm32_reset_data *reset_data = NULL; + data = match->data; + reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); if (!reset_data) return -ENOMEM; diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index e7be3e54b9..c6d3b1ab3d 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -905,7 +905,7 @@ static int vc5_get_output_config(struct i2c_client *client, static const struct of_device_id clk_vc5_of_match[]; -static int vc5_probe(struct i2c_client *client) +static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) { unsigned int oe, sd, src_mask = 0, src_val = 0; struct vc5_driver_data *vc5; @@ -1244,7 +1244,7 @@ static struct i2c_driver vc5_driver = { .pm = &vc5_pm_ops, .of_match_table = clk_vc5_of_match, }, - .probe_new = vc5_probe, + .probe = vc5_probe, .remove = vc5_remove, .id_table = vc5_id, }; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index a289ba730c..d8959f7112 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -432,20 +432,19 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index) if (entry->hw) { parent = entry->hw->core; + /* + * We have a direct reference but it isn't registered yet? + * Orphan it and let clk_reparent() update the orphan status + * when the parent is registered. + */ + if (!parent) + parent = ERR_PTR(-EPROBE_DEFER); } else { parent = clk_core_get(core, index); if (PTR_ERR(parent) == -ENOENT && entry->name) parent = clk_core_lookup(entry->name); } - /* - * We have a direct reference but it isn't registered yet? - * Orphan it and let clk_reparent() update the orphan status - * when the parent is registered. - */ - if (!parent) - parent = ERR_PTR(-EPROBE_DEFER); - /* Only cache it if it's not an error */ if (!IS_ERR(parent)) entry->core = parent; @@ -3092,9 +3091,7 @@ static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, { struct clk_core *child; - clk_pm_runtime_get(c); clk_summary_show_one(s, c, level); - clk_pm_runtime_put(c); hlist_for_each_entry(child, &c->children, child_node) clk_summary_show_subtree(s, child, level + 1); @@ -3237,10 +3234,7 @@ static int clk_rate_get(void *data, u64 *val) { struct clk_core *core = data; - clk_prepare_lock(); - *val = clk_core_get_rate_recalc(core); - clk_prepare_unlock(); - + *val = core->rate; return 0; } @@ -3346,42 +3340,6 @@ static int current_parent_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(current_parent); -#ifdef CLOCK_ALLOW_WRITE_DEBUGFS -static ssize_t current_parent_write(struct file *file, const char __user *ubuf, - size_t count, loff_t *ppos) -{ - struct seq_file *s = file->private_data; - struct clk_core *core = s->private; - struct clk_core *parent; - u8 idx; - int err; - - err = kstrtou8_from_user(ubuf, count, 0, &idx); - if (err < 0) - return err; - - parent = clk_core_get_parent_by_index(core, idx); - if (!parent) - return -ENOENT; - - clk_prepare_lock(); - err = clk_core_set_parent_nolock(core, parent); - clk_prepare_unlock(); - if (err) - return err; - - return count; -} - -static const struct file_operations current_parent_rw_fops = { - .open = current_parent_open, - .write = current_parent_write, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - static int clk_duty_cycle_show(struct seq_file *s, void *data) { struct clk_core *core = s->private; @@ -3447,12 +3405,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) #ifdef CLOCK_ALLOW_WRITE_DEBUGFS debugfs_create_file("clk_prepare_enable", 0644, root, core, &clk_prepare_enable_fops); - - if (core->num_parents > 1) - debugfs_create_file("clk_parent", 0644, root, core, - ¤t_parent_rw_fops); - else #endif + if (core->num_parents > 0) debugfs_create_file("clk_parent", 0444, root, core, ¤t_parent_fops); @@ -3600,6 +3554,9 @@ static int __clk_core_init(struct clk_core *core) unsigned long rate; int phase; + if (!core) + return -EINVAL; + clk_prepare_lock(); /* diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index c08edbd04d..47d9ec3abd 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -98,10 +98,3 @@ config CLK_IMX8QXP select MXC_CLK_SCU help Build the driver for IMX8QXP SCU based clocks. - -config CLK_IMX8ULP - tristate "IMX8ULP CCM Clock Driver" - depends on ARCH_MXC || COMPILE_TEST - select MXC_CLK - help - Build the driver for i.MX8ULP CCM Clock Driver diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index b5e040026d..c24a2acbfa 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -31,8 +31,6 @@ clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \ clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o -obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o - obj-$(CONFIG_CLK_IMX1) += clk-imx1.o obj-$(CONFIG_CLK_IMX25) += clk-imx25.o obj-$(CONFIG_CLK_IMX27) += clk-imx27.o diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c index 4eedd45dba..d85ba78abb 100644 --- a/drivers/clk/imx/clk-composite-7ulp.c +++ b/drivers/clk/imx/clk-composite-7ulp.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "../clk-fractional-divider.h" @@ -24,61 +23,17 @@ #define PCG_PCD_WIDTH 3 #define PCG_PCD_MASK 0x7 -#define SW_RST BIT(28) - -static int pcc_gate_enable(struct clk_hw *hw) -{ - struct clk_gate *gate = to_clk_gate(hw); - unsigned long flags; - u32 val; - int ret; - - ret = clk_gate_ops.enable(hw); - if (ret) - return ret; - - spin_lock_irqsave(gate->lock, flags); - /* - * release the sw reset for peripherals associated with - * with this pcc clock. - */ - val = readl(gate->reg); - val |= SW_RST; - writel(val, gate->reg); - - spin_unlock_irqrestore(gate->lock, flags); - - return 0; -} - -static void pcc_gate_disable(struct clk_hw *hw) -{ - clk_gate_ops.disable(hw); -} - -static int pcc_gate_is_enabled(struct clk_hw *hw) -{ - return clk_gate_ops.is_enabled(hw); -} - -static const struct clk_ops pcc_gate_ops = { - .enable = pcc_gate_enable, - .disable = pcc_gate_disable, - .is_enabled = pcc_gate_is_enabled, -}; - -static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, +struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, int num_parents, bool mux_present, bool rate_present, bool gate_present, - void __iomem *reg, bool has_swrst) + void __iomem *reg) { struct clk_hw *mux_hw = NULL, *fd_hw = NULL, *gate_hw = NULL; struct clk_fractional_divider *fd = NULL; struct clk_gate *gate = NULL; struct clk_mux *mux = NULL; struct clk_hw *hw; - u32 val; if (mux_present) { mux = kzalloc(sizeof(*mux), GFP_KERNEL); @@ -88,8 +43,6 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, mux->reg = reg; mux->shift = PCG_PCS_SHIFT; mux->mask = PCG_PCS_MASK; - if (has_swrst) - mux->lock = &imx_ccm_lock; } if (rate_present) { @@ -107,8 +60,6 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, fd->nwidth = PCG_PCD_WIDTH; fd->nmask = PCG_PCD_MASK; fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; - if (has_swrst) - fd->lock = &imx_ccm_lock; } if (gate_present) { @@ -121,27 +72,13 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, gate_hw = &gate->hw; gate->reg = reg; gate->bit_idx = PCG_CGC_SHIFT; - if (has_swrst) - gate->lock = &imx_ccm_lock; - /* - * make sure clock is gated during clock tree initialization, - * the HW ONLY allow clock parent/rate changed with clock gated, - * during clock tree initialization, clocks could be enabled - * by bootloader, so the HW status will mismatch with clock tree - * prepare count, then clock core driver will allow parent/rate - * change since the prepare count is zero, but HW actually - * prevent the parent/rate change due to the clock is enabled. - */ - val = readl_relaxed(reg); - val &= ~(1 << PCG_CGC_SHIFT); - writel_relaxed(val, reg); } hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, mux_hw, &clk_mux_ops, fd_hw, &clk_fractional_divider_ops, gate_hw, - has_swrst ? &pcc_gate_ops : &clk_gate_ops, CLK_SET_RATE_GATE | - CLK_SET_PARENT_GATE | CLK_SET_RATE_NO_REPARENT); + &clk_gate_ops, CLK_SET_RATE_GATE | + CLK_SET_PARENT_GATE); if (IS_ERR(hw)) { kfree(mux); kfree(fd); @@ -150,20 +87,3 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, return hw; } - -struct clk_hw *imx7ulp_clk_hw_composite(const char *name, const char * const *parent_names, - int num_parents, bool mux_present, bool rate_present, - bool gate_present, void __iomem *reg) -{ - return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, - gate_present, reg, false); -} - -struct clk_hw *imx8ulp_clk_hw_composite(const char *name, const char * const *parent_names, - int num_parents, bool mux_present, bool rate_present, - bool gate_present, void __iomem *reg, bool has_swrst) -{ - return imx_ulp_clk_hw_composite(name, parent_names, num_parents, mux_present, rate_present, - gate_present, reg, has_swrst); -} -EXPORT_SYMBOL_GPL(imx8ulp_clk_hw_composite); diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 2dfd6149e5..04e728538c 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -171,7 +171,7 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = { .determine_rate = imx8m_clk_composite_mux_determine_rate, }; -struct clk_hw *__imx8m_clk_hw_composite(const char *name, +struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, u32 composite_flags, @@ -246,4 +246,4 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, kfree(mux); return ERR_CAST(hw); } -EXPORT_SYMBOL_GPL(__imx8m_clk_hw_composite); +EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags); diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 520b100bff..206e4c43f6 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -380,6 +380,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6ULL_CLK_ESAI_IPG] = imx_clk_hw_gate2_shared("esai_ipg", "ahb", base + 0x70, 0, &share_count_esai); hws[IMX6ULL_CLK_ESAI_MEM] = imx_clk_hw_gate2_shared("esai_mem", "ahb", base + 0x70, 0, &share_count_esai); } + hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x70, 2); hws[IMX6UL_CLK_I2C1] = imx_clk_hw_gate2("i2c1", "perclk", base + 0x70, 6); hws[IMX6UL_CLK_I2C2] = imx_clk_hw_gate2("i2c2", "perclk", base + 0x70, 8); hws[IMX6UL_CLK_I2C3] = imx_clk_hw_gate2("i2c3", "perclk", base + 0x70, 10); @@ -390,12 +391,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_PXP] = imx_clk_hw_gate2("pxp", "axi", base + 0x70, 30); /* CCGR3 */ - /* - * Although the imx6ull reference manual lists CCGR2 as the csi clk - * gate register, tests have shown that it is actually the CCGR3 - * register bit 0/1, same as for the imx6ul. - */ - hws[IMX6UL_CLK_CSI] = imx_clk_hw_gate2("csi", "csi_podf", base + 0x74, 0); hws[IMX6UL_CLK_UART5_IPG] = imx_clk_hw_gate2("uart5_ipg", "ipg", base + 0x74, 2); hws[IMX6UL_CLK_UART5_SERIAL] = imx_clk_hw_gate2("uart5_serial", "uart_podf", base + 0x74, 2); if (clk_on_imx6ul()) { diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index b6e45e77ee..779e09105d 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -78,20 +78,20 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE); /* name parent_name base */ - hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "apll", "apll_pre_div", base + 0x500); - hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4(IMX_PLLV4_IMX7ULP, "spll", "spll_pre_div", base + 0x600); + hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4("apll", "apll_pre_div", base + 0x500); + hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4("spll", "spll_pre_div", base + 0x600); /* APLL PFDs */ - hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd0", "apll", base + 0x50c, 0); - hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd1", "apll", base + 0x50c, 1); - hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd2", "apll", base + 0x50c, 2); - hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "apll_pfd3", "apll", base + 0x50c, 3); + hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0); + hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1); + hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2); + hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3); /* SPLL PFDs */ - hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd0", "spll", base + 0x60C, 0); - hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd1", "spll", base + 0x60C, 1); - hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd2", "spll", base + 0x60C, 2); - hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2(IMX_PFDV2_IMX7ULP, "spll_pfd3", "spll", base + 0x60C, 3); + hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0); + hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1); + hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2); + hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3); /* PLL Mux */ hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE); diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index c990ad3788..1283730454 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -700,7 +700,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0); hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0); hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0); - hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "audio_ahb", ccm_base + 0x4650, 0); + hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0); hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", hws[IMX8MP_CLK_A53_CORE]->clk, diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index 6ca53a960e..6b744c8427 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -161,17 +161,8 @@ static int clk_pfdv2_set_rate(struct clk_hw *hw, unsigned long rate, if (!rate) return -EINVAL; - /* - * PFD can NOT change rate without gating. - * as the PFDs may enabled in HW by default but no - * consumer used it, the enable count is '0', so the - * 'SET_RATE_GATE' can NOT help on blocking the set_rate - * ops especially for 'assigned-clock-xxx'. In order - * to simplify the case, just disable the PFD if it is - * enabled in HW but not in SW. - */ - if (clk_pfdv2_is_enabled(hw)) - clk_pfdv2_disable(hw); + /* PFD can NOT change rate without gating */ + WARN_ON(clk_pfdv2_is_enabled(hw)); tmp = tmp * 18 + rate / 2; do_div(tmp, rate); @@ -200,8 +191,8 @@ static const struct clk_ops clk_pfdv2_ops = { .is_enabled = clk_pfdv2_is_enabled, }; -struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, - const char *parent_name, void __iomem *reg, u8 idx) +struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, + void __iomem *reg, u8 idx) { struct clk_init_data init; struct clk_pfdv2 *pfd; @@ -223,10 +214,7 @@ struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, init.ops = &clk_pfdv2_ops; init.parent_names = &parent_name; init.num_parents = 1; - if (type == IMX_PFDV2_IMX7ULP) - init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; - else - init.flags = CLK_SET_RATE_GATE; + init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; pfd->hw.init = &init; @@ -239,4 +227,3 @@ struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, return hw; } -EXPORT_SYMBOL_GPL(imx_clk_hw_pfdv2); diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c index 93ee81b28f..36ffb05257 100644 --- a/drivers/clk/imx/clk-pllv1.c +++ b/drivers/clk/imx/clk-pllv1.c @@ -8,19 +8,20 @@ #include "clk.h" +/** + * pll v1 + * + * @clk_hw clock source + * @parent the parent clock name + * @base base address of pll registers + * + * PLL clock version 1, found on i.MX1/21/25/27/31/35 + */ + #define MFN_BITS (10) #define MFN_SIGN (BIT(MFN_BITS - 1)) #define MFN_MASK (MFN_SIGN - 1) -/** - * struct clk_pllv1 - IMX PLLv1 clock descriptor - * - * @hw: clock source - * @base: base address of pll registers - * @type: type of IMX_PLLV1 - * - * PLL clock version 1, found on i.MX1/21/25/27/31/35 - */ struct clk_pllv1 { struct clk_hw hw; void __iomem *base; diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index eea32f87c6..20ee9611ba 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -247,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, div = rate / parent_rate; temp64 = (u64) (rate - div * parent_rate); temp64 *= mfd; - temp64 = div64_ul(temp64, parent_rate); + do_div(temp64, parent_rate); mfn = temp64; temp64 = (u64)parent_rate; @@ -277,7 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, div = rate / parent_rate; temp64 = (u64) (rate - div * parent_rate); temp64 *= mfd; - temp64 = div64_ul(temp64, parent_rate); + do_div(temp64, parent_rate); mfn = temp64; val = readl_relaxed(pll->base); @@ -334,7 +334,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf( /* rate = parent_rate * (mfi + mfn/mfd) */ temp64 = rate - parent_rate * mf.mfi; temp64 *= mf.mfd; - temp64 = div64_ul(temp64, parent_rate); + do_div(temp64, parent_rate); mf.mfn = temp64; } diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index 6e7e34571f..8ec703f274 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -23,17 +23,14 @@ /* PLL Configuration Register (xPLLCFG) */ #define PLL_CFG_OFFSET 0x08 -#define IMX8ULP_PLL_CFG_OFFSET 0x10 #define BP_PLL_MULT 16 #define BM_PLL_MULT (0x7f << 16) /* PLL Numerator Register (xPLLNUM) */ #define PLL_NUM_OFFSET 0x10 -#define IMX8ULP_PLL_NUM_OFFSET 0x1c /* PLL Denominator Register (xPLLDENOM) */ #define PLL_DENOM_OFFSET 0x14 -#define IMX8ULP_PLL_DENOM_OFFSET 0x18 #define MAX_MFD 0x3fffffff #define DEFAULT_MFD 1000000 @@ -41,9 +38,6 @@ struct clk_pllv4 { struct clk_hw hw; void __iomem *base; - u32 cfg_offset; - u32 num_offset; - u32 denom_offset; }; /* Valid PLL MULT Table */ @@ -78,12 +72,12 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw, u32 mult, mfn, mfd; u64 temp64; - mult = readl_relaxed(pll->base + pll->cfg_offset); + mult = readl_relaxed(pll->base + PLL_CFG_OFFSET); mult &= BM_PLL_MULT; mult >>= BP_PLL_MULT; - mfn = readl_relaxed(pll->base + pll->num_offset); - mfd = readl_relaxed(pll->base + pll->denom_offset); + mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); + mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); temp64 = parent_rate; temp64 *= mfn; do_div(temp64, mfd); @@ -171,13 +165,13 @@ static int clk_pllv4_set_rate(struct clk_hw *hw, unsigned long rate, do_div(temp64, parent_rate); mfn = temp64; - val = readl_relaxed(pll->base + pll->cfg_offset); + val = readl_relaxed(pll->base + PLL_CFG_OFFSET); val &= ~BM_PLL_MULT; val |= mult << BP_PLL_MULT; - writel_relaxed(val, pll->base + pll->cfg_offset); + writel_relaxed(val, pll->base + PLL_CFG_OFFSET); - writel_relaxed(mfn, pll->base + pll->num_offset); - writel_relaxed(mfd, pll->base + pll->denom_offset); + writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); + writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); return 0; } @@ -213,8 +207,8 @@ static const struct clk_ops clk_pllv4_ops = { .is_prepared = clk_pllv4_is_prepared, }; -struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, - const char *parent_name, void __iomem *base) +struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, + void __iomem *base) { struct clk_pllv4 *pll; struct clk_hw *hw; @@ -227,16 +221,6 @@ struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, pll->base = base; - if (type == IMX_PLLV4_IMX8ULP) { - pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET; - pll->num_offset = IMX8ULP_PLL_NUM_OFFSET; - pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET; - } else { - pll->cfg_offset = PLL_CFG_OFFSET; - pll->num_offset = PLL_NUM_OFFSET; - pll->denom_offset = PLL_DENOM_OFFSET; - } - init.name = name; init.ops = &clk_pllv4_ops; init.parent_names = &parent_name; @@ -254,4 +238,3 @@ struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, return hw; } -EXPORT_SYMBOL_GPL(imx_clk_hw_pllv4); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 7d220a01de..e144f983fd 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -42,16 +42,6 @@ enum imx_pll14xx_type { PLL_1443X, }; -enum imx_pllv4_type { - IMX_PLLV4_IMX7ULP, - IMX_PLLV4_IMX8ULP, -}; - -enum imx_pfdv2_type { - IMX_PFDV2_IMX7ULP, - IMX_PFDV2_IMX8ULP, -}; - /* NOTE: Rate table should be kept sorted in descending order. */ struct imx_pll14xx_rate_table { unsigned int rate; @@ -98,6 +88,9 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll; #define imx_clk_divider(name, parent, reg, shift, width) \ to_clk(imx_clk_hw_divider(name, parent, reg, shift, width)) +#define imx_clk_divider2(name, parent, reg, shift, width) \ + to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width)) + #define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \ to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags)) @@ -110,93 +103,40 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll; #define imx_clk_gate2(name, parent, reg, shift) \ to_clk(imx_clk_hw_gate2(name, parent, reg, shift)) -#define imx_clk_gate2_cgr(name, parent, reg, shift, cgr_val) \ - to_clk(__imx_clk_hw_gate2(name, parent, reg, shift, cgr_val, 0, NULL)) - #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)) +#define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ + to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)) + +#define imx_clk_gate3(name, parent, reg, shift) \ + to_clk(imx_clk_hw_gate3(name, parent, reg, shift)) + +#define imx_clk_gate4(name, parent, reg, shift) \ + to_clk(imx_clk_hw_gate4(name, parent, reg, shift)) + #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)) -#define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ - to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags)) - -#define imx_clk_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \ - to_clk(imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags)) - #define imx_clk_pllv1(type, name, parent, base) \ to_clk(imx_clk_hw_pllv1(type, name, parent, base)) #define imx_clk_pllv2(name, parent, base) \ to_clk(imx_clk_hw_pllv2(name, parent, base)) -#define imx_clk_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ - to_clk(imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags)) +#define imx_clk_frac_pll(name, parent_name, base) \ + to_clk(imx_clk_hw_frac_pll(name, parent_name, base)) -#define imx_clk_hw_gate(name, parent, reg, shift) \ - imx_clk_hw_gate_flags(name, parent, reg, shift, 0) +#define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\ + bypass1, bypass2, base, flags) \ + to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\ + bypass1, bypass2, base, flags)) -#define imx_clk_hw_gate2(name, parent, reg, shift) \ - imx_clk_hw_gate2_flags(name, parent, reg, shift, 0) +struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, + void __iomem *base, const struct imx_pll14xx_clk *pll_clk); -#define imx_clk_hw_gate_dis(name, parent, reg, shift) \ - imx_clk_hw_gate_dis_flags(name, parent, reg, shift, 0) - -#define imx_clk_hw_gate_dis_flags(name, parent, reg, shift, flags) \ - __imx_clk_hw_gate(name, parent, reg, shift, flags, CLK_GATE_SET_TO_DISABLE) - -#define imx_clk_hw_gate_flags(name, parent, reg, shift, flags) \ - __imx_clk_hw_gate(name, parent, reg, shift, flags, 0) - -#define imx_clk_hw_gate2_flags(name, parent, reg, shift, flags) \ - __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, flags, NULL) - -#define imx_clk_hw_gate2_shared(name, parent, reg, shift, shared_count) \ - __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, 0, shared_count) - -#define imx_clk_hw_gate2_shared2(name, parent, reg, shift, shared_count) \ - __imx_clk_hw_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE, shared_count) - -#define imx_clk_hw_gate3(name, parent, reg, shift) \ - imx_clk_hw_gate3_flags(name, parent, reg, shift, 0) - -#define imx_clk_hw_gate3_flags(name, parent, reg, shift, flags) \ - __imx_clk_hw_gate(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE, 0) - -#define imx_clk_hw_gate4(name, parent, reg, shift) \ - imx_clk_hw_gate4_flags(name, parent, reg, shift, 0) - -#define imx_clk_hw_gate4_flags(name, parent, reg, shift, flags) \ - imx_clk_hw_gate2_flags(name, parent, reg, shift, flags | CLK_OPS_PARENT_ENABLE) - -#define imx_clk_hw_mux2(name, reg, shift, width, parents, num_parents) \ - imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, 0) - -#define imx_clk_hw_mux(name, reg, shift, width, parents, num_parents) \ - __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, 0, 0) - -#define imx_clk_hw_mux_flags(name, reg, shift, width, parents, num_parents, flags) \ - __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags, 0) - -#define imx_clk_hw_mux_ldb(name, reg, shift, width, parents, num_parents) \ - __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT, CLK_MUX_READ_ONLY) - -#define imx_clk_hw_mux2_flags(name, reg, shift, width, parents, num_parents, flags) \ - __imx_clk_hw_mux(name, reg, shift, width, parents, num_parents, flags | CLK_OPS_PARENT_ENABLE, 0) - -#define imx_clk_hw_divider(name, parent, reg, shift, width) \ - __imx_clk_hw_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT) - -#define imx_clk_hw_divider2(name, parent, reg, shift, width) \ - __imx_clk_hw_divider(name, parent, reg, shift, width, \ - CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE) - -#define imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags) \ - __imx_clk_hw_divider(name, parent, reg, shift, width, flags) - -#define imx_clk_hw_pll14xx(name, parent_name, base, pll_clk) \ - imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk) +#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \ + to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk)) struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, const char *parent_name, void __iomem *base, @@ -251,8 +191,8 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, .kdiv = (_k), \ } -struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, - const char *parent_name, void __iomem *base); +struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name, + void __iomem *base); struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -275,8 +215,8 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, void __iomem *reg, u8 idx); -struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, - const char *parent_name, void __iomem *reg, u8 idx); +struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name, + void __iomem *reg, u8 idx); struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name, void __iomem *reg, u8 shift, u8 width, @@ -292,12 +232,6 @@ struct clk_hw *imx7ulp_clk_hw_composite(const char *name, bool rate_present, bool gate_present, void __iomem *reg); -struct clk_hw *imx8ulp_clk_hw_composite(const char *name, - const char * const *parent_names, - int num_parents, bool mux_present, - bool rate_present, bool gate_present, - void __iomem *reg, bool has_swrst); - struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 width, void (*fixup)(u32 *val)); @@ -313,11 +247,27 @@ static inline struct clk *to_clk(struct clk_hw *hw) return hw->clk; } +static inline struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_pll14xx_clk *pll_clk) +{ + return imx_dev_clk_hw_pll14xx(NULL, name, parent_name, base, pll_clk); +} + static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate) { return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate); } +static inline struct clk_hw *imx_clk_hw_mux_ldb(const char *name, void __iomem *reg, + u8 shift, u8 width, const char * const *parents, + int num_parents) +{ + return clk_hw_register_mux(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, reg, + shift, width, CLK_MUX_READ_ONLY, &imx_ccm_lock); +} + static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, const char *parent, unsigned int mult, unsigned int div) { @@ -325,7 +275,16 @@ static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name, CLK_SET_RATE_PARENT, mult, div); } -static inline struct clk_hw *__imx_clk_hw_divider(const char *name, +static inline struct clk_hw *imx_clk_hw_divider(const char *name, + const char *parent, + void __iomem *reg, u8 shift, + u8 width) +{ + return clk_hw_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 width, unsigned long flags) @@ -334,31 +293,237 @@ static inline struct clk_hw *__imx_clk_hw_divider(const char *name, reg, shift, width, 0, &imx_ccm_lock); } -static inline struct clk_hw *__imx_clk_hw_gate(const char *name, const char *parent, - void __iomem *reg, u8 shift, - unsigned long flags, - unsigned long clk_gate_flags) +static inline struct clk_hw *imx_clk_hw_divider2(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width) +{ + return clk_hw_register_divider(NULL, name, parent, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_divider2_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, u8 width, + unsigned long flags) +{ + return clk_register_divider(NULL, name, parent, + flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent, + void __iomem *reg, u8 shift, unsigned long flags) { return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, - shift, clk_gate_flags, &imx_ccm_lock); + shift, 0, &imx_ccm_lock); } -static inline struct clk_hw *__imx_clk_hw_gate2(const char *name, const char *parent, - void __iomem *reg, u8 shift, u8 cgr_val, - unsigned long flags, - unsigned int *share_count) +static inline struct clk_hw *imx_clk_hw_gate(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_dev_clk_hw_gate(struct device *dev, const char *name, + const char *parent, void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_gate_dis(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_gate_dis_flags(const char *name, const char *parent, + void __iomem *reg, u8 shift, unsigned long flags) +{ + return clk_hw_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, + shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); +} + +static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, + void __iomem *reg, u8 shift, unsigned long flags) { return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, - shift, cgr_val, 0x3, 0, &imx_ccm_lock, share_count); + shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); } -static inline struct clk_hw *__imx_clk_hw_mux(const char *name, void __iomem *reg, +static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0x3, 0x3, 0, &imx_ccm_lock, share_count); +} + +static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | + CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0x3, 0, + &imx_ccm_lock, share_count); +} + +static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev, + const char *name, const char *parent, + void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | + CLK_OPS_PARENT_ENABLE, reg, shift, 0x1, + 0x1, 0, &imx_ccm_lock, share_count); +} + +static inline struct clk *imx_clk_gate2_cgr(const char *name, + const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, cgr_val, 0x3, 0, &imx_ccm_lock, NULL); +} + +static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate(NULL, name, parent, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned long flags) +{ + return clk_hw_register_gate(NULL, name, parent, + flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, 0, &imx_ccm_lock); +} + +#define imx_clk_gate3_flags(name, parent, reg, shift, flags) \ + to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags)) + +static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_hw_register_gate2(NULL, name, parent, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); +} + +static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned long flags) +{ + return clk_hw_register_gate2(NULL, name, parent, + flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); +} + +#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \ + to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags)) + +static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg, u8 shift, u8 width, const char * const *parents, - int num_parents, unsigned long flags, unsigned long clk_mux_flags) + int num_parents) { return clk_hw_register_mux(NULL, name, parents, num_parents, - flags | CLK_SET_RATE_NO_REPARENT, reg, shift, - width, clk_mux_flags, &imx_ccm_lock); + CLK_SET_RATE_NO_REPARENT, reg, shift, + width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_dev_clk_hw_mux(struct device *dev, + const char *name, void __iomem *reg, u8 shift, + u8 width, const char * const *parents, int num_parents) +{ + return clk_hw_register_mux(dev, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT | CLK_SET_PARENT_GATE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg, + u8 shift, u8 width, const char * const *parents, + int num_parents) +{ + return clk_register_mux(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_mux2(const char *name, void __iomem *reg, + u8 shift, u8 width, + const char * const *parents, + int num_parents) +{ + return clk_hw_register_mux(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT | + CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_mux_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, + const char * const *parents, int num_parents, + unsigned long flags) +{ + return clk_register_mux(NULL, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0, + &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, + const char * const *parents, + int num_parents, unsigned long flags) +{ + return clk_hw_register_mux(NULL, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_mux2_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, + const char * const *parents, + int num_parents, unsigned long flags) +{ + return clk_register_mux(NULL, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_clk_hw_mux_flags(const char *name, + void __iomem *reg, u8 shift, + u8 width, + const char * const *parents, + int num_parents, + unsigned long flags) +{ + return clk_hw_register_mux(NULL, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT, + reg, shift, width, 0, &imx_ccm_lock); +} + +static inline struct clk_hw *imx_dev_clk_hw_mux_flags(struct device *dev, + const char *name, + void __iomem *reg, u8 shift, + u8 width, + const char * const *parents, + int num_parents, + unsigned long flags) +{ + return clk_hw_register_mux(dev, name, parents, num_parents, + flags | CLK_SET_RATE_NO_REPARENT, + reg, shift, width, 0, &imx_ccm_lock); } struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, @@ -369,55 +534,65 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, #define IMX_COMPOSITE_BUS BIT(1) #define IMX_COMPOSITE_FW_MANAGED BIT(2) -#define IMX_COMPOSITE_CLK_FLAGS_DEFAULT \ - (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) -#define IMX_COMPOSITE_CLK_FLAGS_CRITICAL \ - (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_IS_CRITICAL) -#define IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE \ - (IMX_COMPOSITE_CLK_FLAGS_DEFAULT | CLK_GET_RATE_NOCACHE) -#define IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE \ - (IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE | CLK_IS_CRITICAL) - -struct clk_hw *__imx8m_clk_hw_composite(const char *name, +struct clk_hw *imx8m_clk_hw_composite_flags(const char *name, const char * const *parent_names, int num_parents, void __iomem *reg, u32 composite_flags, unsigned long flags); -#define _imx8m_clk_hw_composite(name, parent_names, reg, composite_flags, flags) \ - __imx8m_clk_hw_composite(name, parent_names, \ - ARRAY_SIZE(parent_names), reg, composite_flags, flags) - -#define imx8m_clk_hw_composite(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - 0, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) - -#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - 0, IMX_COMPOSITE_CLK_FLAGS_CRITICAL) - #define imx8m_clk_hw_composite_bus(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, \ + IMX_COMPOSITE_BUS, \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) #define imx8m_clk_hw_composite_bus_critical(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - IMX_COMPOSITE_BUS, IMX_COMPOSITE_CLK_FLAGS_CRITICAL) + imx8m_clk_hw_composite_flags(name, parent_names, ARRAY_SIZE(parent_names), reg, \ + IMX_COMPOSITE_BUS, \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_IS_CRITICAL) #define imx8m_clk_hw_composite_core(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - IMX_COMPOSITE_CORE, IMX_COMPOSITE_CLK_FLAGS_DEFAULT) + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, \ + IMX_COMPOSITE_CORE, \ + CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + +#define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \ + flags) \ + to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \ + num_parents, reg, 0, flags)) + +#define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, 0, \ + flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) + +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \ + imx8m_clk_hw_composite_flags(name, parent_names, \ + ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \ + flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE) #define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - IMX_COMPOSITE_FW_MANAGED, \ - IMX_COMPOSITE_CLK_FLAGS_GET_RATE_NO_CACHE) + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0) #define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \ - _imx8m_clk_hw_composite(name, parent_names, reg, \ - IMX_COMPOSITE_FW_MANAGED, \ - IMX_COMPOSITE_CLK_FLAGS_CRITICAL_GET_RATE_NO_CACHE) + __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL) + +#define __imx8m_clk_composite(name, parent_names, reg, flags) \ + to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags)) + +#define imx8m_clk_hw_composite(name, parent_names, reg) \ + __imx8m_clk_hw_composite(name, parent_names, reg, 0) + +#define imx8m_clk_composite(name, parent_names, reg) \ + __imx8m_clk_composite(name, parent_names, reg, 0) + +#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \ + __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL) + +#define imx8m_clk_composite_critical(name, parent_names, reg) \ + __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL) struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 15d61793f5..66ff141da0 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 43ffb62c42..cd878f08ac 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" diff --git a/drivers/clk/ingenic/jz4760-cgu.c b/drivers/clk/ingenic/jz4760-cgu.c index 8fdd383560..14483797a4 100644 --- a/drivers/clk/ingenic/jz4760-cgu.c +++ b/drivers/clk/ingenic/jz4760-cgu.c @@ -12,7 +12,7 @@ #include -#include +#include #include "cgu.h" #include "pm.h" @@ -313,16 +313,6 @@ static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = { .parents = { JZ4760_CLK_H2CLK, }, .gate = { CGU_REG_CLKGR0, 21 }, }, - [JZ4760_CLK_MDMA] = { - "mdma", CGU_CLK_GATE, - .parents = { JZ4760_CLK_HCLK, }, - .gate = { CGU_REG_CLKGR0, 25 }, - }, - [JZ4760_CLK_BDMA] = { - "bdma", CGU_CLK_GATE, - .parents = { JZ4760_CLK_HCLK, }, - .gate = { CGU_REG_CLKGR1, 0 }, - }, [JZ4760_CLK_I2C0] = { "i2c0", CGU_CLK_GATE, .parents = { JZ4760_CLK_EXT, }, diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index 7ef9125763..2321742b34 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" @@ -329,11 +329,6 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { .parents = { JZ4770_CLK_H2CLK, }, .gate = { CGU_REG_CLKGR0, 21 }, }, - [JZ4770_CLK_BDMA] = { - "bdma", CGU_CLK_GATE, - .parents = { JZ4770_CLK_H2CLK, }, - .gate = { CGU_REG_CLKGR1, 0 }, - }, [JZ4770_CLK_I2C0] = { "i2c0", CGU_CLK_GATE, .parents = { JZ4770_CLK_EXT, }, diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index e357c228e0..0268d23ebe 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c index 3c4d5a77cc..9aa20b52e1 100644 --- a/drivers/clk/ingenic/x1000-cgu.c +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c index e01ec2dc7a..950aee2433 100644 --- a/drivers/clk/ingenic/x1830-cgu.c +++ b/drivers/clk/ingenic/x1830-cgu.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include "cgu.h" #include "pm.h" diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 01ef02c547..439b7c8d0d 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -6,7 +6,7 @@ menu "Clock driver for MediaTek SoC" depends on ARCH_MEDIATEK || COMPILE_TEST config COMMON_CLK_MEDIATEK - tristate + bool select RESET_CONTROLLER help MediaTek SoCs' clock support. @@ -204,7 +204,7 @@ config COMMON_CLK_MT6765_MIPI2BSYS This driver supports MediaTek MT6765 mipi2bsys clocks. config COMMON_CLK_MT6779 - tristate "Clock driver for MediaTek MT6779" + bool "Clock driver for MediaTek MT6779" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST select COMMON_CLK_MEDIATEK default ARCH_MEDIATEK && ARM64 @@ -212,49 +212,49 @@ config COMMON_CLK_MT6779 This driver supports MediaTek MT6779 basic clocks. config COMMON_CLK_MT6779_MMSYS - tristate "Clock driver for MediaTek MT6779 mmsys" + bool "Clock driver for MediaTek MT6779 mmsys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 mmsys clocks. config COMMON_CLK_MT6779_IMGSYS - tristate "Clock driver for MediaTek MT6779 imgsys" + bool "Clock driver for MediaTek MT6779 imgsys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 imgsys clocks. config COMMON_CLK_MT6779_IPESYS - tristate "Clock driver for MediaTek MT6779 ipesys" + bool "Clock driver for MediaTek MT6779 ipesys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 ipesys clocks. config COMMON_CLK_MT6779_CAMSYS - tristate "Clock driver for MediaTek MT6779 camsys" + bool "Clock driver for MediaTek MT6779 camsys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 camsys clocks. config COMMON_CLK_MT6779_VDECSYS - tristate "Clock driver for MediaTek MT6779 vdecsys" + bool "Clock driver for MediaTek MT6779 vdecsys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 vdecsys clocks. config COMMON_CLK_MT6779_VENCSYS - tristate "Clock driver for MediaTek MT6779 vencsys" + bool "Clock driver for MediaTek MT6779 vencsys" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 vencsys clocks. config COMMON_CLK_MT6779_MFGCFG - tristate "Clock driver for MediaTek MT6779 mfgcfg" + bool "Clock driver for MediaTek MT6779 mfgcfg" depends on COMMON_CLK_MT6779 help This driver supports MediaTek MT6779 mfgcfg clocks. config COMMON_CLK_MT6779_AUDSYS - tristate "Clock driver for Mediatek MT6779 audsys" + bool "Clock driver for Mediatek MT6779 audsys" depends on COMMON_CLK_MT6779 help This driver supports Mediatek MT6779 audsys clocks. @@ -344,23 +344,6 @@ config COMMON_CLK_MT7629_HIFSYS This driver supports MediaTek MT7629 HIFSYS clocks providing to PCI-E and USB. -config COMMON_CLK_MT7986 - bool "Clock driver for MediaTek MT7986" - depends on ARCH_MEDIATEK || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK - help - This driver supports MediaTek MT7986 basic clocks and clocks - required for various peripherals found on MediaTek. - -config COMMON_CLK_MT7986_ETHSYS - bool "Clock driver for MediaTek MT7986 ETHSYS" - depends on COMMON_CLK_MT7986 - default COMMON_CLK_MT7986 - help - This driver adds support for clocks for Ethernet and SGMII - required on MediaTek MT7986 SoC. - config COMMON_CLK_MT8135 bool "Clock driver for MediaTek MT8135" depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST @@ -592,14 +575,6 @@ config COMMON_CLK_MT8192_VENCSYS help This driver supports MediaTek MT8192 vencsys clocks. -config COMMON_CLK_MT8195 - bool "Clock driver for MediaTek MT8195" - depends on ARM64 || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK - help - This driver supports MediaTek MT8195 clocks. - config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 7b0c2646ce..15bc045f0b 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -46,10 +46,6 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o -obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o -obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o -obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o -obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o @@ -84,13 +80,5 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o -obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o \ - clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o \ - clk-mt8195-cam.o clk-mt8195-ccu.o clk-mt8195-img.o \ - clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \ - clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o \ - clk-mt8195-venc.o clk-mt8195-vpp0.o clk-mt8195-vpp1.o \ - clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o \ - clk-mt8195-apusys_pll.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c index caa9119413..258d128370 100644 --- a/drivers/clk/mediatek/clk-apmixed.c +++ b/drivers/clk/mediatek/clk-apmixed.c @@ -5,7 +5,6 @@ */ #include -#include #include #include @@ -98,5 +97,3 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name, return clk; } - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index e188018bc9..61eeae4e60 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -6,7 +6,6 @@ #include #include -#include #include #include "clk-mtk.h" @@ -107,5 +106,3 @@ int mtk_clk_register_cpumuxes(struct device_node *node, return 0; } - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 5d88b42856..a35cf0b221 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -11,29 +11,32 @@ #include #include #include -#include #include "clk-mtk.h" #include "clk-gate.h" -static u32 mtk_get_clockgating(struct clk_hw *hw) +static int mtk_cg_bit_is_cleared(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); - return val & BIT(cg->bit); -} + val &= BIT(cg->bit); -static int mtk_cg_bit_is_cleared(struct clk_hw *hw) -{ - return mtk_get_clockgating(hw) == 0; + return val == 0; } static int mtk_cg_bit_is_set(struct clk_hw *hw) { - return mtk_get_clockgating(hw) != 0; + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 val; + + regmap_read(cg->regmap, cg->sta_ofs, &val); + + val &= BIT(cg->bit); + + return val != 0; } static void mtk_cg_set_bit(struct clk_hw *hw) @@ -53,15 +56,17 @@ static void mtk_cg_clr_bit(struct clk_hw *hw) static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 cgbit = BIT(cg->bit); - regmap_set_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit)); + regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, cgbit); } static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw) { struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); + u32 cgbit = BIT(cg->bit); - regmap_clear_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit)); + regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, 0); } static int mtk_cg_enable(struct clk_hw *hw) @@ -117,28 +122,24 @@ const struct clk_ops mtk_clk_gate_ops_setclr = { .enable = mtk_cg_enable, .disable = mtk_cg_disable, }; -EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr); const struct clk_ops mtk_clk_gate_ops_setclr_inv = { .is_enabled = mtk_cg_bit_is_set, .enable = mtk_cg_enable_inv, .disable = mtk_cg_disable_inv, }; -EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv); const struct clk_ops mtk_clk_gate_ops_no_setclr = { .is_enabled = mtk_cg_bit_is_cleared, .enable = mtk_cg_enable_no_setclr, .disable = mtk_cg_disable_no_setclr, }; -EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr); const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = { .is_enabled = mtk_cg_bit_is_set, .enable = mtk_cg_enable_inv_no_setclr, .disable = mtk_cg_disable_inv_no_setclr, }; -EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv); struct clk *mtk_clk_register_gate( const char *name, @@ -180,6 +181,3 @@ struct clk *mtk_clk_register_gate( return clk; } -EXPORT_SYMBOL_GPL(mtk_clk_register_gate); - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c index 9e889e4c36..11b209f95e 100644 --- a/drivers/clk/mediatek/clk-mt6779-aud.c +++ b/drivers/clk/mediatek/clk-mt6779-aud.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -115,5 +114,4 @@ static struct platform_driver clk_mt6779_aud_drv = { }, }; -module_platform_driver(clk_mt6779_aud_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_aud_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c index 7f07a2a139..244d4208b7 100644 --- a/drivers/clk/mediatek/clk-mt6779-cam.c +++ b/drivers/clk/mediatek/clk-mt6779-cam.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -64,5 +63,4 @@ static struct platform_driver clk_mt6779_cam_drv = { }, }; -module_platform_driver(clk_mt6779_cam_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_cam_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c index f0961fa1a2..26292a45c6 100644 --- a/drivers/clk/mediatek/clk-mt6779-img.c +++ b/drivers/clk/mediatek/clk-mt6779-img.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -56,5 +55,4 @@ static struct platform_driver clk_mt6779_img_drv = { }, }; -module_platform_driver(clk_mt6779_img_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_img_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c index 8c6f3e154b..bb51907563 100644 --- a/drivers/clk/mediatek/clk-mt6779-ipe.c +++ b/drivers/clk/mediatek/clk-mt6779-ipe.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -58,5 +57,4 @@ static struct platform_driver clk_mt6779_ipe_drv = { }, }; -module_platform_driver(clk_mt6779_ipe_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_ipe_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c index 9f3372886e..c6ee2a89c0 100644 --- a/drivers/clk/mediatek/clk-mt6779-mfg.c +++ b/drivers/clk/mediatek/clk-mt6779-mfg.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include @@ -53,5 +52,4 @@ static struct platform_driver clk_mt6779_mfg_drv = { }, }; -module_platform_driver(clk_mt6779_mfg_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_mfg_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c index 33946e6471..059c1a41ac 100644 --- a/drivers/clk/mediatek/clk-mt6779-mm.c +++ b/drivers/clk/mediatek/clk-mt6779-mm.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -106,5 +105,4 @@ static struct platform_driver clk_mt6779_mm_drv = { }, }; -module_platform_driver(clk_mt6779_mm_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_mm_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c index f4358844c2..1900da2586 100644 --- a/drivers/clk/mediatek/clk-mt6779-vdec.c +++ b/drivers/clk/mediatek/clk-mt6779-vdec.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include @@ -65,5 +64,4 @@ static struct platform_driver clk_mt6779_vdec_drv = { }, }; -module_platform_driver(clk_mt6779_vdec_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_vdec_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c index ff67084af5..b41d1f859e 100644 --- a/drivers/clk/mediatek/clk-mt6779-venc.c +++ b/drivers/clk/mediatek/clk-mt6779-venc.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include @@ -56,5 +55,4 @@ static struct platform_driver clk_mt6779_venc_drv = { }, }; -module_platform_driver(clk_mt6779_venc_drv); -MODULE_LICENSE("GPL"); +builtin_platform_driver(clk_mt6779_venc_drv); diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c index 9825385c9f..6e0d3a1667 100644 --- a/drivers/clk/mediatek/clk-mt6779.c +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -4,7 +4,6 @@ * Author: Wendell Lin */ -#include #include #include #include @@ -1315,4 +1314,3 @@ static int __init clk_mt6779_init(void) } arch_initcall(clk_mt6779_init); -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 8d5791b3f4..4b6096c44d 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -43,16 +42,6 @@ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) return NULL; } -EXPORT_SYMBOL_GPL(mtk_alloc_clk_data); - -void mtk_free_clk_data(struct clk_onecell_data *clk_data) -{ - if (!clk_data) - return; - - kfree(clk_data->clks); - kfree(clk_data); -} void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num, struct clk_onecell_data *clk_data) @@ -79,7 +68,6 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, clk_data->clks[rc->id] = clk; } } -EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks); void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, struct clk_onecell_data *clk_data) @@ -106,7 +94,6 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, clk_data->clks[ff->id] = clk; } } -EXPORT_SYMBOL_GPL(mtk_clk_register_factors); int mtk_clk_register_gates_with_dev(struct device_node *node, const struct mtk_gate *clks, @@ -159,7 +146,6 @@ int mtk_clk_register_gates(struct device_node *node, return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL); } -EXPORT_SYMBOL_GPL(mtk_clk_register_gates); struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, void __iomem *base, spinlock_t *lock) @@ -273,7 +259,6 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs, clk_data->clks[mc->id] = clk; } } -EXPORT_SYMBOL_GPL(mtk_clk_register_composites); void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num, void __iomem *base, spinlock_t *lock, @@ -320,17 +305,7 @@ int mtk_clk_simple_probe(struct platform_device *pdev) r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data); if (r) - goto free_data; + return r; - r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); - if (r) - goto free_data; - - return r; - -free_data: - mtk_free_clk_data(clk_data); - return r; + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); } - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 0ff289d934..7de41c3b32 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -202,7 +202,6 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, struct clk_onecell_data *clk_data); struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); -void mtk_free_clk_data(struct clk_onecell_data *clk_data); #define HAVE_RST_BAR BIT(0) #define PLL_AO BIT(1) diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index 6d3a50eb7d..855b0a1f7e 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "clk-mtk.h" #include "clk-mux.h" @@ -121,7 +120,6 @@ const struct clk_ops mtk_mux_clr_set_upd_ops = { .get_parent = mtk_clk_mux_get_parent, .set_parent = mtk_clk_mux_set_parent_setclr_lock, }; -EXPORT_SYMBOL_GPL(mtk_mux_clr_set_upd_ops); const struct clk_ops mtk_mux_gate_clr_set_upd_ops = { .enable = mtk_clk_mux_enable_setclr, @@ -130,7 +128,6 @@ const struct clk_ops mtk_mux_gate_clr_set_upd_ops = { .get_parent = mtk_clk_mux_get_parent, .set_parent = mtk_clk_mux_set_parent_setclr_lock, }; -EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops); static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, struct regmap *regmap, @@ -198,6 +195,3 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes, return 0; } -EXPORT_SYMBOL_GPL(mtk_clk_register_muxes); - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 60d7ffa0b9..7fb001a4e7 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -333,7 +332,7 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data, pll->pcw_chg_addr = pll->base_addr + REG_CON1; if (data->tuner_reg) pll->tuner_addr = base + data->tuner_reg; - if (data->tuner_en_reg || data->tuner_en_bit) + if (data->tuner_en_reg) pll->tuner_en_addr = base + data->tuner_en_reg; if (data->en_reg) pll->en_addr = base + data->en_reg; @@ -386,6 +385,3 @@ void mtk_clk_register_plls(struct device_node *node, clk_data->clks[pll->id] = clk; } } -EXPORT_SYMBOL_GPL(mtk_clk_register_plls); - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index ffe464ce7f..e562dc3c10 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -137,5 +137,3 @@ void mtk_register_reset_controller_set_clr(struct device_node *np, mtk_register_reset_controller_common(np, num_regs, regofs, &mtk_reset_ops_set_clr); } - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index cd0f5bae24..a844d35b55 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -118,56 +118,6 @@ static struct clk_regmap meson8b_fixed_pll = { }, }; -static struct clk_fixed_factor hdmi_pll_dco_in = { - .mult = 2, - .div = 1, - .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll_dco_in", - .ops = &clk_fixed_factor_ops, - .parent_data = &(const struct clk_parent_data) { - .fw_name = "xtal", - .index = -1, - }, - .num_parents = 1, - }, -}; - -/* - * Taken from the vendor driver for the 2970/2975MHz (both only differ in the - * FRAC part in HHI_VID_PLL_CNTL2) where these values are identical for Meson8, - * Meson8b and Meson8m2. This doubles the input (or output - it's not clear - * which one but the result is the same) clock. The vendor driver additionally - * has the following comment about: "optimise HPLL VCO 2.97GHz performance". - */ -static const struct reg_sequence meson8b_hdmi_pll_init_regs[] = { - { .reg = HHI_VID_PLL_CNTL2, .def = 0x69c84000 }, - { .reg = HHI_VID_PLL_CNTL3, .def = 0x8a46c023 }, - { .reg = HHI_VID_PLL_CNTL4, .def = 0x4123b100 }, - { .reg = HHI_VID_PLL_CNTL5, .def = 0x00012385 }, - { .reg = HHI_VID2_PLL_CNTL2, .def = 0x0430a800 }, -}; - -static const struct pll_params_table hdmi_pll_params_table[] = { - PLL_PARAMS(40, 1), - PLL_PARAMS(42, 1), - PLL_PARAMS(44, 1), - PLL_PARAMS(45, 1), - PLL_PARAMS(49, 1), - PLL_PARAMS(52, 1), - PLL_PARAMS(54, 1), - PLL_PARAMS(56, 1), - PLL_PARAMS(59, 1), - PLL_PARAMS(60, 1), - PLL_PARAMS(61, 1), - PLL_PARAMS(62, 1), - PLL_PARAMS(64, 1), - PLL_PARAMS(66, 1), - PLL_PARAMS(68, 1), - PLL_PARAMS(71, 1), - PLL_PARAMS(82, 1), - { /* sentinel */ } -}; - static struct clk_regmap meson8b_hdmi_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { @@ -200,16 +150,15 @@ static struct clk_regmap meson8b_hdmi_pll_dco = { .shift = 29, .width = 1, }, - .table = hdmi_pll_params_table, - .init_regs = meson8b_hdmi_pll_init_regs, - .init_count = ARRAY_SIZE(meson8b_hdmi_pll_init_regs), }, .hw.init = &(struct clk_init_data){ /* sometimes also called "HPLL" or "HPLL PLL" */ .name = "hdmi_pll_dco", - .ops = &meson_clk_pll_ops, - .parent_hws = (const struct clk_hw *[]) { - &hdmi_pll_dco_in.hw + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + .name = "xtal", + .index = -1, }, .num_parents = 1, }, @@ -224,7 +173,7 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = { }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_lvds_out", - .ops = &clk_regmap_divider_ops, + .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_hdmi_pll_dco.hw }, @@ -242,7 +191,7 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = { }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_hdmi_out", - .ops = &clk_regmap_divider_ops, + .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_hdmi_pll_dco.hw }, @@ -1096,23 +1045,6 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = { }, }; -/* also called LVDS_CLK_EN */ -static struct clk_regmap meson8b_vid_pll_lvds_en = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_DIVIDER_CNTL, - .bit_idx = 11, - }, - .hw.init = &(struct clk_init_data){ - .name = "vid_pll_lvds_en", - .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { - &meson8b_hdmi_pll_lvds_out.hw - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - static struct clk_regmap meson8b_vid_pll_in_sel = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_VID_DIVIDER_CNTL, @@ -1121,7 +1053,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll_in_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, /* * TODO: depending on the SoC there is also a second parent: * Meson8: unknown @@ -1129,7 +1061,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = { * Meson8m2: vid2_pll */ .parent_hws = (const struct clk_hw *[]) { - &meson8b_vid_pll_lvds_en.hw + &meson8b_hdmi_pll_lvds_out.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1143,7 +1075,7 @@ static struct clk_regmap meson8b_vid_pll_in_en = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll_in_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vid_pll_in_sel.hw }, @@ -1160,7 +1092,7 @@ static struct clk_regmap meson8b_vid_pll_pre_div = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll_pre_div", - .ops = &clk_regmap_divider_ops, + .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vid_pll_in_en.hw }, @@ -1177,7 +1109,7 @@ static struct clk_regmap meson8b_vid_pll_post_div = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll_post_div", - .ops = &clk_regmap_divider_ops, + .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vid_pll_pre_div.hw }, @@ -1194,7 +1126,7 @@ static struct clk_regmap meson8b_vid_pll = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */ .parent_hws = (const struct clk_hw *[]) { &meson8b_vid_pll_pre_div.hw, @@ -1213,7 +1145,7 @@ static struct clk_regmap meson8b_vid_pll_final_div = { }, .hw.init = &(struct clk_init_data){ .name = "vid_pll_final_div", - .ops = &clk_regmap_divider_ops, + .ops = &clk_regmap_divider_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vid_pll.hw }, @@ -1240,10 +1172,10 @@ static struct clk_regmap meson8b_vclk_in_sel = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_in_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), - .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -1254,7 +1186,7 @@ static struct clk_regmap meson8b_vclk_in_en = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_in_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_in_sel.hw }, @@ -1270,7 +1202,7 @@ static struct clk_regmap meson8b_vclk_en = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_in_en.hw }, @@ -1286,7 +1218,7 @@ static struct clk_regmap meson8b_vclk_div1_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_div1_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_en.hw }, @@ -1316,7 +1248,7 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_div2_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div2_div.hw }, @@ -1346,7 +1278,7 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_div4_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div4_div.hw }, @@ -1376,7 +1308,7 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_div6_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div6_div.hw }, @@ -1406,7 +1338,7 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk_div12_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk_div12_div.hw }, @@ -1423,10 +1355,10 @@ static struct clk_regmap meson8b_vclk2_in_sel = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_in_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), - .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -1437,7 +1369,7 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_in_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_in_sel.hw }, @@ -1453,7 +1385,7 @@ static struct clk_regmap meson8b_vclk2_clk_en = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_clk_in_en.hw }, @@ -1469,7 +1401,7 @@ static struct clk_regmap meson8b_vclk2_div1_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_div1_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_clk_en.hw }, @@ -1499,7 +1431,7 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_div2_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div2_div.hw }, @@ -1529,7 +1461,7 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_div4_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div4_div.hw }, @@ -1559,7 +1491,7 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_div6_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div6_div.hw }, @@ -1589,7 +1521,7 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = { }, .hw.init = &(struct clk_init_data){ .name = "vclk2_div12_en", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_vclk2_div12_div.hw }, @@ -1614,7 +1546,7 @@ static struct clk_regmap meson8b_cts_enct_sel = { }, .hw.init = &(struct clk_init_data){ .name = "cts_enct_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1628,7 +1560,7 @@ static struct clk_regmap meson8b_cts_enct = { }, .hw.init = &(struct clk_init_data){ .name = "cts_enct", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_cts_enct_sel.hw }, @@ -1645,7 +1577,7 @@ static struct clk_regmap meson8b_cts_encp_sel = { }, .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1659,7 +1591,7 @@ static struct clk_regmap meson8b_cts_encp = { }, .hw.init = &(struct clk_init_data){ .name = "cts_encp", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_cts_encp_sel.hw }, @@ -1676,7 +1608,7 @@ static struct clk_regmap meson8b_cts_enci_sel = { }, .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1690,7 +1622,7 @@ static struct clk_regmap meson8b_cts_enci = { }, .hw.init = &(struct clk_init_data){ .name = "cts_enci", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_cts_enci_sel.hw }, @@ -1707,7 +1639,7 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = { }, .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1721,7 +1653,7 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = { }, .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_hdmi_tx_pixel_sel.hw }, @@ -1746,7 +1678,7 @@ static struct clk_regmap meson8b_cts_encl_sel = { }, .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk2_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1760,7 +1692,7 @@ static struct clk_regmap meson8b_cts_encl = { }, .hw.init = &(struct clk_init_data){ .name = "cts_encl", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_cts_encl_sel.hw }, @@ -1777,7 +1709,7 @@ static struct clk_regmap meson8b_cts_vdac0_sel = { }, .hw.init = &(struct clk_init_data){ .name = "cts_vdac0_sel", - .ops = &clk_regmap_mux_ops, + .ops = &clk_regmap_mux_ro_ops, .parent_hws = meson8b_vclk2_enc_mux_parent_hws, .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, @@ -1791,7 +1723,7 @@ static struct clk_regmap meson8b_cts_vdac0 = { }, .hw.init = &(struct clk_init_data){ .name = "cts_vdac0", - .ops = &clk_regmap_gate_ops, + .ops = &clk_regmap_gate_ro_ops, .parent_hws = (const struct clk_hw *[]) { &meson8b_cts_vdac0_sel.hw }, @@ -2973,8 +2905,6 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLKID_CTS_I958] = &meson8b_cts_i958.hw, - [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, - [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3192,8 +3122,6 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLKID_CTS_I958] = &meson8b_cts_i958.hw, - [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, - [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3413,8 +3341,6 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { [CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw, [CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw, [CLKID_CTS_I958] = &meson8b_cts_i958.hw, - [CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw, - [CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -3613,7 +3539,6 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_cts_mclk_i958_div, &meson8b_cts_mclk_i958, &meson8b_cts_i958, - &meson8b_vid_pll_lvds_en, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index ce62ed47cb..b1a5074cf1 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -51,16 +51,6 @@ #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ #define HHI_VID_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */ -#define HHI_VID_PLL_CNTL3 0x328 /* 0xca offset in data sheet */ -#define HHI_VID_PLL_CNTL4 0x32c /* 0xcb offset in data sheet */ -#define HHI_VID_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */ -#define HHI_VID_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */ -#define HHI_VID2_PLL_CNTL 0x380 /* 0xe0 offset in data sheet */ -#define HHI_VID2_PLL_CNTL2 0x384 /* 0xe1 offset in data sheet */ -#define HHI_VID2_PLL_CNTL3 0x388 /* 0xe2 offset in data sheet */ -#define HHI_VID2_PLL_CNTL4 0x38c /* 0xe3 offset in data sheet */ -#define HHI_VID2_PLL_CNTL5 0x390 /* 0xe4 offset in data sheet */ -#define HHI_VID2_PLL_CNTL6 0x394 /* 0xe5 offset in data sheet */ /* * MPLL register offeset taken from the S905 datasheet. Vendor kernel source @@ -117,11 +107,14 @@ #define CLKID_PERIPH_SEL 125 #define CLKID_AXI_SEL 127 #define CLKID_L2_DRAM_SEL 129 -#define CLKID_HDMI_PLL_LVDS_OUT 131 +#define CLKID_HDMI_PLL_LVDS_OUT 131 +#define CLKID_HDMI_PLL_HDMI_OUT 132 #define CLKID_VID_PLL_IN_SEL 133 #define CLKID_VID_PLL_IN_EN 134 #define CLKID_VID_PLL_PRE_DIV 135 #define CLKID_VID_PLL_POST_DIV 136 +#define CLKID_VID_PLL_FINAL_DIV 137 +#define CLKID_VCLK_IN_SEL 138 #define CLKID_VCLK_IN_EN 139 #define CLKID_VCLK_DIV1 140 #define CLKID_VCLK_DIV2_DIV 141 @@ -132,6 +125,7 @@ #define CLKID_VCLK_DIV6 146 #define CLKID_VCLK_DIV12_DIV 147 #define CLKID_VCLK_DIV12 148 +#define CLKID_VCLK2_IN_SEL 149 #define CLKID_VCLK2_IN_EN 150 #define CLKID_VCLK2_DIV1 151 #define CLKID_VCLK2_DIV2_DIV 152 @@ -143,11 +137,17 @@ #define CLKID_VCLK2_DIV12_DIV 158 #define CLKID_VCLK2_DIV12 159 #define CLKID_CTS_ENCT_SEL 160 +#define CLKID_CTS_ENCT 161 #define CLKID_CTS_ENCP_SEL 162 +#define CLKID_CTS_ENCP 163 #define CLKID_CTS_ENCI_SEL 164 +#define CLKID_CTS_ENCI 165 #define CLKID_HDMI_TX_PIXEL_SEL 166 +#define CLKID_HDMI_TX_PIXEL 167 #define CLKID_CTS_ENCL_SEL 168 +#define CLKID_CTS_ENCL 169 #define CLKID_CTS_VDAC0_SEL 170 +#define CLKID_CTS_VDAC0 171 #define CLKID_HDMI_SYS_SEL 172 #define CLKID_HDMI_SYS_DIV 173 #define CLKID_MALI_0_SEL 175 @@ -182,10 +182,8 @@ #define CLKID_CTS_MCLK_I958_DIV 211 #define CLKID_VCLK_EN 214 #define CLKID_VCLK2_EN 215 -#define CLKID_VID_PLL_LVDS_EN 216 -#define CLKID_HDMI_PLL_DCO_IN 217 -#define CLK_NR_CLKS 218 +#define CLK_NR_CLKS 216 /* * include the CLKID and RESETID that have diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 42c874194d..9ef007b3cf 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -265,14 +265,6 @@ config MSM_MMCC_8974 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. -config MSM_GCC_8976 - tristate "MSM8956/76 Global Clock Controller" - select QCOM_GDSC - help - Support for the global clock controller on msm8956/76 devices. - Say Y if you want to use peripheral devices such as UART, SPI, - i2c, USB, SD/eMMC, SATA, PCIe, etc. - config MSM_MMCC_8994 tristate "MSM8994 Multimedia Clock Controller" select MSM_GCC_8994 @@ -332,14 +324,6 @@ config MSM_MMCC_8998 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. -config QCM_GCC_2290 - tristate "QCM2290 Global Clock Controller" - select QCOM_GDSC - help - Support for the global clock controller on QCM2290 devices. - Say Y if you want to use multimedia devices or peripheral - devices such as UART, SPI, I2C, USB, SD/eMMC etc. - config QCS_GCC_404 tristate "QCS404 Global Clock Controller" help @@ -356,15 +340,6 @@ config SC_CAMCC_7180 Say Y if you want to support camera devices and functionality such as capturing pictures. -config SC_CAMCC_7280 - tristate "SC7280 Camera Clock Controller" - select SC_GCC_7280 - help - Support for the camera clock controller on Qualcomm Technologies, Inc - SC7280 devices. - Say Y if you want to support camera devices and functionality such as - capturing pictures. - config SC_DISPCC_7180 tristate "SC7180 Display Clock Controller" select SC_GCC_7180 @@ -410,6 +385,15 @@ config SC_GCC_8180X Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, UFS, SDCC, etc. +config SC_LPASS_CORECC_7180 + tristate "SC7180 LPASS Core Clock Controller" + select SC_GCC_7180 + help + Support for the LPASS(Low Power Audio Subsystem) core clock controller + on SC7180 devices. + Say Y if you want to use LPASS clocks and power domains of the LPASS + core clock controller. + config SC_GPUCC_7180 tristate "SC7180 Graphics Clock Controller" select SC_GCC_7180 @@ -426,23 +410,6 @@ config SC_GPUCC_7280 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. -config SC_LPASSCC_7280 - tristate "SC7280 Low Power Audio Subsystem (LPASS) Clock Controller" - select SC_GCC_7280 - help - Support for the LPASS clock controller on SC7280 devices. - Say Y if you want to use the LPASS branch clocks of the LPASS clock - controller to reset the LPASS subsystem. - -config SC_LPASS_CORECC_7180 - tristate "SC7180 LPASS Core Clock Controller" - select SC_GCC_7180 - help - Support for the LPASS(Low Power Audio Subsystem) core clock controller - on SC7180 devices. - Say Y if you want to use LPASS clocks and power domains of the LPASS - core clock controller. - config SC_MSS_7180 tristate "SC7180 Modem Clock Controller" select SC_GCC_7180 @@ -572,14 +539,6 @@ config SM_CAMCC_8250 Support for the camera clock controller on SM8250 devices. Say Y if you want to support camera devices and camera functionality. -config SDX_GCC_65 - tristate "SDX65 Global Clock Controller" - select QCOM_GDSC - help - Support for the global clock controller on SDX65 devices. - Say Y if you want to use peripheral devices such as UART, - SPI, I2C, USB, SD/UFS, PCIe etc. - config SM_DISPCC_8250 tristate "SM8150 and SM8250 Display Clock Controller" depends on SM_GCC_8150 || SM_GCC_8250 @@ -634,14 +593,6 @@ config SM_GCC_8350 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. -config SM_GCC_8450 - tristate "SM8450 Global Clock Controller" - select QCOM_GDSC - help - Support for the global clock controller on SM8450 devices. - Say Y if you want to use peripheral devices such as UART, - SPI, I2C, USB, SD/UFS, PCIe etc. - config SM_GPUCC_8150 tristate "SM8150 Graphics Clock Controller" select SM_GCC_8150 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0d98ca9be6..9825ef843f 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o obj-$(CONFIG_MSM_GCC_8953) += gcc-msm8953.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o -obj-$(CONFIG_MSM_GCC_8976) += gcc-msm8976.o obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o @@ -55,12 +54,10 @@ obj-$(CONFIG_QCOM_CLK_APCS_SDX55) += apcs-sdx55.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o -obj-$(CONFIG_QCM_GCC_2290) += gcc-qcm2290.o obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o -obj-$(CONFIG_SC_CAMCC_7280) += camcc-sc7280.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o @@ -68,7 +65,6 @@ obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o -obj-$(CONFIG_SC_LPASSCC_7280) += lpasscc-sc7280.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o @@ -84,7 +80,6 @@ obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o -obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o @@ -92,7 +87,6 @@ obj-$(CONFIG_SM_GCC_6350) += gcc-sm6350.o obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o -obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c index 329d2c5356..9e6decb9c2 100644 --- a/drivers/clk/qcom/a53-pll.c +++ b/drivers/clk/qcom/a53-pll.c @@ -90,6 +90,7 @@ static int qcom_a53pll_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct regmap *regmap; + struct resource *res; struct clk_pll *pll; void __iomem *base; struct clk_init_data init = { }; @@ -99,7 +100,8 @@ static int qcom_a53pll_probe(struct platform_device *pdev) if (!pll) return -ENOMEM; - base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 4406cf609a..8f65b9bdaf 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -140,20 +139,6 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x28, [PLL_OFF_STATUS] = 0x38, }, - [CLK_ALPHA_PLL_TYPE_LUCID_EVO] = { - [PLL_OFF_OPMODE] = 0x04, - [PLL_OFF_STATUS] = 0x0c, - [PLL_OFF_L_VAL] = 0x10, - [PLL_OFF_ALPHA_VAL] = 0x14, - [PLL_OFF_USER_CTL] = 0x18, - [PLL_OFF_USER_CTL_U] = 0x1c, - [PLL_OFF_CONFIG_CTL] = 0x20, - [PLL_OFF_CONFIG_CTL_U] = 0x24, - [PLL_OFF_CONFIG_CTL_U1] = 0x28, - [PLL_OFF_TEST_CTL] = 0x2c, - [PLL_OFF_TEST_CTL_U] = 0x30, - [PLL_OFF_TEST_CTL_U1] = 0x34, - }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -190,10 +175,6 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); #define LUCID_5LPE_PLL_LATCH_INPUT BIT(14) #define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21) -/* LUCID EVO PLL specific settings and offsets */ -#define LUCID_EVO_ENABLE_VOTE_RUN BIT(25) -#define LUCID_EVO_PLL_L_VAL_MASK GENMASK(15, 0) - /* ZONDA PLL specific */ #define ZONDA_PLL_OUT_MASK 0xf #define ZONDA_STAY_IN_CFA BIT(16) @@ -223,7 +204,7 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse, if (ret) return ret; - for (count = 200; count > 0; count--) { + for (count = 100; count > 0; count--) { ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); if (ret) return ret; @@ -1769,32 +1750,24 @@ static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate, LUCID_5LPE_ALPHA_PLL_ACK_LATCH); } -static int __clk_lucid_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate, - unsigned long enable_vote_run) +static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - struct regmap *regmap = pll->clkr.regmap; - int i, val, div, ret; + int i, val = 0, div, ret; u32 mask; /* * If the PLL is in FSM mode, then treat set_rate callback as a * no-operation. */ - ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); + ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val); if (ret) return ret; - if (val & enable_vote_run) + if (val & LUCID_5LPE_ENABLE_VOTE_RUN) return 0; - if (!pll->post_div_table) { - pr_err("Missing the post_div_table for the %s PLL\n", - clk_hw_get_name(&pll->clkr.hw)); - return -EINVAL; - } - div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); for (i = 0; i < pll->num_post_div; i++) { if (pll->post_div_table[i].div == div) { @@ -1808,12 +1781,6 @@ static int __clk_lucid_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rat mask, val << pll->post_div_shift); } -static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_5LPE_ENABLE_VOTE_RUN); -} - const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = { .prepare = alpha_pll_lucid_5lpe_prepare, .enable = alpha_pll_lucid_5lpe_enable, @@ -1993,124 +1960,3 @@ const struct clk_ops clk_alpha_pll_zonda_ops = { .set_rate = clk_zonda_pll_set_rate, }; EXPORT_SYMBOL(clk_alpha_pll_zonda_ops); - -static int alpha_pll_lucid_evo_enable(struct clk_hw *hw) -{ - struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - struct regmap *regmap = pll->clkr.regmap; - u32 val; - int ret; - - ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); - if (ret) - return ret; - - /* If in FSM mode, just vote for it */ - if (val & LUCID_EVO_ENABLE_VOTE_RUN) { - ret = clk_enable_regmap(hw); - if (ret) - return ret; - return wait_for_pll_enable_lock(pll); - } - - /* Check if PLL is already enabled */ - ret = trion_pll_is_enabled(pll, regmap); - if (ret < 0) { - return ret; - } else if (ret) { - pr_warn("%s PLL is already enabled\n", clk_hw_get_name(&pll->clkr.hw)); - return 0; - } - - ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); - if (ret) - return ret; - - /* Set operation mode to RUN */ - regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); - - ret = wait_for_pll_enable_lock(pll); - if (ret) - return ret; - - /* Enable the PLL outputs */ - ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK); - if (ret) - return ret; - - /* Enable the global PLL outputs */ - ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); - if (ret) - return ret; - - /* Ensure that the write above goes through before returning. */ - mb(); - return ret; -} - -static void alpha_pll_lucid_evo_disable(struct clk_hw *hw) -{ - struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - struct regmap *regmap = pll->clkr.regmap; - u32 val; - int ret; - - ret = regmap_read(regmap, PLL_USER_CTL(pll), &val); - if (ret) - return; - - /* If in FSM mode, just unvote it */ - if (val & LUCID_EVO_ENABLE_VOTE_RUN) { - clk_disable_regmap(hw); - return; - } - - /* Disable the global PLL output */ - ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); - if (ret) - return; - - /* Disable the PLL outputs */ - ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0); - if (ret) - return; - - /* Place the PLL mode in STANDBY */ - regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); -} - -static unsigned long alpha_pll_lucid_evo_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - struct regmap *regmap = pll->clkr.regmap; - u32 l, frac; - - regmap_read(regmap, PLL_L_VAL(pll), &l); - l &= LUCID_EVO_PLL_L_VAL_MASK; - regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); - - return alpha_pll_calc_rate(parent_rate, l, frac, pll_alpha_width(pll)); -} - -static int clk_lucid_evo_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - return __clk_lucid_pll_postdiv_set_rate(hw, rate, parent_rate, LUCID_EVO_ENABLE_VOTE_RUN); -} - -const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops = { - .enable = alpha_pll_lucid_evo_enable, - .disable = alpha_pll_lucid_evo_disable, - .is_enabled = clk_trion_pll_is_enabled, - .recalc_rate = alpha_pll_lucid_evo_recalc_rate, - .round_rate = clk_alpha_pll_round_rate, -}; -EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_lucid_evo_ops); - -const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops = { - .recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate, - .round_rate = clk_alpha_pll_postdiv_fabia_round_rate, - .set_rate = clk_lucid_evo_pll_postdiv_set_rate, -}; -EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_evo_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 6e9907deaf..55e4fa4791 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -17,7 +17,6 @@ enum { CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_AGERA, CLK_ALPHA_PLL_TYPE_ZONDA, - CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -152,8 +151,6 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops; extern const struct clk_ops clk_alpha_pll_zonda_ops; #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops -extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops; -extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 74e57c84f6..441d7a20e6 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -515,32 +515,6 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = { /* Resource name must match resource id present in cmd-db */ DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4); -DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4); -DEFINE_CLK_RPMH_VRM(sm8450, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 4); - -static struct clk_hw *sm8450_rpmh_clocks[] = { - [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, - [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw, - [RPMH_LN_BB_CLK1] = &sm8450_ln_bb_clk1.hw, - [RPMH_LN_BB_CLK1_A] = &sm8450_ln_bb_clk1_ao.hw, - [RPMH_LN_BB_CLK2] = &sm8450_ln_bb_clk2.hw, - [RPMH_LN_BB_CLK2_A] = &sm8450_ln_bb_clk2_ao.hw, - [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, - [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, - [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, - [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, - [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, - [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, - [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw, - [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw, - [RPMH_IPA_CLK] = &sdm845_ipa.hw, -}; - -static const struct clk_rpmh_desc clk_rpmh_sm8450 = { - .clks = sm8450_rpmh_clocks, - .num_clks = ARRAY_SIZE(sm8450_rpmh_clocks), -}; - static struct clk_hw *sc7280_rpmh_clocks[] = { [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw, @@ -582,30 +556,6 @@ static const struct clk_rpmh_desc clk_rpmh_sm6350 = { .num_clks = ARRAY_SIZE(sm6350_rpmh_clocks), }; -DEFINE_CLK_RPMH_VRM(sdx65, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 4); - -static struct clk_hw *sdx65_rpmh_clocks[] = { - [RPMH_CXO_CLK] = &sc7280_bi_tcxo.hw, - [RPMH_CXO_CLK_A] = &sc7280_bi_tcxo_ao.hw, - [RPMH_LN_BB_CLK1] = &sdx65_ln_bb_clk1.hw, - [RPMH_LN_BB_CLK1_A] = &sdx65_ln_bb_clk1_ao.hw, - [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, - [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, - [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, - [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, - [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, - [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, - [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw, - [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw, - [RPMH_IPA_CLK] = &sdm845_ipa.hw, - [RPMH_QPIC_CLK] = &sdx55_qpic_clk.hw, -}; - -static const struct clk_rpmh_desc clk_rpmh_sdx65 = { - .clks = sdx65_rpmh_clocks, - .num_clks = ARRAY_SIZE(sdx65_rpmh_clocks), -}; - static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -693,12 +643,10 @@ static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x}, { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, { .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55}, - { .compatible = "qcom,sdx65-rpmh-clk", .data = &clk_rpmh_sdx65}, { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350}, { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250}, { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350}, - { .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450}, { .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280}, { } }; diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index ea28e45ca3..66d7807ee3 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -17,6 +17,7 @@ #include #include +#include #define QCOM_RPM_KEY_SOFTWARE_ENABLE 0x6e657773 #define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY 0x62636370 @@ -117,15 +118,14 @@ __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id, \ 0, QCOM_RPM_SMD_KEY_STATE) -#define DEFINE_CLK_SMD_RPM_XO_BUFFER(_platform, _name, _active, r_id, r) \ +#define DEFINE_CLK_SMD_RPM_XO_BUFFER(_platform, _name, _active, r_id) \ __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, \ - QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, r, \ + QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000, \ QCOM_RPM_KEY_SOFTWARE_ENABLE) -#define DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(_platform, _name, _active, \ - r_id, r) \ +#define DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(_platform, _name, _active, r_id) \ __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, \ - QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, r, \ + QCOM_SMD_RPM_CLK_BUF_A, r_id, 0, 1000, \ QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY) #define to_clk_smd_rpm(_hw) container_of(_hw, struct clk_smd_rpm, hw) @@ -150,6 +150,12 @@ struct clk_smd_rpm_req { __le32 value; }; +struct rpm_cc { + struct qcom_rpm *rpm; + struct clk_smd_rpm **clks; + size_t num_clks; +}; + struct rpm_smd_clk_desc { struct clk_smd_rpm **clks; size_t num_clks; @@ -410,21 +416,20 @@ static const struct clk_ops clk_smd_rpm_ops = { static const struct clk_ops clk_smd_rpm_branch_ops = { .prepare = clk_smd_rpm_prepare, .unprepare = clk_smd_rpm_unprepare, - .recalc_rate = clk_smd_rpm_recalc_rate, }; DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM_QDSS(msm8916, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk1, bb_clk1_a, 1, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk2, bb_clk2_a, 2, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk1, rf_clk1_a, 4, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk2, rf_clk2_a, 5, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk1_pin, bb_clk1_a_pin, 1, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk1, bb_clk1_a, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, bb_clk2, bb_clk2_a, 2); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk1, rf_clk1_a, 4); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8916, rf_clk2, rf_clk2_a, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk1_pin, bb_clk1_a_pin, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5); static struct clk_smd_rpm *msm8916_clks[] = { [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, @@ -498,19 +503,19 @@ DEFINE_CLK_SMD_RPM(msm8974, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); DEFINE_CLK_SMD_RPM(msm8974, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 3); DEFINE_CLK_SMD_RPM(msm8974, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1); DEFINE_CLK_SMD_RPM(msm8974, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a1, cxo_a1_a, 5, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a2, cxo_a2_a, 6, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, diff_clk, diff_a_clk, 7, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk1, div_a_clk1, 11, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk2, div_a_clk2, 12, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d0_pin, cxo_d0_a_pin, 1, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d1_pin, cxo_d1_a_pin, 2, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a1, cxo_a1_a, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a2, cxo_a2_a, 6); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, diff_clk, diff_a_clk, 7); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk1, div_a_clk1, 11); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk2, div_a_clk2, 12); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d0_pin, cxo_d0_a_pin, 1); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d1_pin, cxo_d1_a_pin, 2); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6); static struct clk_smd_rpm *msm8974_clks[] = { [RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk, @@ -598,8 +603,8 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { .num_clks = ARRAY_SIZE(msm8976_clks), }; -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk3, div_clk3_a, 13, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, ln_bb_clk, ln_bb_a_clk, 8, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk3, div_clk3_a, 13); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, ln_bb_clk, ln_bb_a_clk, 8); DEFINE_CLK_SMD_RPM(msm8992, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); DEFINE_CLK_SMD_RPM(msm8992, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1); @@ -777,7 +782,7 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { DEFINE_CLK_SMD_RPM(qcs404, bimc_gpu_clk, bimc_gpu_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8); static struct clk_smd_rpm *qcs404_clks[] = { [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, @@ -806,13 +811,13 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { }; DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin, - 3, 19200000); + 3); DEFINE_CLK_SMD_RPM(msm8998, aggre1_noc_clk, aggre1_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 1); DEFINE_CLK_SMD_RPM(msm8998, aggre2_noc_clk, aggre2_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); static struct clk_smd_rpm *msm8998_clks[] = { [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, @@ -859,8 +864,8 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, ln_bb_clk3_pin_a, 3, 19200000); +DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, ln_bb_clk3_pin_a, 3); static struct clk_smd_rpm *sdm660_clks[] = { [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, @@ -1062,64 +1067,6 @@ static const struct rpm_smd_clk_desc rpm_clk_sm6115 = { .num_clks = ARRAY_SIZE(sm6115_clks), }; -/* QCM2290 */ -DEFINE_CLK_SMD_RPM_XO_BUFFER(qcm2290, ln_bb_clk2, ln_bb_clk2_a, 0x2, 19200000); -DEFINE_CLK_SMD_RPM_XO_BUFFER(qcm2290, rf_clk3, rf_clk3_a, 6, 38400000); - -DEFINE_CLK_SMD_RPM(qcm2290, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0); -DEFINE_CLK_SMD_RPM(qcm2290, hwkm_clk, hwkm_a_clk, QCOM_SMD_RPM_HWKM_CLK, 0); -DEFINE_CLK_SMD_RPM(qcm2290, pka_clk, pka_a_clk, QCOM_SMD_RPM_PKA_CLK, 0); -DEFINE_CLK_SMD_RPM(qcm2290, cpuss_gnoc_clk, cpuss_gnoc_a_clk, - QCOM_SMD_RPM_MEM_CLK, 1); -DEFINE_CLK_SMD_RPM(qcm2290, bimc_gpu_clk, bimc_gpu_a_clk, - QCOM_SMD_RPM_MEM_CLK, 2); - -static struct clk_smd_rpm *qcm2290_clks[] = { - [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, - [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, - [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk, - [RPM_SMD_LN_BB_CLK2] = &qcm2290_ln_bb_clk2, - [RPM_SMD_LN_BB_CLK2_A] = &qcm2290_ln_bb_clk2_a, - [RPM_SMD_RF_CLK3] = &qcm2290_rf_clk3, - [RPM_SMD_RF_CLK3_A] = &qcm2290_rf_clk3_a, - [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk, - [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, - [RPM_SMD_QUP_CLK] = &sm6125_qup_clk, - [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk, - [RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk, - [RPM_SMD_MMRT_A_CLK] = &sm6125_mmrt_a_clk, - [RPM_SMD_MMNRT_CLK] = &sm6125_mmnrt_clk, - [RPM_SMD_MMNRT_A_CLK] = &sm6125_mmnrt_a_clk, - [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk, - [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk, - [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk, - [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk, - [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, - [RPM_SMD_QPIC_CLK] = &qcm2290_qpic_clk, - [RPM_SMD_QPIC_CLK_A] = &qcm2290_qpic_a_clk, - [RPM_SMD_HWKM_CLK] = &qcm2290_hwkm_clk, - [RPM_SMD_HWKM_A_CLK] = &qcm2290_hwkm_a_clk, - [RPM_SMD_PKA_CLK] = &qcm2290_pka_clk, - [RPM_SMD_PKA_A_CLK] = &qcm2290_pka_a_clk, - [RPM_SMD_BIMC_GPU_CLK] = &qcm2290_bimc_gpu_clk, - [RPM_SMD_BIMC_GPU_A_CLK] = &qcm2290_bimc_gpu_a_clk, - [RPM_SMD_CPUSS_GNOC_CLK] = &qcm2290_cpuss_gnoc_clk, - [RPM_SMD_CPUSS_GNOC_A_CLK] = &qcm2290_cpuss_gnoc_a_clk, -}; - -static const struct rpm_smd_clk_desc rpm_clk_qcm2290 = { - .clks = qcm2290_clks, - .num_clks = ARRAY_SIZE(qcm2290_clks), -}; - static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 }, { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, @@ -1132,7 +1079,6 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8994", .data = &rpm_clk_msm8994 }, { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 }, { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, - { .compatible = "qcom,rpmcc-qcm2290", .data = &rpm_clk_qcm2290 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 }, { .compatible = "qcom,rpmcc-sm6115", .data = &rpm_clk_sm6115 }, @@ -1144,19 +1090,20 @@ MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table); static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec, void *data) { - const struct rpm_smd_clk_desc *desc = data; + struct rpm_cc *rcc = data; unsigned int idx = clkspec->args[0]; - if (idx >= desc->num_clks) { + if (idx >= rcc->num_clks) { pr_err("%s: invalid index %u\n", __func__, idx); return ERR_PTR(-EINVAL); } - return desc->clks[idx] ? &desc->clks[idx]->hw : ERR_PTR(-ENOENT); + return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT); } static int rpm_smd_clk_probe(struct platform_device *pdev) { + struct rpm_cc *rcc; int ret; size_t num_clks, i; struct qcom_smd_rpm *rpm; @@ -1176,6 +1123,13 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) rpm_smd_clks = desc->clks; num_clks = desc->num_clks; + rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL); + if (!rcc) + return -ENOMEM; + + rcc->clks = rpm_smd_clks; + rcc->num_clks = num_clks; + for (i = 0; i < num_clks; i++) { if (!rpm_smd_clks[i]) continue; @@ -1201,7 +1155,7 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) } ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get, - (void *)desc); + rcc); if (ret) goto err; diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 75f09e6e05..2af04fc4ab 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -85,9 +85,11 @@ struct regmap * qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) { void __iomem *base; + struct resource *res; struct device *dev = &pdev->dev; - base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return ERR_CAST(base); @@ -323,9 +325,11 @@ int qcom_cc_probe_by_index(struct platform_device *pdev, int index, const struct qcom_cc_desc *desc) { struct regmap *regmap; + struct resource *res; void __iomem *base; - base = devm_platform_ioremap_resource(pdev, index); + res = platform_get_resource(pdev, IORESOURCE_MEM, index); + base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return -ENOMEM; diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index 566fdfa0a1..bf9ffe1a1c 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -1229,31 +1228,13 @@ static const struct of_device_id disp_cc_sm8250_match_table[] = { }; MODULE_DEVICE_TABLE(of, disp_cc_sm8250_match_table); -static void disp_cc_sm8250_pm_runtime_disable(void *data) -{ - pm_runtime_disable(data); -} - static int disp_cc_sm8250_probe(struct platform_device *pdev) { struct regmap *regmap; - int ret; - - pm_runtime_enable(&pdev->dev); - - ret = devm_add_action_or_reset(&pdev->dev, disp_cc_sm8250_pm_runtime_disable, &pdev->dev); - if (ret) - return ret; - - ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret) - return ret; regmap = qcom_cc_map(pdev, &disp_cc_sm8250_desc); - if (IS_ERR(regmap)) { - pm_runtime_put(&pdev->dev); + if (IS_ERR(regmap)) return PTR_ERR(regmap); - } /* note: trion == lucid, except for the prepare() op */ BUILD_BUG_ON(CLK_ALPHA_PLL_TYPE_TRION != CLK_ALPHA_PLL_TYPE_LUCID); @@ -1278,11 +1259,7 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) /* DISP_CC_XO_CLK always-on */ regmap_update_bits(regmap, 0x605c, BIT(0), BIT(0)); - ret = qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap); - - pm_runtime_put(&pdev->dev); - - return ret; + return qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap); } static struct platform_driver disp_cc_sm8250_driver = { diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 8aafa6591e..49513f1366 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -4230,6 +4230,7 @@ static struct platform_driver gcc_msm8953_driver = { .driver = { .name = "gcc-msm8953", .of_match_table = gcc_msm8953_match_table, + .owner = THIS_MODULE, }, }; diff --git a/drivers/clk/qcom/gcc-msm8994.c b/drivers/clk/qcom/gcc-msm8994.c index f09499999e..144d2ba7a9 100644 --- a/drivers/clk/qcom/gcc-msm8994.c +++ b/drivers/clk/qcom/gcc-msm8994.c @@ -2,14 +2,12 @@ /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. */ -#include #include #include #include #include #include #include -#include #include #include #include @@ -30,17 +28,50 @@ enum { P_GPLL4, }; +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const char * const gcc_xo_gpll0[] = { + "xo", + "gpll0", +}; + +static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL4, 5 }, +}; + +static const char * const gcc_xo_gpll0_gpll4[] = { + "xo", + "gpll0", + "gpll4", +}; + +static struct clk_fixed_factor xo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data) + { + .name = "xo", + .parent_names = (const char *[]) { "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + static struct clk_alpha_pll gpll0_early = { - .offset = 0, + .offset = 0x00000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr = { .enable_reg = 0x1480, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gpll0_early", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_ops, }, @@ -48,9 +79,10 @@ static struct clk_alpha_pll gpll0_early = { }; static struct clk_alpha_pll_postdiv gpll0 = { - .offset = 0, + .offset = 0x00000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "gpll0", .parent_names = (const char *[]) { "gpll0_early" }, .num_parents = 1, @@ -64,11 +96,10 @@ static struct clk_alpha_pll gpll4_early = { .clkr = { .enable_reg = 0x1480, .enable_mask = BIT(4), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gpll4_early", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_ops, }, @@ -78,7 +109,8 @@ static struct clk_alpha_pll gpll4_early = { static struct clk_alpha_pll_postdiv gpll4 = { .offset = 0x1dc0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "gpll4", .parent_names = (const char *[]) { "gpll4_early" }, .num_parents = 1, @@ -86,28 +118,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { }, }; -static const struct parent_map gcc_xo_gpll0_map[] = { - { P_XO, 0 }, - { P_GPLL0, 1 }, -}; - -static const struct clk_parent_data gcc_xo_gpll0[] = { - { .fw_name = "xo" }, - { .hw = &gpll0.clkr.hw }, -}; - -static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { - { P_XO, 0 }, - { P_GPLL0, 1 }, - { P_GPLL4, 5 }, -}; - -static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = { - { .fw_name = "xo" }, - { .hw = &gpll0.clkr.hw }, - { .hw = &gpll4.clkr.hw }, -}; - static struct freq_tbl ftbl_ufs_axi_clk_src[] = { F(50000000, P_GPLL0, 12, 0, 0), F(100000000, P_GPLL0, 6, 0, 0), @@ -124,10 +134,11 @@ static struct clk_rcg2 ufs_axi_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_ufs_axi_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "ufs_axi_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -144,10 +155,11 @@ static struct clk_rcg2 usb30_master_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_usb30_master_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "usb30_master_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -163,15 +175,16 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup1_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { +static struct freq_tbl ftbl_blspqup_spi_apps_clk_src[] = { F(960000, P_XO, 10, 1, 2), F(4800000, P_XO, 4, 0, 0), F(9600000, P_XO, 2, 0, 0), @@ -184,27 +197,17 @@ static struct freq_tbl ftbl_blsp1_qup1_spi_apps_clk_src[] = { { } }; -static struct freq_tbl ftbl_blsp1_qup_spi_apps_clk_src_8992[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(25000000, P_GPLL0, 12, 1, 2), - F(50000000, P_GPLL0, 12, 0, 0), - { } -}; - static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { .cmd_rcgr = 0x064c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup1_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -214,37 +217,26 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup2_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp1_qup2_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(42860000, P_GPLL0, 14, 0, 0), - F(46150000, P_GPLL0, 13, 0, 0), - { } -}; - static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .cmd_rcgr = 0x06cc, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup2_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup2_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -254,37 +246,26 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup3_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp1_qup3_4_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(42860000, P_GPLL0, 14, 0, 0), - F(44440000, P_GPLL0, 13.5, 0, 0), - { } -}; - static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { .cmd_rcgr = 0x074c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup3_4_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup3_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -294,10 +275,11 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup4_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -307,11 +289,12 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup3_4_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup4_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -321,37 +304,26 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup5_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp1_qup5_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(40000000, P_GPLL0, 15, 0, 0), - F(42860000, P_GPLL0, 14, 0, 0), - { } -}; - static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { .cmd_rcgr = 0x084c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup5_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup5_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -361,37 +333,26 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup6_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp1_qup6_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(27906976, P_GPLL0, 1, 2, 43), - F(41380000, P_GPLL0, 15, 0, 0), - F(42860000, P_GPLL0, 14, 0, 0), - { } -}; - static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { .cmd_rcgr = 0x08cc, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp1_qup6_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_qup6_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -421,10 +382,11 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart1_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -435,10 +397,11 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart2_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -449,10 +412,11 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart3_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -463,10 +427,11 @@ static struct clk_rcg2 blsp1_uart4_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart4_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -477,10 +442,11 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart5_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -491,10 +457,11 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp1_uart6_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -504,37 +471,26 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup1_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp2_qup1_2_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(42860000, P_GPLL0, 14, 0, 0), - F(44440000, P_GPLL0, 13.5, 0, 0), - { } -}; - static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { .cmd_rcgr = 0x098c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp2_qup1_2_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup1_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -544,10 +500,11 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup2_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -557,37 +514,26 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp2_qup1_2_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup2_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp2_qup3_4_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(42860000, P_GPLL0, 14, 0, 0), - F(48000000, P_GPLL0, 12.5, 0, 0), - { } -}; - static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { .cmd_rcgr = 0x0aa0, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup3_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -597,11 +543,12 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp2_qup3_4_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup3_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -611,10 +558,11 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup4_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -624,11 +572,12 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp2_qup3_4_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup4_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -638,10 +587,11 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup5_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -651,12 +601,12 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = { .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - /* BLSP1 QUP1 and BLSP2 QUP5 use the same freqs */ - .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup5_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -666,37 +616,26 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_i2c_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup6_i2c_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; -static struct freq_tbl ftbl_blsp2_qup6_spi_apps_clk_src[] = { - F(960000, P_XO, 10, 1, 2), - F(4800000, P_XO, 4, 0, 0), - F(9600000, P_XO, 2, 0, 0), - F(15000000, P_GPLL0, 10, 1, 4), - F(19200000, P_XO, 1, 0, 0), - F(24000000, P_GPLL0, 12.5, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(44440000, P_GPLL0, 13.5, 0, 0), - F(48000000, P_GPLL0, 12.5, 0, 0), - { } -}; - static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = { .cmd_rcgr = 0x0c0c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_blsp2_qup6_spi_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .freq_tbl = ftbl_blspqup_spi_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_qup6_spi_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -707,10 +646,11 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart1_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -721,10 +661,11 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart2_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -735,10 +676,11 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart3_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -749,10 +691,11 @@ static struct clk_rcg2 blsp2_uart4_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart4_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -763,10 +706,11 @@ static struct clk_rcg2 blsp2_uart5_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart5_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -777,10 +721,11 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_blsp_uart_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "blsp2_uart6_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -798,10 +743,11 @@ static struct clk_rcg2 gp1_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_gp1_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "gp1_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -819,10 +765,11 @@ static struct clk_rcg2 gp2_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_gp2_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "gp2_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -840,10 +787,11 @@ static struct clk_rcg2 gp3_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_gp3_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "gp3_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -858,11 +806,10 @@ static struct clk_rcg2 pcie_0_aux_clk_src = { .mnd_width = 8, .hid_width = 5, .freq_tbl = ftbl_pcie_0_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "pcie_0_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -877,11 +824,10 @@ static struct clk_rcg2 pcie_0_pipe_clk_src = { .cmd_rcgr = 0x1adc, .hid_width = 5, .freq_tbl = ftbl_pcie_pipe_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "pcie_0_pipe_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -897,11 +843,10 @@ static struct clk_rcg2 pcie_1_aux_clk_src = { .mnd_width = 8, .hid_width = 5, .freq_tbl = ftbl_pcie_1_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "pcie_1_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -911,11 +856,10 @@ static struct clk_rcg2 pcie_1_pipe_clk_src = { .cmd_rcgr = 0x1b5c, .hid_width = 5, .freq_tbl = ftbl_pcie_pipe_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "pcie_1_pipe_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -931,10 +875,11 @@ static struct clk_rcg2 pdm2_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_pdm2_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "pdm2_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -951,28 +896,17 @@ static struct freq_tbl ftbl_sdcc1_apps_clk_src[] = { { } }; -static struct freq_tbl ftbl_sdcc1_apps_clk_src_8992[] = { - F(144000, P_XO, 16, 3, 25), - F(400000, P_XO, 12, 1, 4), - F(20000000, P_GPLL0, 15, 1, 2), - F(25000000, P_GPLL0, 12, 1, 2), - F(50000000, P_GPLL0, 12, 0, 0), - F(100000000, P_GPLL0, 6, 0, 0), - F(172000000, P_GPLL4, 2, 0, 0), - F(344000000, P_GPLL4, 1, 0, 0), - { } -}; - static struct clk_rcg2 sdcc1_apps_clk_src = { .cmd_rcgr = 0x04d0, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_xo_gpll0_gpll4_map, .freq_tbl = ftbl_sdcc1_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "sdcc1_apps_clk_src", - .parent_data = gcc_xo_gpll0_gpll4, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4), + .parent_names = gcc_xo_gpll0_gpll4, + .num_parents = 3, .ops = &clk_rcg2_floor_ops, }, }; @@ -994,10 +928,11 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_sdcc2_4_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "sdcc2_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_floor_ops, }, }; @@ -1008,10 +943,11 @@ static struct clk_rcg2 sdcc3_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_sdcc2_4_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "sdcc3_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_floor_ops, }, }; @@ -1022,10 +958,11 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_sdcc2_4_apps_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "sdcc4_apps_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_floor_ops, }, }; @@ -1040,11 +977,10 @@ static struct clk_rcg2 tsif_ref_clk_src = { .mnd_width = 8, .hid_width = 5, .freq_tbl = ftbl_tsif_ref_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "tsif_ref_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -1061,10 +997,11 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_usb30_mock_utmi_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "usb30_mock_utmi_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -1078,11 +1015,10 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = { .cmd_rcgr = 0x1414, .hid_width = 5, .freq_tbl = ftbl_usb3_phy_aux_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "usb3_phy_aux_clk_src", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo", - }, + .parent_names = (const char *[]) { "xo" }, .num_parents = 1, .ops = &clk_rcg2_ops, }, @@ -1098,10 +1034,11 @@ static struct clk_rcg2 usb_hs_system_clk_src = { .hid_width = 5, .parent_map = gcc_xo_gpll0_map, .freq_tbl = ftbl_usb_hs_system_clk_src, - .clkr.hw.init = &(struct clk_init_data){ + .clkr.hw.init = &(struct clk_init_data) + { .name = "usb_hs_system_clk_src", - .parent_data = gcc_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .parent_names = gcc_xo_gpll0, + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -1112,7 +1049,8 @@ static struct clk_branch gcc_blsp1_ahb_clk = { .clkr = { .enable_reg = 0x1484, .enable_mask = BIT(17), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1124,9 +1062,12 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { .clkr = { .enable_reg = 0x0648, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup1_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup1_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup1_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1139,9 +1080,12 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { .clkr = { .enable_reg = 0x0644, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup1_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup1_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup1_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1154,9 +1098,12 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { .clkr = { .enable_reg = 0x06c8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup2_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup2_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup2_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1169,9 +1116,12 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { .clkr = { .enable_reg = 0x06c4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup2_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup2_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup2_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1184,9 +1134,12 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { .clkr = { .enable_reg = 0x0748, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup3_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup3_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup3_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1199,9 +1152,12 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { .clkr = { .enable_reg = 0x0744, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup3_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup3_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup3_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1214,9 +1170,12 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { .clkr = { .enable_reg = 0x07c8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup4_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup4_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup4_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1229,9 +1188,12 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { .clkr = { .enable_reg = 0x07c4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup4_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup4_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup4_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1244,9 +1206,12 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = { .clkr = { .enable_reg = 0x0848, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup5_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup5_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup5_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1259,9 +1224,12 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = { .clkr = { .enable_reg = 0x0844, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup5_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup5_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup5_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1274,9 +1242,12 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = { .clkr = { .enable_reg = 0x08c8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup6_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup6_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup6_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1289,9 +1260,12 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { .clkr = { .enable_reg = 0x08c4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_qup6_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_qup6_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_qup6_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1304,9 +1278,12 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = { .clkr = { .enable_reg = 0x0684, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart1_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart1_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart1_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1319,9 +1296,12 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = { .clkr = { .enable_reg = 0x0704, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart2_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart2_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart2_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1334,9 +1314,12 @@ static struct clk_branch gcc_blsp1_uart3_apps_clk = { .clkr = { .enable_reg = 0x0784, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart3_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart3_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart3_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1349,9 +1332,12 @@ static struct clk_branch gcc_blsp1_uart4_apps_clk = { .clkr = { .enable_reg = 0x0804, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart4_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart4_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart4_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1364,9 +1350,12 @@ static struct clk_branch gcc_blsp1_uart5_apps_clk = { .clkr = { .enable_reg = 0x0884, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart5_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart5_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart5_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1379,9 +1368,12 @@ static struct clk_branch gcc_blsp1_uart6_apps_clk = { .clkr = { .enable_reg = 0x0904, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp1_uart6_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp1_uart6_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp1_uart6_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1395,7 +1387,8 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .clkr = { .enable_reg = 0x1484, .enable_mask = BIT(15), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1407,9 +1400,12 @@ static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { .clkr = { .enable_reg = 0x0988, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup1_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup1_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup1_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1422,9 +1418,12 @@ static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { .clkr = { .enable_reg = 0x0984, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup1_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup1_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup1_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1437,9 +1436,12 @@ static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { .clkr = { .enable_reg = 0x0a08, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup2_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup2_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup2_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1452,9 +1454,12 @@ static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { .clkr = { .enable_reg = 0x0a04, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup2_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup2_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup2_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1467,9 +1472,12 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { .clkr = { .enable_reg = 0x0a88, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup3_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup3_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup3_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1482,9 +1490,12 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { .clkr = { .enable_reg = 0x0a84, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup3_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup3_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup3_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1497,9 +1508,12 @@ static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { .clkr = { .enable_reg = 0x0b08, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup4_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup4_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup4_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1512,9 +1526,12 @@ static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { .clkr = { .enable_reg = 0x0b04, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup4_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup4_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup4_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1527,9 +1544,12 @@ static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = { .clkr = { .enable_reg = 0x0b88, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup5_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup5_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup5_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1542,9 +1562,12 @@ static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = { .clkr = { .enable_reg = 0x0b84, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup5_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup5_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup5_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1557,9 +1580,12 @@ static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = { .clkr = { .enable_reg = 0x0c08, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup6_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup6_i2c_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup6_i2c_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1572,9 +1598,12 @@ static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = { .clkr = { .enable_reg = 0x0c04, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_qup6_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_qup6_spi_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_qup6_spi_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1587,9 +1616,12 @@ static struct clk_branch gcc_blsp2_uart1_apps_clk = { .clkr = { .enable_reg = 0x09c4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart1_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart1_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart1_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1602,9 +1634,12 @@ static struct clk_branch gcc_blsp2_uart2_apps_clk = { .clkr = { .enable_reg = 0x0a44, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart2_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart2_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart2_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1617,9 +1652,12 @@ static struct clk_branch gcc_blsp2_uart3_apps_clk = { .clkr = { .enable_reg = 0x0ac4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart3_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart3_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart3_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1632,9 +1670,12 @@ static struct clk_branch gcc_blsp2_uart4_apps_clk = { .clkr = { .enable_reg = 0x0b44, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart4_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart4_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart4_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1647,9 +1688,12 @@ static struct clk_branch gcc_blsp2_uart5_apps_clk = { .clkr = { .enable_reg = 0x0bc4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart5_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart5_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart5_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1662,9 +1706,12 @@ static struct clk_branch gcc_blsp2_uart6_apps_clk = { .clkr = { .enable_reg = 0x0c44, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_blsp2_uart6_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &blsp2_uart6_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "blsp2_uart6_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1677,9 +1724,12 @@ static struct clk_branch gcc_gp1_clk = { .clkr = { .enable_reg = 0x1900, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_gp1_clk", - .parent_hws = (const struct clk_hw *[]){ &gp1_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "gp1_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1692,9 +1742,12 @@ static struct clk_branch gcc_gp2_clk = { .clkr = { .enable_reg = 0x1940, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_gp2_clk", - .parent_hws = (const struct clk_hw *[]){ &gp2_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "gp2_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1707,9 +1760,12 @@ static struct clk_branch gcc_gp3_clk = { .clkr = { .enable_reg = 0x1980, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_gp3_clk", - .parent_hws = (const struct clk_hw *[]){ &gp3_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "gp3_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1722,7 +1778,8 @@ static struct clk_branch gcc_lpass_q6_axi_clk = { .clkr = { .enable_reg = 0x0280, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_lpass_q6_axi_clk", .ops = &clk_branch2_ops, }, @@ -1734,7 +1791,8 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .clkr = { .enable_reg = 0x0284, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_mss_q6_bimc_axi_clk", .ops = &clk_branch2_ops, }, @@ -1746,9 +1804,12 @@ static struct clk_branch gcc_pcie_0_aux_clk = { .clkr = { .enable_reg = 0x1ad4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_0_aux_clk", - .parent_hws = (const struct clk_hw *[]){ &pcie_0_aux_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "pcie_0_aux_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1761,7 +1822,8 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { .clkr = { .enable_reg = 0x1ad0, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_0_cfg_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1773,7 +1835,8 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { .clkr = { .enable_reg = 0x1acc, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_0_mstr_axi_clk", .ops = &clk_branch2_ops, }, @@ -1786,9 +1849,12 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { .clkr = { .enable_reg = 0x1ad8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_0_pipe_clk", - .parent_hws = (const struct clk_hw *[]){ &pcie_0_pipe_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "pcie_0_pipe_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1802,7 +1868,8 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = { .clkr = { .enable_reg = 0x1ac8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_0_slv_axi_clk", .ops = &clk_branch2_ops, }, @@ -1814,9 +1881,12 @@ static struct clk_branch gcc_pcie_1_aux_clk = { .clkr = { .enable_reg = 0x1b54, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_1_aux_clk", - .parent_hws = (const struct clk_hw *[]){ &pcie_1_aux_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "pcie_1_aux_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1829,7 +1899,8 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { .clkr = { .enable_reg = 0x1b54, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_1_cfg_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1841,7 +1912,8 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { .clkr = { .enable_reg = 0x1b50, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_1_mstr_axi_clk", .ops = &clk_branch2_ops, }, @@ -1854,9 +1926,12 @@ static struct clk_branch gcc_pcie_1_pipe_clk = { .clkr = { .enable_reg = 0x1b58, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_1_pipe_clk", - .parent_hws = (const struct clk_hw *[]){ &pcie_1_pipe_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "pcie_1_pipe_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1869,7 +1944,8 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = { .clkr = { .enable_reg = 0x1b48, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pcie_1_slv_axi_clk", .ops = &clk_branch2_ops, }, @@ -1881,9 +1957,12 @@ static struct clk_branch gcc_pdm2_clk = { .clkr = { .enable_reg = 0x0ccc, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pdm2_clk", - .parent_hws = (const struct clk_hw *[]){ &pdm2_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "pdm2_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1896,7 +1975,8 @@ static struct clk_branch gcc_pdm_ahb_clk = { .clkr = { .enable_reg = 0x0cc4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_pdm_ahb_clk", .ops = &clk_branch2_ops, }, @@ -1908,9 +1988,12 @@ static struct clk_branch gcc_sdcc1_apps_clk = { .clkr = { .enable_reg = 0x04c4, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc1_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &sdcc1_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "sdcc1_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1923,8 +2006,13 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { .clkr = { .enable_reg = 0x04c8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc1_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1935,8 +2023,13 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { .clkr = { .enable_reg = 0x0508, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc2_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1947,9 +2040,12 @@ static struct clk_branch gcc_sdcc2_apps_clk = { .clkr = { .enable_reg = 0x0504, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc2_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &sdcc2_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "sdcc2_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1962,8 +2058,13 @@ static struct clk_branch gcc_sdcc3_ahb_clk = { .clkr = { .enable_reg = 0x0548, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc3_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1974,9 +2075,12 @@ static struct clk_branch gcc_sdcc3_apps_clk = { .clkr = { .enable_reg = 0x0544, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc3_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &sdcc3_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "sdcc3_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -1989,8 +2093,13 @@ static struct clk_branch gcc_sdcc4_ahb_clk = { .clkr = { .enable_reg = 0x0588, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc4_ahb_clk", + .parent_names = (const char *[]){ + "periph_noc_clk_src", + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -2001,9 +2110,12 @@ static struct clk_branch gcc_sdcc4_apps_clk = { .clkr = { .enable_reg = 0x0584, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sdcc4_apps_clk", - .parent_hws = (const struct clk_hw *[]){ &sdcc4_apps_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "sdcc4_apps_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2016,9 +2128,12 @@ static struct clk_branch gcc_sys_noc_ufs_axi_clk = { .clkr = { .enable_reg = 0x1d7c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sys_noc_ufs_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &ufs_axi_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "ufs_axi_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2031,9 +2146,12 @@ static struct clk_branch gcc_sys_noc_usb3_axi_clk = { .clkr = { .enable_reg = 0x03fc, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_sys_noc_usb3_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &usb30_master_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "usb30_master_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2046,7 +2164,8 @@ static struct clk_branch gcc_tsif_ahb_clk = { .clkr = { .enable_reg = 0x0d84, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_tsif_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2058,9 +2177,12 @@ static struct clk_branch gcc_tsif_ref_clk = { .clkr = { .enable_reg = 0x0d88, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_tsif_ref_clk", - .parent_hws = (const struct clk_hw *[]){ &tsif_ref_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "tsif_ref_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2073,7 +2195,8 @@ static struct clk_branch gcc_ufs_ahb_clk = { .clkr = { .enable_reg = 0x1d4c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2085,9 +2208,12 @@ static struct clk_branch gcc_ufs_axi_clk = { .clkr = { .enable_reg = 0x1d48, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_axi_clk", - .parent_hws = (const struct clk_hw *[]){ &ufs_axi_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "ufs_axi_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2100,9 +2226,12 @@ static struct clk_branch gcc_ufs_rx_cfg_clk = { .clkr = { .enable_reg = 0x1d54, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_rx_cfg_clk", - .parent_hws = (const struct clk_hw *[]){ &ufs_axi_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "ufs_axi_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2116,7 +2245,8 @@ static struct clk_branch gcc_ufs_rx_symbol_0_clk = { .clkr = { .enable_reg = 0x1d60, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_rx_symbol_0_clk", .ops = &clk_branch2_ops, }, @@ -2129,7 +2259,8 @@ static struct clk_branch gcc_ufs_rx_symbol_1_clk = { .clkr = { .enable_reg = 0x1d64, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_rx_symbol_1_clk", .ops = &clk_branch2_ops, }, @@ -2141,9 +2272,12 @@ static struct clk_branch gcc_ufs_tx_cfg_clk = { .clkr = { .enable_reg = 0x1d50, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_tx_cfg_clk", - .parent_hws = (const struct clk_hw *[]){ &ufs_axi_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "ufs_axi_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2157,7 +2291,8 @@ static struct clk_branch gcc_ufs_tx_symbol_0_clk = { .clkr = { .enable_reg = 0x1d58, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_tx_symbol_0_clk", .ops = &clk_branch2_ops, }, @@ -2170,7 +2305,8 @@ static struct clk_branch gcc_ufs_tx_symbol_1_clk = { .clkr = { .enable_reg = 0x1d5c, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_ufs_tx_symbol_1_clk", .ops = &clk_branch2_ops, }, @@ -2182,13 +2318,9 @@ static struct clk_branch gcc_usb2_hs_phy_sleep_clk = { .clkr = { .enable_reg = 0x04ac, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb2_hs_phy_sleep_clk", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "sleep", - .name = "sleep" - }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -2199,9 +2331,12 @@ static struct clk_branch gcc_usb30_master_clk = { .clkr = { .enable_reg = 0x03c8, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb30_master_clk", - .parent_hws = (const struct clk_hw *[]){ &usb30_master_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "usb30_master_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2214,9 +2349,12 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = { .clkr = { .enable_reg = 0x03d0, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb30_mock_utmi_clk", - .parent_hws = (const struct clk_hw *[]){ &usb30_mock_utmi_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "usb30_mock_utmi_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2229,13 +2367,9 @@ static struct clk_branch gcc_usb30_sleep_clk = { .clkr = { .enable_reg = 0x03cc, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb30_sleep_clk", - .parent_data = &(const struct clk_parent_data){ - .fw_name = "sleep", - .name = "sleep" - }, - .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -2246,9 +2380,12 @@ static struct clk_branch gcc_usb3_phy_aux_clk = { .clkr = { .enable_reg = 0x1408, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb3_phy_aux_clk", - .parent_hws = (const struct clk_hw *[]){ &usb3_phy_aux_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "usb3_phy_aux_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2256,25 +2393,13 @@ static struct clk_branch gcc_usb3_phy_aux_clk = { }, }; -static struct clk_branch gcc_usb3_phy_pipe_clk = { - .halt_reg = 0x140c, - .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x140c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_usb3_phy_pipe_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_usb_hs_ahb_clk = { .halt_reg = 0x0488, .clkr = { .enable_reg = 0x0488, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb_hs_ahb_clk", .ops = &clk_branch2_ops, }, @@ -2286,9 +2411,12 @@ static struct clk_branch gcc_usb_hs_system_clk = { .clkr = { .enable_reg = 0x0484, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb_hs_system_clk", - .parent_hws = (const struct clk_hw *[]){ &usb_hs_system_clk_src.clkr.hw }, + .parent_names = (const char *[]) { + "usb_hs_system_clk_src", + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, @@ -2301,119 +2429,20 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { .clkr = { .enable_reg = 0x1a84, .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ + .hw.init = &(struct clk_init_data) + { .name = "gcc_usb_phy_cfg_ahb2phy_clk", .ops = &clk_branch2_ops, }, }, }; -static struct clk_branch gpll0_out_mmsscc = { - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x1484, - .enable_mask = BIT(26), - .hw.init = &(struct clk_init_data){ - .name = "gpll0_out_mmsscc", - .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw }, - .num_parents = 1, - .ops = &clk_branch2_ops, +static struct gdsc pcie_gdsc = { + .gdscr = 0x1e18, + .pd = { + .name = "pcie", }, - }, -}; - -static struct clk_branch gpll0_out_msscc = { - .halt_check = BRANCH_HALT_DELAY, - .clkr = { - .enable_reg = 0x1484, - .enable_mask = BIT(27), - .hw.init = &(struct clk_init_data){ - .name = "gpll0_out_msscc", - .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch pcie_0_phy_ldo = { - .halt_reg = 0x1e00, - .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x1E00, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "pcie_0_phy_ldo", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch pcie_1_phy_ldo = { - .halt_reg = 0x1e04, - .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x1E04, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "pcie_1_phy_ldo", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch ufs_phy_ldo = { - .halt_reg = 0x1e0c, - .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x1E0C, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "ufs_phy_ldo", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch usb_ss_phy_ldo = { - .halt_reg = 0x1e08, - .halt_check = BRANCH_HALT_SKIP, - .clkr = { - .enable_reg = 0x1E08, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "usb_ss_phy_ldo", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_boot_rom_ahb_clk = { - .halt_reg = 0x0e04, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x0e04, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x1484, - .enable_mask = BIT(10), - .hw.init = &(struct clk_init_data){ - .name = "gcc_boot_rom_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_prng_ahb_clk = { - .halt_reg = 0x0d04, - .halt_check = BRANCH_HALT_VOTED, - .clkr = { - .enable_reg = 0x1484, - .enable_mask = BIT(13), - .hw.init = &(struct clk_init_data){ - .name = "gcc_prng_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, + .pwrsts = PWRSTS_OFF_ON, }; static struct gdsc pcie_0_gdsc = { @@ -2587,32 +2616,13 @@ static struct clk_regmap *gcc_msm8994_clocks[] = { [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, - [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, - [GPLL0_OUT_MMSSCC] = &gpll0_out_mmsscc.clkr, - [GPLL0_OUT_MSSCC] = &gpll0_out_msscc.clkr, - [PCIE_0_PHY_LDO] = &pcie_0_phy_ldo.clkr, - [PCIE_1_PHY_LDO] = &pcie_1_phy_ldo.clkr, - [UFS_PHY_LDO] = &ufs_phy_ldo.clkr, - [USB_SS_PHY_LDO] = &usb_ss_phy_ldo.clkr, - [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, - [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, - - /* - * The following clocks should NOT be managed by this driver, but they once were - * mistakengly added. Now they are only here to indicate that they are not defined - * on purpose, even though the names will stay in the header file (for ABI sanity). - */ - [CONFIG_NOC_CLK_SRC] = NULL, - [PERIPH_NOC_CLK_SRC] = NULL, - [SYSTEM_NOC_CLK_SRC] = NULL, }; static struct gdsc *gcc_msm8994_gdscs[] = { - /* This GDSC does not exist, but ABI has to remain intact */ - [PCIE_GDSC] = NULL, + [PCIE_GDSC] = &pcie_gdsc, [PCIE_0_GDSC] = &pcie_0_gdsc, [PCIE_1_GDSC] = &pcie_1_gdsc, [USB30_GDSC] = &usb30_gdsc, @@ -2622,7 +2632,6 @@ static struct gdsc *gcc_msm8994_gdscs[] = { static const struct qcom_reset_map gcc_msm8994_resets[] = { [USB3_PHY_RESET] = { 0x1400 }, [USB3PHY_PHY_RESET] = { 0x1404 }, - [MSS_RESET] = { 0x1680 }, [PCIE_PHY_0_RESET] = { 0x1b18 }, [PCIE_PHY_1_RESET] = { 0x1b98 }, [QUSB2_PHY_RESET] = { 0x04b8 }, @@ -2647,57 +2656,19 @@ static const struct qcom_cc_desc gcc_msm8994_desc = { }; static const struct of_device_id gcc_msm8994_match_table[] = { - { .compatible = "qcom,gcc-msm8992" }, - { .compatible = "qcom,gcc-msm8994" }, /* V2 and V2.1 */ + { .compatible = "qcom,gcc-msm8994" }, {} }; MODULE_DEVICE_TABLE(of, gcc_msm8994_match_table); static int gcc_msm8994_probe(struct platform_device *pdev) { - if (of_device_is_compatible(pdev->dev.of_node, "qcom,gcc-msm8992")) { - /* MSM8992 features less clocks and some have different freq tables */ - gcc_msm8994_desc.clks[UFS_AXI_CLK_SRC] = NULL; - gcc_msm8994_desc.clks[GCC_LPASS_Q6_AXI_CLK] = NULL; - gcc_msm8994_desc.clks[UFS_PHY_LDO] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_AHB_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_AXI_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_RX_CFG_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_RX_SYMBOL_0_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_RX_SYMBOL_1_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_TX_CFG_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_TX_SYMBOL_0_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_UFS_TX_SYMBOL_1_CLK] = NULL; + struct device *dev = &pdev->dev; + struct clk *clk; - sdcc1_apps_clk_src.freq_tbl = ftbl_sdcc1_apps_clk_src_8992; - blsp1_qup1_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp1_qup2_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp1_qup3_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp1_qup4_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp1_qup5_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp1_qup6_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup1_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup2_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup3_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup4_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup5_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - blsp2_qup6_i2c_apps_clk_src.freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src_8992; - - /* - * Some 8992 boards might *possibly* use - * PCIe1 clocks and controller, but it's not - * standard and they should be disabled otherwise. - */ - gcc_msm8994_desc.clks[PCIE_1_AUX_CLK_SRC] = NULL; - gcc_msm8994_desc.clks[PCIE_1_PIPE_CLK_SRC] = NULL; - gcc_msm8994_desc.clks[PCIE_1_PHY_LDO] = NULL; - gcc_msm8994_desc.clks[GCC_PCIE_1_AUX_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_PCIE_1_CFG_AHB_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_PCIE_1_MSTR_AXI_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_PCIE_1_PIPE_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_PCIE_1_SLV_AXI_CLK] = NULL; - gcc_msm8994_desc.clks[GCC_SYS_NOC_UFS_AXI_CLK] = NULL; - } + clk = devm_clk_register(dev, &xo.hw); + if (IS_ERR(clk)) + return PTR_ERR(clk); return qcom_cc_probe(pdev, &gcc_msm8994_desc); } diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 407e2c5cae..050c91af88 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -25,366 +25,6 @@ #include "reset.h" #include "gdsc.h" -static struct pll_vco fabia_vco[] = { - { 250000000, 2000000000, 0 }, - { 125000000, 1000000000, 1 }, -}; - -static struct clk_alpha_pll gpll0 = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .vco_table = fabia_vco, - .num_vco = ARRAY_SIZE(fabia_vco), - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gpll0", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - } - }, -}; - -static struct clk_alpha_pll_postdiv gpll0_out_even = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll0_out_even", - .parent_hws = (const struct clk_hw*[]) { - &gpll0.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll0_out_main = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll0_out_main", - .parent_hws = (const struct clk_hw*[]) { - &gpll0.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll0_out_odd = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll0_out_odd", - .parent_hws = (const struct clk_hw*[]) { - &gpll0.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll0_out_test = { - .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll0_out_test", - .parent_hws = (const struct clk_hw*[]) { - &gpll0.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll gpll1 = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .vco_table = fabia_vco, - .num_vco = ARRAY_SIZE(fabia_vco), - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(1), - .hw.init = &(struct clk_init_data){ - .name = "gpll1", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - } - }, -}; - -static struct clk_alpha_pll_postdiv gpll1_out_even = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll1_out_even", - .parent_hws = (const struct clk_hw*[]) { - &gpll1.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll1_out_main = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll1_out_main", - .parent_hws = (const struct clk_hw*[]) { - &gpll1.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll1_out_odd = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll1_out_odd", - .parent_hws = (const struct clk_hw*[]) { - &gpll1.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll1_out_test = { - .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll1_out_test", - .parent_hws = (const struct clk_hw*[]) { - &gpll1.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll gpll2 = { - .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .vco_table = fabia_vco, - .num_vco = ARRAY_SIZE(fabia_vco), - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(2), - .hw.init = &(struct clk_init_data){ - .name = "gpll2", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - } - }, -}; - -static struct clk_alpha_pll_postdiv gpll2_out_even = { - .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll2_out_even", - .parent_hws = (const struct clk_hw*[]) { - &gpll2.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll2_out_main = { - .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll2_out_main", - .parent_hws = (const struct clk_hw*[]) { - &gpll2.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll2_out_odd = { - .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll2_out_odd", - .parent_hws = (const struct clk_hw*[]) { - &gpll2.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll2_out_test = { - .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll2_out_test", - .parent_hws = (const struct clk_hw*[]) { - &gpll2.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll gpll3 = { - .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .vco_table = fabia_vco, - .num_vco = ARRAY_SIZE(fabia_vco), - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(3), - .hw.init = &(struct clk_init_data){ - .name = "gpll3", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - } - }, -}; - -static struct clk_alpha_pll_postdiv gpll3_out_even = { - .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll3_out_even", - .parent_hws = (const struct clk_hw*[]) { - &gpll3.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll3_out_main = { - .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll3_out_main", - .parent_hws = (const struct clk_hw*[]) { - &gpll3.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll3_out_odd = { - .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll3_out_odd", - .parent_hws = (const struct clk_hw*[]) { - &gpll3.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll3_out_test = { - .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll3_out_test", - .parent_hws = (const struct clk_hw*[]) { - &gpll3.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll gpll4 = { - .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .vco_table = fabia_vco, - .num_vco = ARRAY_SIZE(fabia_vco), - .clkr = { - .enable_reg = 0x52000, - .enable_mask = BIT(4), - .hw.init = &(struct clk_init_data){ - .name = "gpll4", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_fixed_fabia_ops, - } - }, -}; - -static struct clk_alpha_pll_postdiv gpll4_out_even = { - .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll4_out_even", - .parent_hws = (const struct clk_hw*[]) { - &gpll4.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll4_out_main = { - .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll4_out_main", - .parent_hws = (const struct clk_hw*[]) { - &gpll4.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll4_out_odd = { - .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll4_out_odd", - .parent_hws = (const struct clk_hw*[]) { - &gpll4.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - -static struct clk_alpha_pll_postdiv gpll4_out_test = { - .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], - .clkr.hw.init = &(struct clk_init_data){ - .name = "gpll4_out_test", - .parent_hws = (const struct clk_hw*[]) { - &gpll4.clkr.hw, - }, - .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_fabia_ops, - }, -}; - enum { P_AUD_REF_CLK, P_CORE_BI_PLL_TEST_SE, @@ -402,11 +42,11 @@ static const struct parent_map gcc_parent_map_0[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_0[] = { - { .fw_name = "xo" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .hw = &gpll0_out_main.clkr.hw }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_0[] = { + "xo", + "gpll0_out_main", + "gpll0_out_main", + "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_1[] = { @@ -415,10 +55,10 @@ static const struct parent_map gcc_parent_map_1[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_1[] = { - { .fw_name = "xo" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_1[] = { + "xo", + "gpll0_out_main", + "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_2[] = { @@ -429,12 +69,12 @@ static const struct parent_map gcc_parent_map_2[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_2[] = { - { .fw_name = "xo" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .fw_name = "sleep_clk" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_2[] = { + "xo", + "gpll0_out_main", + "core_pi_sleep_clk", + "gpll0_out_main", + "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_3[] = { @@ -443,10 +83,10 @@ static const struct parent_map gcc_parent_map_3[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_3[] = { - { .fw_name = "xo" }, - { .fw_name = "sleep_clk" }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_3[] = { + "xo", + "core_pi_sleep_clk", + "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_4[] = { @@ -456,11 +96,11 @@ static const struct parent_map gcc_parent_map_4[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_4[] = { - { .fw_name = "xo" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .hw = &gpll4_out_main.clkr.hw }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_4[] = { + "xo", + "gpll0_out_main", + "gpll4_out_main", + "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_5[] = { @@ -470,11 +110,332 @@ static const struct parent_map gcc_parent_map_5[] = { { P_CORE_BI_PLL_TEST_SE, 7 }, }; -static const struct clk_parent_data gcc_parent_data_5[] = { - { .fw_name = "xo" }, - { .hw = &gpll0_out_main.clkr.hw }, - { .fw_name = "aud_ref_clk" }, - { .fw_name = "core_bi_pll_test_se" }, +static const char * const gcc_parent_names_5[] = { + "xo", + "gpll0_out_main", + "aud_ref_clk", + "core_bi_pll_test_se", +}; + +static struct clk_fixed_factor xo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "xo", + .parent_names = (const char *[]){ "xo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct pll_vco fabia_vco[] = { + { 250000000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0_out_main = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_main", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0_out_odd = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_odd", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0_out_test = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_test", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv gpll1_out_even = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1_out_even", + .parent_names = (const char *[]){ "gpll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll1_out_main = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1_out_main", + .parent_names = (const char *[]){ "gpll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll1_out_odd = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1_out_odd", + .parent_names = (const char *[]){ "gpll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll1_out_test = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1_out_test", + .parent_names = (const char *[]){ "gpll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gpll2", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv gpll2_out_even = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll2_out_even", + .parent_names = (const char *[]){ "gpll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2_out_main = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll2_out_main", + .parent_names = (const char *[]){ "gpll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2_out_odd = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll2_out_odd", + .parent_names = (const char *[]){ "gpll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2_out_test = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll2_out_test", + .parent_names = (const char *[]){ "gpll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gpll3", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv gpll3_out_even = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3_out_even", + .parent_names = (const char *[]){ "gpll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll3_out_main = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3_out_main", + .parent_names = (const char *[]){ "gpll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll3_out_odd = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3_out_odd", + .parent_names = (const char *[]){ "gpll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll3_out_test = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll3_out_test", + .parent_names = (const char *[]){ "gpll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll gpll4 = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + } + }, +}; + +static struct clk_alpha_pll_postdiv gpll4_out_even = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4_out_even", + .parent_names = (const char *[]){ "gpll4" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4_out_main = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4_out_main", + .parent_names = (const char *[]){ "gpll4" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4_out_odd = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4_out_odd", + .parent_names = (const char *[]){ "gpll4" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll_postdiv gpll4_out_test = { + .offset = 0x77000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll4_out_test", + .parent_names = (const char *[]){ "gpll4" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, }; static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = { @@ -491,8 +452,8 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup1_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -516,8 +477,8 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup1_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -530,8 +491,8 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup2_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -544,8 +505,8 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup2_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -558,8 +519,8 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup3_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -572,8 +533,8 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup3_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -586,8 +547,8 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup4_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -600,8 +561,8 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup4_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -614,8 +575,8 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup5_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -628,8 +589,8 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup5_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -642,8 +603,8 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup6_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -656,8 +617,8 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup6_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -689,8 +650,8 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_uart1_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -703,8 +664,8 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_uart2_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -717,8 +678,8 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_uart3_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -731,8 +692,8 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup1_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -745,8 +706,8 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup1_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -759,8 +720,8 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup2_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -773,8 +734,8 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup2_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -787,8 +748,8 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup3_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -801,8 +762,8 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup3_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -815,8 +776,8 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup4_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -829,8 +790,8 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup4_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -843,8 +804,8 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup5_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -857,8 +818,8 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup5_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -871,8 +832,8 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup6_i2c_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -885,8 +846,8 @@ static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = { .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup6_spi_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -899,8 +860,8 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_uart1_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -913,8 +874,8 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_uart2_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -927,8 +888,8 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = { .freq_tbl = ftbl_blsp1_uart1_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_uart3_apps_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -948,8 +909,8 @@ static struct clk_rcg2 gp1_clk_src = { .freq_tbl = ftbl_gp1_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gp1_clk_src", - .parent_data = gcc_parent_data_2, - .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .parent_names = gcc_parent_names_2, + .num_parents = 5, .ops = &clk_rcg2_ops, }, }; @@ -962,8 +923,8 @@ static struct clk_rcg2 gp2_clk_src = { .freq_tbl = ftbl_gp1_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gp2_clk_src", - .parent_data = gcc_parent_data_2, - .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .parent_names = gcc_parent_names_2, + .num_parents = 5, .ops = &clk_rcg2_ops, }, }; @@ -976,8 +937,8 @@ static struct clk_rcg2 gp3_clk_src = { .freq_tbl = ftbl_gp1_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "gp3_clk_src", - .parent_data = gcc_parent_data_2, - .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .parent_names = gcc_parent_names_2, + .num_parents = 5, .ops = &clk_rcg2_ops, }, }; @@ -997,8 +958,8 @@ static struct clk_rcg2 hmss_ahb_clk_src = { .freq_tbl = ftbl_hmss_ahb_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_ahb_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -1016,8 +977,8 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = { .freq_tbl = ftbl_hmss_rbcpr_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_rbcpr_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -1035,8 +996,8 @@ static struct clk_rcg2 pcie_aux_clk_src = { .freq_tbl = ftbl_pcie_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "pcie_aux_clk_src", - .parent_data = gcc_parent_data_3, - .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .parent_names = gcc_parent_names_3, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -1054,8 +1015,8 @@ static struct clk_rcg2 pdm2_clk_src = { .freq_tbl = ftbl_pdm2_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "pdm2_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -1079,8 +1040,8 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .freq_tbl = ftbl_sdcc2_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc2_apps_clk_src", - .parent_data = gcc_parent_data_4, - .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .parent_names = gcc_parent_names_4, + .num_parents = 4, .ops = &clk_rcg2_floor_ops, }, }; @@ -1103,8 +1064,8 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .freq_tbl = ftbl_sdcc4_apps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc4_apps_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = 3, .ops = &clk_rcg2_floor_ops, }, }; @@ -1122,8 +1083,8 @@ static struct clk_rcg2 tsif_ref_clk_src = { .freq_tbl = ftbl_tsif_ref_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "tsif_ref_clk_src", - .parent_data = gcc_parent_data_5, - .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .parent_names = gcc_parent_names_5, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1143,8 +1104,8 @@ static struct clk_rcg2 ufs_axi_clk_src = { .freq_tbl = ftbl_ufs_axi_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_axi_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1164,8 +1125,8 @@ static struct clk_rcg2 ufs_unipro_core_clk_src = { .freq_tbl = ftbl_ufs_unipro_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_unipro_core_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1186,8 +1147,8 @@ static struct clk_rcg2 usb30_master_clk_src = { .freq_tbl = ftbl_usb30_master_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "usb30_master_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1200,8 +1161,8 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = { .freq_tbl = ftbl_hmss_rbcpr_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "usb30_mock_utmi_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .parent_names = gcc_parent_names_0, + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1219,8 +1180,8 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = { .freq_tbl = ftbl_usb3_phy_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "usb3_phy_aux_clk_src", - .parent_data = gcc_parent_data_3, - .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .parent_names = gcc_parent_names_3, + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -1246,8 +1207,8 @@ static struct clk_branch gcc_aggre1_ufs_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_aggre1_ufs_axi_clk", - .parent_hws = (const struct clk_hw *[]) { - &ufs_axi_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "ufs_axi_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1264,8 +1225,8 @@ static struct clk_branch gcc_aggre1_usb3_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_aggre1_usb3_axi_clk", - .parent_hws = (const struct clk_hw *[]) { - &usb30_master_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "usb30_master_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1387,8 +1348,8 @@ static struct clk_branch gcc_mmss_gpll0_clk = { .enable_mask = BIT(1), .hw.init = &(struct clk_init_data){ .name = "gcc_mmss_gpll0_clk", - .parent_hws = (const struct clk_hw *[]) { - &gpll0_out_main.clkr.hw, + .parent_names = (const char *[]){ + "gpll0_out_main", }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -1429,8 +1390,8 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup1_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup1_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1447,8 +1408,8 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup1_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup1_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1465,8 +1426,8 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup2_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup2_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1483,8 +1444,8 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup2_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup2_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1501,8 +1462,8 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup3_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup3_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup3_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1519,8 +1480,8 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup3_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup3_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup3_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1537,8 +1498,8 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup4_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup4_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup4_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1555,8 +1516,8 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup4_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup4_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup4_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1573,8 +1534,8 @@ static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup5_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup5_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup5_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1591,8 +1552,8 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup5_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup5_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup5_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1609,8 +1570,8 @@ static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup6_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup6_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup6_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1627,8 +1588,8 @@ static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_qup6_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_qup6_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_qup6_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1658,8 +1619,8 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart1_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_uart1_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1676,8 +1637,8 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart2_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_uart2_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1694,8 +1655,8 @@ static struct clk_branch gcc_blsp1_uart3_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_uart3_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp1_uart3_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp1_uart3_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1725,8 +1686,8 @@ static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup1_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup1_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup1_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1743,8 +1704,8 @@ static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup1_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup1_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup1_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1761,8 +1722,8 @@ static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup2_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup2_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup2_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1779,8 +1740,8 @@ static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup2_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup2_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup2_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1797,8 +1758,8 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup3_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup3_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup3_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1815,8 +1776,8 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup3_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup3_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup3_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1833,8 +1794,8 @@ static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup4_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup4_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup4_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1851,8 +1812,8 @@ static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup4_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup4_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup4_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1869,8 +1830,8 @@ static struct clk_branch gcc_blsp2_qup5_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup5_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup5_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup5_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1887,8 +1848,8 @@ static struct clk_branch gcc_blsp2_qup5_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup5_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup5_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup5_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1905,8 +1866,8 @@ static struct clk_branch gcc_blsp2_qup6_i2c_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup6_i2c_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup6_i2c_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup6_i2c_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1923,8 +1884,8 @@ static struct clk_branch gcc_blsp2_qup6_spi_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_qup6_spi_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_qup6_spi_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_qup6_spi_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1954,8 +1915,8 @@ static struct clk_branch gcc_blsp2_uart1_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_uart1_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_uart1_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_uart1_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1972,8 +1933,8 @@ static struct clk_branch gcc_blsp2_uart2_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_uart2_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_uart2_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_uart2_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1990,8 +1951,8 @@ static struct clk_branch gcc_blsp2_uart3_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_uart3_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &blsp2_uart3_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "blsp2_uart3_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2008,8 +1969,8 @@ static struct clk_branch gcc_cfg_noc_usb3_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_cfg_noc_usb3_axi_clk", - .parent_hws = (const struct clk_hw *[]) { - &usb30_master_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "usb30_master_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2026,8 +1987,8 @@ static struct clk_branch gcc_gp1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp1_clk", - .parent_hws = (const struct clk_hw *[]) { - &gp1_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "gp1_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2044,8 +2005,8 @@ static struct clk_branch gcc_gp2_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp2_clk", - .parent_hws = (const struct clk_hw *[]) { - &gp2_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "gp2_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2062,8 +2023,8 @@ static struct clk_branch gcc_gp3_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_gp3_clk", - .parent_hws = (const struct clk_hw *[]) { - &gp3_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "gp3_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2151,8 +2112,8 @@ static struct clk_branch gcc_hmss_ahb_clk = { .enable_mask = BIT(21), .hw.init = &(struct clk_init_data){ .name = "gcc_hmss_ahb_clk", - .parent_hws = (const struct clk_hw *[]) { - &hmss_ahb_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "hmss_ahb_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2182,8 +2143,8 @@ static struct clk_branch gcc_hmss_rbcpr_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_hmss_rbcpr_clk", - .parent_hws = (const struct clk_hw *[]) { - &hmss_rbcpr_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "hmss_rbcpr_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2218,8 +2179,8 @@ static struct clk_rcg2 hmss_gpll0_clk_src = { .freq_tbl = ftbl_hmss_gpll0_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "hmss_gpll0_clk_src", - .parent_data = gcc_parent_data_1, - .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .parent_names = gcc_parent_names_1, + .num_parents = ARRAY_SIZE(gcc_parent_names_1), .ops = &clk_rcg2_ops, }, }; @@ -2303,8 +2264,8 @@ static struct clk_branch gcc_pcie_0_aux_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie_0_aux_clk", - .parent_hws = (const struct clk_hw *[]) { - &pcie_aux_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "pcie_aux_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2373,8 +2334,8 @@ static struct clk_branch gcc_pcie_phy_aux_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie_phy_aux_clk", - .parent_hws = (const struct clk_hw *[]) { - &pcie_aux_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "pcie_aux_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2391,8 +2352,8 @@ static struct clk_branch gcc_pdm2_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pdm2_clk", - .parent_hws = (const struct clk_hw *[]) { - &pdm2_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "pdm2_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2461,8 +2422,8 @@ static struct clk_branch gcc_sdcc2_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &sdcc2_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "sdcc2_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2492,8 +2453,8 @@ static struct clk_branch gcc_sdcc4_apps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_sdcc4_apps_clk", - .parent_hws = (const struct clk_hw *[]) { - &sdcc4_apps_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "sdcc4_apps_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2536,8 +2497,8 @@ static struct clk_branch gcc_tsif_ref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_tsif_ref_clk", - .parent_hws = (const struct clk_hw *[]) { - &tsif_ref_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "tsif_ref_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2567,8 +2528,8 @@ static struct clk_branch gcc_ufs_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_axi_clk", - .parent_hws = (const struct clk_hw *[]) { - &ufs_axi_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "ufs_axi_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2650,8 +2611,8 @@ static struct clk_branch gcc_ufs_unipro_core_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_unipro_core_clk", - .parent_hws = (const struct clk_hw *[]) { - &ufs_unipro_core_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "ufs_unipro_core_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2668,8 +2629,8 @@ static struct clk_branch gcc_usb30_master_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb30_master_clk", - .parent_hws = (const struct clk_hw *[]) { - &usb30_master_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "usb30_master_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2686,8 +2647,8 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb30_mock_utmi_clk", - .parent_hws = (const struct clk_hw *[]) { - &usb30_mock_utmi_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2717,8 +2678,8 @@ static struct clk_branch gcc_usb3_phy_aux_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb3_phy_aux_clk", - .parent_hws = (const struct clk_hw *[]) { - &usb3_phy_aux_clk_src.clkr.hw, + .parent_names = (const char *[]){ + "usb3_phy_aux_clk_src", }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -2760,9 +2721,7 @@ static struct clk_branch gcc_hdmi_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_hdmi_clkref_clk", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, + .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2776,9 +2735,7 @@ static struct clk_branch gcc_ufs_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_clkref_clk", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, + .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2792,9 +2749,7 @@ static struct clk_branch gcc_usb3_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_usb3_clkref_clk", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, + .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2808,9 +2763,7 @@ static struct clk_branch gcc_pcie_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie_clkref_clk", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, + .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2824,9 +2777,7 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_rx1_usb2_clkref_clk", - .parent_data = (const struct clk_parent_data []) { - { .fw_name = "xo" }, - }, + .parent_names = (const char *[]){ "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -3164,6 +3115,10 @@ static const struct regmap_config gcc_msm8998_regmap_config = { .fast_io = true, }; +static struct clk_hw *gcc_msm8998_hws[] = { + &xo.hw, +}; + static const struct qcom_cc_desc gcc_msm8998_desc = { .config = &gcc_msm8998_regmap_config, .clks = gcc_msm8998_clocks, @@ -3172,6 +3127,8 @@ static const struct qcom_cc_desc gcc_msm8998_desc = { .num_resets = ARRAY_SIZE(gcc_msm8998_resets), .gdscs = gcc_msm8998_gdscs, .num_gdscs = ARRAY_SIZE(gcc_msm8998_gdscs), + .clk_hws = gcc_msm8998_hws, + .num_clk_hws = ARRAY_SIZE(gcc_msm8998_hws), }; static int gcc_msm8998_probe(struct platform_device *pdev) diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c index 423627d497..ce7c5ba2b9 100644 --- a/drivers/clk/qcom/gcc-sc7280.c +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -197,6 +197,12 @@ static const struct clk_parent_data gcc_parent_data_0[] = { { .hw = &gcc_gpll0_out_even.clkr.hw }, }; +static const struct clk_parent_data gcc_parent_data_0_ao[] = { + { .fw_name = "bi_tcxo_ao" }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + static const struct parent_map gcc_parent_map_1[] = { { P_BI_TCXO, 0 }, { P_GCC_GPLL0_OUT_MAIN, 1 }, @@ -473,6 +479,24 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { }, }, }; +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x4800c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parent_data_0_ao, + .num_parents = ARRAY_SIZE(gcc_parent_data_0_ao), + .ops = &clk_rcg2_ops, + }, +}; static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), @@ -1215,6 +1239,21 @@ static struct clk_rcg2 gcc_sec_ctrl_clk_src = { }, }; +static struct clk_regmap_div gcc_cpuss_ahb_postdiv_clk_src = { + .reg = 0x48024, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gcc_cpuss_ahb_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gcc_cpuss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { .reg = 0xf050, .shift = 0, @@ -1461,6 +1500,27 @@ static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = { }, }; +/* For CPUSS functionality the AHB clock needs to be left enabled */ +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_cpuss_ahb_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ddrss_gpu_axi_clk = { .halt_reg = 0x71154, .halt_check = BRANCH_HALT_SKIP, @@ -2548,6 +2608,27 @@ static struct clk_branch gcc_sdcc4_apps_clk = { }, }; +/* For CPUSS functionality the AHB clock needs to be left enabled */ +static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x48178, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48178, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_cpuss_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_cpuss_ahb_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_throttle_pcie_ahb_clk = { .halt_reg = 0x9001c, .halt_check = BRANCH_HALT, @@ -3213,6 +3294,9 @@ static struct clk_regmap *gcc_sc7280_clocks[] = { [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_CPUSS_AHB_POSTDIV_CLK_SRC] = &gcc_cpuss_ahb_postdiv_clk_src.clkr, [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, [GCC_DDRSS_PCIE_SF_CLK] = &gcc_ddrss_pcie_sf_clk.clkr, [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, @@ -3319,6 +3403,7 @@ static struct clk_regmap *gcc_sc7280_clocks[] = { [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, [GCC_THROTTLE_PCIE_AHB_CLK] = &gcc_throttle_pcie_ahb_clk.clkr, [GCC_TITAN_NRT_THROTTLE_CORE_CLK] = &gcc_titan_nrt_throttle_core_clk.clkr, diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index 9b97425008..4d36f96e9a 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -284,7 +284,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup1_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -309,7 +309,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup1_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -323,7 +323,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup2_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -337,7 +337,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup2_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -351,7 +351,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup3_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -365,7 +365,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup3_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -379,7 +379,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup4_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -393,7 +393,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_qup4_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -426,7 +426,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_uart1_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -440,7 +440,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp1_uart2_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -454,7 +454,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup1_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -468,7 +468,7 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup1_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -482,7 +482,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup2_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -496,7 +496,7 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup2_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -510,7 +510,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup3_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -524,7 +524,7 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup3_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -538,7 +538,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup4_i2c_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -552,7 +552,7 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_qup4_spi_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -566,7 +566,7 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_uart1_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -580,7 +580,7 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "blsp2_uart2_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -601,7 +601,7 @@ static struct clk_rcg2 gp1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gp1_clk_src", .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -615,7 +615,7 @@ static struct clk_rcg2 gp2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gp2_clk_src", .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -629,7 +629,7 @@ static struct clk_rcg2 gp3_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gp3_clk_src", .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -649,7 +649,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_gpll0_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -670,7 +670,7 @@ static struct clk_rcg2 hmss_gpll4_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_gpll4_clk_src", .parent_data = gcc_parent_data_xo_gpll4, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll4), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -689,7 +689,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_rbcpr_clk_src", .parent_data = gcc_parent_data_xo_gpll0, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -708,7 +708,7 @@ static struct clk_rcg2 pdm2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "pdm2_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -730,7 +730,7 @@ static struct clk_rcg2 qspi_ser_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "qspi_ser_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -756,7 +756,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc1_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -778,7 +778,7 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -804,7 +804,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "sdcc2_apps_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div_gpll4, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div_gpll4), + .num_parents = 4, .ops = &clk_rcg2_floor_ops, }, }; @@ -827,7 +827,7 @@ static struct clk_rcg2 ufs_axi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_axi_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -848,7 +848,7 @@ static struct clk_rcg2 ufs_ice_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_ice_core_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -862,7 +862,7 @@ static struct clk_rcg2 ufs_phy_aux_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_phy_aux_clk_src", .parent_data = gcc_parent_data_xo_sleep_clk, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_sleep_clk), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -883,7 +883,7 @@ static struct clk_rcg2 ufs_unipro_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ufs_unipro_core_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -904,7 +904,7 @@ static struct clk_rcg2 usb20_master_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "usb20_master_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -924,7 +924,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "usb20_mock_utmi_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -949,7 +949,7 @@ static struct clk_rcg2 usb30_master_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "usb30_master_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -970,7 +970,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "usb30_mock_utmi_clk_src", .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll0_early_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -990,7 +990,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "usb3_phy_aux_clk_src", .parent_data = gcc_parent_data_xo_sleep_clk, - .num_parents = ARRAY_SIZE(gcc_parent_data_xo_sleep_clk), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c index a4f7fba703..3236706771 100644 --- a/drivers/clk/qcom/gcc-sm6350.c +++ b/drivers/clk/qcom/gcc-sm6350.c @@ -4,7 +4,6 @@ * Copyright (c) 2021, Konrad Dybcio */ -#include #include #include #include diff --git a/drivers/clk/qcom/gcc-sm8350.c b/drivers/clk/qcom/gcc-sm8350.c index c3731f96c8..6d0a9e2d51 100644 --- a/drivers/clk/qcom/gcc-sm8350.c +++ b/drivers/clk/qcom/gcc-sm8350.c @@ -4,7 +4,6 @@ * Copyright (c) 2020-2021, Linaro Limited */ -#include #include #include #include diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 7e1dd8ccfa..4ece326ea2 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -51,22 +50,6 @@ enum gdsc_status { GDSC_ON }; -static int gdsc_pm_runtime_get(struct gdsc *sc) -{ - if (!sc->dev) - return 0; - - return pm_runtime_resume_and_get(sc->dev); -} - -static int gdsc_pm_runtime_put(struct gdsc *sc) -{ - if (!sc->dev) - return 0; - - return pm_runtime_put_sync(sc->dev); -} - /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */ static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status) { @@ -249,8 +232,9 @@ static void gdsc_retain_ff_on(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); } -static int _gdsc_enable(struct gdsc *sc) +static int gdsc_enable(struct generic_pm_domain *domain) { + struct gdsc *sc = domain_to_gdsc(domain); int ret; if (sc->pwrsts == PWRSTS_ON) @@ -306,22 +290,11 @@ static int _gdsc_enable(struct gdsc *sc) return 0; } -static int gdsc_enable(struct generic_pm_domain *domain) +static int gdsc_disable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; - ret = gdsc_pm_runtime_get(sc); - if (ret) - return ret; - - return _gdsc_enable(sc); -} - -static int _gdsc_disable(struct gdsc *sc) -{ - int ret; - if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -356,18 +329,6 @@ static int _gdsc_disable(struct gdsc *sc) return 0; } -static int gdsc_disable(struct generic_pm_domain *domain) -{ - struct gdsc *sc = domain_to_gdsc(domain); - int ret; - - ret = _gdsc_disable(sc); - - gdsc_pm_runtime_put(sc); - - return ret; -} - static int gdsc_init(struct gdsc *sc) { u32 mask, val; @@ -482,8 +443,6 @@ int gdsc_register(struct gdsc_desc *desc, for (i = 0; i < num; i++) { if (!scs[i]) continue; - if (pm_runtime_enabled(dev)) - scs[i]->dev = dev; scs[i]->regmap = regmap; scs[i]->rcdev = rcdev; ret = gdsc_init(scs[i]); @@ -498,8 +457,6 @@ int gdsc_register(struct gdsc_desc *desc, continue; if (scs[i]->parent) pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); - else if (!IS_ERR_OR_NULL(dev->pm_domain)) - pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); } return of_genpd_add_provider_onecell(dev->of_node, data); @@ -518,8 +475,6 @@ void gdsc_unregister(struct gdsc_desc *desc) continue; if (scs[i]->parent) pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); - else if (!IS_ERR_OR_NULL(dev->pm_domain)) - pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); } of_genpd_del_provider(dev->of_node); } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index d7cc4c21a9..5bb396b344 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -25,7 +25,6 @@ struct reset_controller_dev; * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller - * @dev: the device holding the GDSC, used for pm_runtime calls */ struct gdsc { struct generic_pm_domain pd; @@ -59,7 +58,6 @@ struct gdsc { const char *supply; struct regulator *rsupply; - struct device *dev; }; struct gdsc_desc { diff --git a/drivers/clk/qcom/gpucc-msm8998.c b/drivers/clk/qcom/gpucc-msm8998.c index a925ac9001..fedfffaf0a 100644 --- a/drivers/clk/qcom/gpucc-msm8998.c +++ b/drivers/clk/qcom/gpucc-msm8998.c @@ -40,7 +40,8 @@ static struct clk_branch gpucc_cxo_clk = { .hw.init = &(struct clk_init_data){ .name = "gpucc_cxo_clk", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -98,7 +99,7 @@ static const struct parent_map gpu_xo_gpll0_map[] = { static const struct clk_parent_data gpu_xo_gpll0[] = { { .hw = &gpucc_cxo_clk.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, }; static const struct parent_map gpu_xo_gpupll0_map[] = { @@ -125,7 +126,7 @@ static struct clk_rcg2 rbcpr_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rbcpr_clk_src", .parent_data = gpu_xo_gpll0, - .num_parents = ARRAY_SIZE(gpu_xo_gpll0), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -143,7 +144,7 @@ static struct clk_rcg2 gfx3d_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gfx3d_clk_src", .parent_data = gpu_xo_gpupll0, - .num_parents = ARRAY_SIZE(gpu_xo_gpupll0), + .num_parents = 2, .ops = &clk_rcg2_ops, .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, }, @@ -162,7 +163,7 @@ static struct clk_rcg2 rbbmtimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rbbmtimer_clk_src", .parent_data = gpu_xo_gpll0, - .num_parents = ARRAY_SIZE(gpu_xo_gpll0), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; @@ -183,7 +184,7 @@ static struct clk_rcg2 gfx3d_isense_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gfx3d_isense_clk_src", .parent_data = gpu_xo_gpll0, - .num_parents = ARRAY_SIZE(gpu_xo_gpll0), + .num_parents = 2, .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/gpucc-sdm660.c b/drivers/clk/qcom/gpucc-sdm660.c index 41bba96a08..1ebcceb3a5 100644 --- a/drivers/clk/qcom/gpucc-sdm660.c +++ b/drivers/clk/qcom/gpucc-sdm660.c @@ -44,7 +44,8 @@ static struct clk_branch gpucc_cxo_clk = { .hw.init = &(struct clk_init_data){ .name = "gpucc_cxo_clk", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -100,7 +101,7 @@ static const struct clk_parent_data gpucc_parent_data_1[] = { { .hw = &gpucc_cxo_clk.clkr.hw }, { .hw = &gpu_pll0_pll_out_main.clkr.hw }, { .hw = &gpu_pll1_pll_out_main.clkr.hw }, - { .fw_name = "gcc_gpu_gpll0_clk" }, + { .fw_name = "gcc_gpu_gpll0_clk", .name = "gcc_gpu_gpll0_clk" }, }; static struct clk_rcg2_gfx3d gfx3d_clk_src = { @@ -113,7 +114,7 @@ static struct clk_rcg2_gfx3d gfx3d_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "gfx3d_clk_src", .parent_data = gpucc_parent_data_1, - .num_parents = ARRAY_SIZE(gpucc_parent_data_1), + .num_parents = 4, .ops = &clk_gfx3d_ops, .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, }, @@ -153,8 +154,8 @@ static const struct parent_map gpucc_parent_map_0[] = { static const struct clk_parent_data gpucc_parent_data_0[] = { { .hw = &gpucc_cxo_clk.clkr.hw }, - { .fw_name = "gcc_gpu_gpll0_clk" }, - { .fw_name = "gcc_gpu_gpll0_div_clk" }, + { .fw_name = "gcc_gpu_gpll0_clk", .name = "gcc_gpu_gpll0_clk" }, + { .fw_name = "gcc_gpu_gpll0_div_clk", .name = "gcc_gpu_gpll0_div_clk" }, }; static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = { @@ -171,7 +172,7 @@ static struct clk_rcg2 rbbmtimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rbbmtimer_clk_src", .parent_data = gpucc_parent_data_0, - .num_parents = ARRAY_SIZE(gpucc_parent_data_0), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -191,7 +192,7 @@ static struct clk_rcg2 rbcpr_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rbcpr_clk_src", .parent_data = gpucc_parent_data_0, - .num_parents = ARRAY_SIZE(gpucc_parent_data_0), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/kpss-xcc.c b/drivers/clk/qcom/kpss-xcc.c index 4fec1f9142..8590b5edd1 100644 --- a/drivers/clk/qcom/kpss-xcc.c +++ b/drivers/clk/qcom/kpss-xcc.c @@ -33,6 +33,7 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) { const struct of_device_id *id; struct clk *clk; + struct resource *res; void __iomem *base; const char *name; @@ -40,7 +41,8 @@ static int kpss_xcc_driver_probe(struct platform_device *pdev) if (!id) return -ENODEV; - base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/qcom/lpasscc-sdm845.c b/drivers/clk/qcom/lpasscc-sdm845.c index 7040da9527..56d3e99288 100644 --- a/drivers/clk/qcom/lpasscc-sdm845.c +++ b/drivers/clk/qcom/lpasscc-sdm845.c @@ -3,7 +3,6 @@ * Copyright (c) 2018, The Linux Foundation. All rights reserved. */ -#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index e9f9713591..fbfcf00067 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c @@ -3,7 +3,6 @@ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. */ -#include #include #include #include diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c index c421b12916..467dadccde 100644 --- a/drivers/clk/qcom/mmcc-msm8998.c +++ b/drivers/clk/qcom/mmcc-msm8998.c @@ -53,7 +53,8 @@ static struct clk_fixed_factor gpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mmss_gpll0_div", .parent_data = &(const struct clk_parent_data){ - .fw_name = "gpll0" + .fw_name = "gpll0", + .name = "gpll0" }, .num_parents = 1, .ops = &clk_fixed_factor_ops, @@ -77,7 +78,8 @@ static struct clk_alpha_pll mmpll0 = { .hw.init = &(struct clk_init_data){ .name = "mmpll0", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -109,7 +111,8 @@ static struct clk_alpha_pll mmpll1 = { .hw.init = &(struct clk_init_data){ .name = "mmpll1", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -138,7 +141,8 @@ static struct clk_alpha_pll mmpll3 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll3", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -166,7 +170,8 @@ static struct clk_alpha_pll mmpll4 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll4", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -194,7 +199,8 @@ static struct clk_alpha_pll mmpll5 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll5", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -222,7 +228,8 @@ static struct clk_alpha_pll mmpll6 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll6", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -250,7 +257,8 @@ static struct clk_alpha_pll mmpll7 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll7", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -278,7 +286,8 @@ static struct clk_alpha_pll mmpll10 = { .clkr.hw.init = &(struct clk_init_data){ .name = "mmpll10", .parent_data = &(const struct clk_parent_data){ - .fw_name = "xo" + .fw_name = "xo", + .name = "xo" }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -307,9 +316,9 @@ static const struct parent_map mmss_xo_hdmi_map[] = { }; static const struct clk_parent_data mmss_xo_hdmi[] = { - { .fw_name = "xo" }, - { .fw_name = "hdmipll" }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "hdmipll", .name = "hdmipll" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = { @@ -320,10 +329,10 @@ static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = { }; static const struct clk_parent_data mmss_xo_dsi0pll_dsi1pll[] = { - { .fw_name = "xo" }, - { .fw_name = "dsi0dsi" }, - { .fw_name = "dsi1dsi" }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dsi0dsi", .name = "dsi0dsi" }, + { .fw_name = "dsi1dsi", .name = "dsi1dsi" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_dsibyte_map[] = { @@ -334,10 +343,10 @@ static const struct parent_map mmss_xo_dsibyte_map[] = { }; static const struct clk_parent_data mmss_xo_dsibyte[] = { - { .fw_name = "xo" }, - { .fw_name = "dsi0byte" }, - { .fw_name = "dsi1byte" }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dsi0byte", .name = "dsi0byte" }, + { .fw_name = "dsi1byte", .name = "dsi1byte" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_dp_map[] = { @@ -348,10 +357,10 @@ static const struct parent_map mmss_xo_dp_map[] = { }; static const struct clk_parent_data mmss_xo_dp[] = { - { .fw_name = "xo" }, - { .fw_name = "dplink" }, - { .fw_name = "dpvco" }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "dplink", .name = "dplink" }, + { .fw_name = "dpvco", .name = "dpvco" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = { @@ -362,10 +371,10 @@ static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = { }; static const struct clk_parent_data mmss_xo_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, - { .fw_name = "gpll0" }, + { .fw_name = "xo", .name = "xo" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = { @@ -377,11 +386,11 @@ static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = { }; static const struct clk_parent_data mmss_xo_mmpll0_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map[] = { @@ -394,12 +403,12 @@ static const struct parent_map mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map[] = { }; static const struct clk_parent_data mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, { .hw = &mmpll1_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map[] = { @@ -412,12 +421,12 @@ static const struct parent_map mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map[] = { }; static const struct clk_parent_data mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, { .hw = &mmpll5_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map[] = { @@ -431,13 +440,13 @@ static const struct parent_map mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map[ }; static const struct clk_parent_data mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, { .hw = &mmpll3_out_even.clkr.hw }, { .hw = &mmpll6_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { @@ -451,13 +460,13 @@ static const struct parent_map mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map }; static const struct clk_parent_data mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll4_out_even.clkr.hw }, { .hw = &mmpll7_out_even.clkr.hw }, { .hw = &mmpll10_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { @@ -471,13 +480,13 @@ static const struct parent_map mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map }; static const struct clk_parent_data mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, { .hw = &mmpll7_out_even.clkr.hw }, { .hw = &mmpll10_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static const struct parent_map mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = { @@ -492,14 +501,14 @@ static const struct parent_map mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_ }; static const struct clk_parent_data mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = { - { .fw_name = "xo" }, + { .fw_name = "xo", .name = "xo" }, { .hw = &mmpll0_out_even.clkr.hw }, { .hw = &mmpll4_out_even.clkr.hw }, { .hw = &mmpll7_out_even.clkr.hw }, { .hw = &mmpll10_out_even.clkr.hw }, - { .fw_name = "gpll0" }, + { .fw_name = "gpll0", .name = "gpll0" }, { .hw = &gpll0_div.hw }, - { .fw_name = "core_bi_pll_test_se" }, + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; static struct clk_rcg2 byte0_clk_src = { @@ -509,7 +518,7 @@ static struct clk_rcg2 byte0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "byte0_clk_src", .parent_data = mmss_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), + .num_parents = 4, .ops = &clk_byte2_ops, .flags = CLK_SET_RATE_PARENT, }, @@ -522,7 +531,7 @@ static struct clk_rcg2 byte1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "byte1_clk_src", .parent_data = mmss_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), + .num_parents = 4, .ops = &clk_byte2_ops, .flags = CLK_SET_RATE_PARENT, }, @@ -543,7 +552,7 @@ static struct clk_rcg2 cci_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "cci_clk_src", .parent_data = mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -567,7 +576,7 @@ static struct clk_rcg2 cpp_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "cpp_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -590,7 +599,7 @@ static struct clk_rcg2 csi0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi0_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -603,7 +612,7 @@ static struct clk_rcg2 csi1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi1_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -616,7 +625,7 @@ static struct clk_rcg2 csi2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi2_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -629,7 +638,7 @@ static struct clk_rcg2 csi3_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi3_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -651,7 +660,7 @@ static struct clk_rcg2 csiphy_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csiphy_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -670,7 +679,7 @@ static struct clk_rcg2 csi0phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi0phytimer_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -683,7 +692,7 @@ static struct clk_rcg2 csi1phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi1phytimer_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -696,7 +705,7 @@ static struct clk_rcg2 csi2phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi2phytimer_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -714,7 +723,7 @@ static struct clk_rcg2 dp_aux_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_aux_clk_src", .parent_data = mmss_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_gpll0_gpll0_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -734,7 +743,7 @@ static struct clk_rcg2 dp_crypto_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_crypto_clk_src", .parent_data = mmss_xo_dp, - .num_parents = ARRAY_SIZE(mmss_xo_dp), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -754,7 +763,7 @@ static struct clk_rcg2 dp_link_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_link_clk_src", .parent_data = mmss_xo_dp, - .num_parents = ARRAY_SIZE(mmss_xo_dp), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -774,7 +783,7 @@ static struct clk_rcg2 dp_pixel_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_pixel_clk_src", .parent_data = mmss_xo_dp, - .num_parents = ARRAY_SIZE(mmss_xo_dp), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -792,7 +801,7 @@ static struct clk_rcg2 esc0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "esc0_clk_src", .parent_data = mmss_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -805,7 +814,7 @@ static struct clk_rcg2 esc1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "esc1_clk_src", .parent_data = mmss_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmss_xo_dsibyte), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -823,7 +832,7 @@ static struct clk_rcg2 extpclk_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "extpclk_clk_src", .parent_data = mmss_xo_hdmi, - .num_parents = ARRAY_SIZE(mmss_xo_hdmi), + .num_parents = 3, .ops = &clk_byte_ops, .flags = CLK_SET_RATE_PARENT, }, @@ -846,7 +855,7 @@ static struct clk_rcg2 fd_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "fd_core_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -864,7 +873,7 @@ static struct clk_rcg2 hdmi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "hdmi_clk_src", .parent_data = mmss_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_gpll0_gpll0_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -885,7 +894,7 @@ static struct clk_rcg2 jpeg0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "jpeg0_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -907,7 +916,7 @@ static struct clk_rcg2 maxi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "maxi_clk_src", .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -934,7 +943,7 @@ static struct clk_rcg2 mclk0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk0_clk_src", .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -947,7 +956,7 @@ static struct clk_rcg2 mclk1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk1_clk_src", .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -960,7 +969,7 @@ static struct clk_rcg2 mclk2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk2_clk_src", .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -973,7 +982,7 @@ static struct clk_rcg2 mclk3_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk3_clk_src", .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -999,7 +1008,7 @@ static struct clk_rcg2 mdp_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mdp_clk_src", .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -1017,7 +1026,7 @@ static struct clk_rcg2 vsync_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vsync_clk_src", .parent_data = mmss_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_gpll0_gpll0_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -1037,7 +1046,7 @@ static struct clk_rcg2 ahb_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ahb_clk_src", .parent_data = mmss_xo_mmpll0_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_gpll0_gpll0_div), + .num_parents = 5, .ops = &clk_rcg2_ops, }, }; @@ -1060,7 +1069,7 @@ static struct clk_rcg2 axi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "axi_clk_src", .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -1073,7 +1082,7 @@ static struct clk_rcg2 pclk0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "pclk0_clk_src", .parent_data = mmss_xo_dsi0pll_dsi1pll, - .num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll), + .num_parents = 4, .ops = &clk_pixel_ops, .flags = CLK_SET_RATE_PARENT, }, @@ -1087,7 +1096,7 @@ static struct clk_rcg2 pclk1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "pclk1_clk_src", .parent_data = mmss_xo_dsi0pll_dsi1pll, - .num_parents = ARRAY_SIZE(mmss_xo_dsi0pll_dsi1pll), + .num_parents = 4, .ops = &clk_pixel_ops, .flags = CLK_SET_RATE_PARENT, }, @@ -1109,7 +1118,7 @@ static struct clk_rcg2 rot_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rot_clk_src", .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -1131,7 +1140,7 @@ static struct clk_rcg2 video_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "video_core_clk_src", .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -1144,7 +1153,7 @@ static struct clk_rcg2 video_subcore0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "video_subcore0_clk_src", .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -1157,7 +1166,7 @@ static struct clk_rcg2 video_subcore1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "video_subcore1_clk_src", .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -1182,7 +1191,7 @@ static struct clk_rcg2 vfe0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vfe0_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; @@ -1195,7 +1204,7 @@ static struct clk_rcg2 vfe1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vfe1_clk_src", .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 8, .ops = &clk_rcg2_ops, }, }; diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index bc19a23e13..941993bc61 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -483,7 +483,7 @@ static struct clk_rcg2 ahb_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "ahb_clk_src", .parent_data = mmcc_xo_mmpll0_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_gpll0_gpll0_div), + .num_parents = 4, .ops = &clk_rcg2_ops, }, }; @@ -496,7 +496,7 @@ static struct clk_rcg2 byte0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "byte0_clk_src", .parent_data = mmcc_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte), + .num_parents = 3, .ops = &clk_byte2_ops, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, @@ -510,7 +510,7 @@ static struct clk_rcg2 byte1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "byte1_clk_src", .parent_data = mmcc_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte), + .num_parents = 3, .ops = &clk_byte2_ops, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, @@ -538,7 +538,7 @@ static struct clk_rcg2 camss_gp0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "camss_gp0_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -552,7 +552,7 @@ static struct clk_rcg2 camss_gp1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "camss_gp1_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -573,7 +573,7 @@ static struct clk_rcg2 cci_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "cci_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -597,7 +597,7 @@ static struct clk_rcg2 cpp_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "cpp_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_mmpll6, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_mmpll6), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -620,7 +620,7 @@ static struct clk_rcg2 csi0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi0_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -641,7 +641,7 @@ static struct clk_rcg2 csi0phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi0phytimer_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -655,7 +655,7 @@ static struct clk_rcg2 csi1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi1_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -669,7 +669,7 @@ static struct clk_rcg2 csi1phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi1phytimer_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -683,7 +683,7 @@ static struct clk_rcg2 csi2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi2_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -697,7 +697,7 @@ static struct clk_rcg2 csi2phytimer_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi2phytimer_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -711,7 +711,7 @@ static struct clk_rcg2 csi3_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csi3_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -733,7 +733,7 @@ static struct clk_rcg2 csiphy_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "csiphy_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll8_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -752,7 +752,7 @@ static struct clk_rcg2 dp_aux_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_aux_clk_src", .parent_data = mmcc_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_gpll0_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -773,7 +773,7 @@ static struct clk_rcg2 dp_crypto_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_crypto_clk_src", .parent_data = mmcc_xo_dplink_dpvco, - .num_parents = ARRAY_SIZE(mmcc_xo_dplink_dpvco), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -793,7 +793,7 @@ static struct clk_rcg2 dp_gtc_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_gtc_clk_src", .parent_data = mmcc_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_gpll0_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -814,7 +814,7 @@ static struct clk_rcg2 dp_link_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_link_clk_src", .parent_data = mmcc_xo_dplink_dpvco, - .num_parents = ARRAY_SIZE(mmcc_xo_dplink_dpvco), + .num_parents = 3, .ops = &clk_rcg2_ops, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -828,7 +828,7 @@ static struct clk_rcg2 dp_pixel_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "dp_pixel_clk_src", .parent_data = mmcc_xo_dplink_dpvco, - .num_parents = ARRAY_SIZE(mmcc_xo_dplink_dpvco), + .num_parents = 3, .ops = &clk_dp_ops, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -842,7 +842,7 @@ static struct clk_rcg2 esc0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "esc0_clk_src", .parent_data = mmcc_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -855,7 +855,7 @@ static struct clk_rcg2 esc1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "esc1_clk_src", .parent_data = mmcc_xo_dsibyte, - .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -878,7 +878,7 @@ static struct clk_rcg2 jpeg0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "jpeg0_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -906,7 +906,7 @@ static struct clk_rcg2 mclk0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk0_clk_src", .parent_data = mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -920,7 +920,7 @@ static struct clk_rcg2 mclk1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk1_clk_src", .parent_data = mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -934,7 +934,7 @@ static struct clk_rcg2 mclk2_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk2_clk_src", .parent_data = mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -948,7 +948,7 @@ static struct clk_rcg2 mclk3_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mclk3_clk_src", .parent_data = mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll4_mmpll7_mmpll10_sleep_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -974,7 +974,7 @@ static struct clk_rcg2 mdp_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "mdp_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll5_mmpll7_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll5_mmpll7_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -987,7 +987,7 @@ static struct clk_rcg2 pclk0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "pclk0_clk_src", .parent_data = mmcc_xo_dsi0pll_dsi1pll, - .num_parents = ARRAY_SIZE(mmcc_xo_dsi0pll_dsi1pll), + .num_parents = 3, .ops = &clk_pixel_ops, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, @@ -1001,7 +1001,7 @@ static struct clk_rcg2 pclk1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "pclk1_clk_src", .parent_data = mmcc_xo_dsi0pll_dsi1pll, - .num_parents = ARRAY_SIZE(mmcc_xo_dsi0pll_dsi1pll), + .num_parents = 3, .ops = &clk_pixel_ops, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, @@ -1025,7 +1025,7 @@ static struct clk_rcg2 rot_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "rot_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll5_mmpll7_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll5_mmpll7_gpll0_gpll0_div), + .num_parents = 6, .ops = &clk_rcg2_ops, }, }; @@ -1051,7 +1051,7 @@ static struct clk_rcg2 vfe0_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vfe0_clk_src", .parent_data = mmcc_mmpll0_mmpll4_mmpll7_mmpll10_mmpll6_gpll0, - .num_parents = ARRAY_SIZE(mmcc_mmpll0_mmpll4_mmpll7_mmpll10_mmpll6_gpll0), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -1065,7 +1065,7 @@ static struct clk_rcg2 vfe1_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vfe1_clk_src", .parent_data = mmcc_mmpll0_mmpll4_mmpll7_mmpll10_mmpll6_gpll0, - .num_parents = ARRAY_SIZE(mmcc_mmpll0_mmpll4_mmpll7_mmpll10_mmpll6_gpll0), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -1089,7 +1089,7 @@ static struct clk_rcg2 video_core_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "video_core_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll8_mmpll3_mmpll6_gpll0_mmpll7, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll8_mmpll3_mmpll6_gpll0_mmpll7), + .num_parents = 7, .ops = &clk_rcg2_ops, .flags = CLK_IS_CRITICAL, }, @@ -1104,7 +1104,7 @@ static struct clk_rcg2 vsync_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "vsync_clk_src", .parent_data = mmcc_xo_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_gpll0_div), + .num_parents = 3, .ops = &clk_rcg2_ops, }, }; @@ -2055,7 +2055,7 @@ static struct clk_rcg2 axi_clk_src = { .clkr.hw.init = &(struct clk_init_data){ .name = "axi_clk_src", .parent_data = mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div, - .num_parents = ARRAY_SIZE(mmcc_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div), + .num_parents = 7, .ops = &clk_rcg2_ops, }, }; @@ -2560,8 +2560,6 @@ static struct clk_branch video_subcore0_clk = { static struct gdsc venus_gdsc = { .gdscr = 0x1024, - .cxcs = (unsigned int[]){ 0x1028, 0x1034, 0x1048 }, - .cxc_count = 3, .pd = { .name = "venus", }, @@ -2575,7 +2573,6 @@ static struct gdsc venus_core0_gdsc = { }, .parent = &venus_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, }; static struct gdsc mdss_gdsc = { diff --git a/drivers/clk/qcom/q6sstop-qcs404.c b/drivers/clk/qcom/q6sstop-qcs404.c index 780074e058..507386bee0 100644 --- a/drivers/clk/qcom/q6sstop-qcs404.c +++ b/drivers/clk/qcom/q6sstop-qcs404.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include diff --git a/drivers/clk/qcom/turingcc-qcs404.c b/drivers/clk/qcom/turingcc-qcs404.c index 4318445922..4543bda793 100644 --- a/drivers/clk/qcom/turingcc-qcs404.c +++ b/drivers/clk/qcom/turingcc-qcs404.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c index 8617454e4a..7b435a1c2c 100644 --- a/drivers/clk/qcom/videocc-sm8250.c +++ b/drivers/clk/qcom/videocc-sm8250.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -365,31 +364,13 @@ static const struct of_device_id video_cc_sm8250_match_table[] = { }; MODULE_DEVICE_TABLE(of, video_cc_sm8250_match_table); -static void video_cc_sm8250_pm_runtime_disable(void *data) -{ - pm_runtime_disable(data); -} - static int video_cc_sm8250_probe(struct platform_device *pdev) { struct regmap *regmap; - int ret; - - pm_runtime_enable(&pdev->dev); - - ret = devm_add_action_or_reset(&pdev->dev, video_cc_sm8250_pm_runtime_disable, &pdev->dev); - if (ret) - return ret; - - ret = pm_runtime_resume_and_get(&pdev->dev); - if (ret) - return ret; regmap = qcom_cc_map(pdev, &video_cc_sm8250_desc); - if (IS_ERR(regmap)) { - pm_runtime_put(&pdev->dev); + if (IS_ERR(regmap)) return PTR_ERR(regmap); - } clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); @@ -398,11 +379,7 @@ static int video_cc_sm8250_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0)); regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0)); - ret = qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap); - - pm_runtime_put(&pdev->dev); - - return ret; + return qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap); } static struct platform_driver video_cc_sm8250_driver = { diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index be6e6ae744..6d0280751b 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -31,7 +31,6 @@ config CLK_RENESAS select CLK_R8A77990 if ARCH_R8A77990 select CLK_R8A77995 if ARCH_R8A77995 select CLK_R8A779A0 if ARCH_R8A779A0 - select CLK_R8A779F0 if ARCH_R8A779F0 select CLK_R9A06G032 if ARCH_R9A06G032 select CLK_R9A07G044 if ARCH_R9A07G044 select CLK_SH73A0 if ARCH_SH73A0 @@ -150,11 +149,8 @@ config CLK_R8A77995 config CLK_R8A779A0 bool "R-Car V3U clock support" if COMPILE_TEST - select CLK_RCAR_GEN4_CPG - -config CLK_R8A779F0 - bool "R-Car S4-8 clock support" if COMPILE_TEST - select CLK_RCAR_GEN4_CPG + select CLK_RCAR_CPG_LIB + select CLK_RENESAS_CPG_MSSR config CLK_R9A06G032 bool "RZ/N1D clock support" if COMPILE_TEST @@ -182,11 +178,6 @@ config CLK_RCAR_GEN3_CPG select CLK_RCAR_CPG_LIB select CLK_RENESAS_CPG_MSSR -config CLK_RCAR_GEN4_CPG - bool "R-Car Gen4 clock support" if COMPILE_TEST - select CLK_RCAR_CPG_LIB - select CLK_RENESAS_CPG_MSSR - config CLK_RCAR_USB2_CLOCK_SEL bool "Renesas R-Car USB2 clock selector support" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 8b34db1a32..7d018700d0 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o -obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o @@ -37,7 +36,6 @@ obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o obj-$(CONFIG_CLK_RCAR_CPG_LIB) += rcar-cpg-lib.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o -obj-$(CONFIG_CLK_RCAR_GEN4_CPG) += rcar-gen4-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 95dd56b64d..39b185d8e9 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -100,14 +100,10 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A774A1_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A774A1_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A774A1_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A774A1_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A774A1_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A774A1_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, R8A774A1_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, R8A774A1_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, R8A774A1_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, R8A774A1_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c index 56061b9b84..af602d83c8 100644 --- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -97,14 +97,10 @@ static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A774B1_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A774B1_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A774B1_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A774B1_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A774B1_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A774B1_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, R8A774B1_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, R8A774B1_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, R8A774B1_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, R8A774B1_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A774B1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774B1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774B1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774B1_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A774B1_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A774B1_CLK_CP, CLK_EXTAL, 2, 1), diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c index b5eb5dc45d..5b938eb2df 100644 --- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -108,12 +108,9 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A774C0_CLK_SD0H, CLK_SDSRC, 0x0074), - DEF_GEN3_SDH("sd1h", R8A774C0_CLK_SD1H, CLK_SDSRC, 0x0078), - DEF_GEN3_SDH("sd3h", R8A774C0_CLK_SD3H, CLK_SDSRC, 0x026c), - DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, R8A774C0_CLK_SD0H, 0x0074), - DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, R8A774C0_CLK_SD1H, 0x0078), - DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, R8A774C0_CLK_SD3H, 0x026c), + DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c), DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1), diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c index 2950f0db90..40c71466df 100644 --- a/drivers/clk/renesas/r8a774e1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c @@ -100,14 +100,10 @@ static const struct cpg_core_clk r8a774e1_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A774E1_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A774E1_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A774E1_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A774E1_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A774E1_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A774E1_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, R8A774E1_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, R8A774E1_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, R8A774E1_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, R8A774E1_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A774E1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774E1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774E1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774E1_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A774E1_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cr", R8A774E1_CLK_CR, CLK_PLL1_DIV4, 2, 1), diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 991a44315d..c32d2c6780 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -104,14 +104,10 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A7795_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A7795_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A7795_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A7795_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, R8A7795_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, R8A7795_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, R8A7795_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, R8A7795_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cr", R8A7795_CLK_CR, CLK_PLL1_DIV4, 2, 1), @@ -233,7 +229,6 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = { DEF_MOD("lvds", 727, R8A7795_CLK_S0D4), DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), - DEF_MOD("mlp", 802, R8A7795_CLK_S2D1), DEF_MOD("vin7", 804, R8A7795_CLK_S0D2), DEF_MOD("vin6", 805, R8A7795_CLK_S0D2), DEF_MOD("vin5", 806, R8A7795_CLK_S0D2), diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 7950313611..41593c126f 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -106,14 +106,10 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A7796_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A7796_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A7796_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A7796_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, R8A7796_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, R8A7796_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, R8A7796_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, R8A7796_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cr", R8A7796_CLK_CR, CLK_PLL1_DIV4, 2, 1), @@ -211,7 +207,6 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = { DEF_MOD("du0", 724, R8A7796_CLK_S2D1), DEF_MOD("lvds", 727, R8A7796_CLK_S2D1), DEF_MOD("hdmi0", 729, R8A7796_CLK_HDMI), - DEF_MOD("mlp", 802, R8A7796_CLK_S2D1), DEF_MOD("vin7", 804, R8A7796_CLK_S0D2), DEF_MOD("vin6", 805, R8A7796_CLK_S0D2), DEF_MOD("vin5", 806, R8A7796_CLK_S0D2), diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index d687c29efa..bc1be8bcbb 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -101,14 +101,10 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A77965_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A77965_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A77965_CLK_SD0H, CLK_SDSRC, 0x074), - DEF_GEN3_SDH("sd1h", R8A77965_CLK_SD1H, CLK_SDSRC, 0x078), - DEF_GEN3_SDH("sd2h", R8A77965_CLK_SD2H, CLK_SDSRC, 0x268), - DEF_GEN3_SDH("sd3h", R8A77965_CLK_SD3H, CLK_SDSRC, 0x26c), - DEF_GEN3_SD("sd0", R8A77965_CLK_SD0, R8A77965_CLK_SD0H, 0x074), - DEF_GEN3_SD("sd1", R8A77965_CLK_SD1, R8A77965_CLK_SD1H, 0x078), - DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, R8A77965_CLK_SD2H, 0x268), - DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, R8A77965_CLK_SD3H, 0x26c), + DEF_GEN3_SD("sd0", R8A77965_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A77965_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, CLK_SDSRC, 0x26c), DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cr", R8A77965_CLK_CR, CLK_PLL1_DIV4, 2, 1), @@ -209,7 +205,6 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("lvds", 727, R8A77965_CLK_S2D1), DEF_MOD("hdmi0", 729, R8A77965_CLK_HDMI), - DEF_MOD("mlp", 802, R8A77965_CLK_S2D1), DEF_MOD("vin7", 804, R8A77965_CLK_S0D2), DEF_MOD("vin6", 805, R8A77965_CLK_S0D2), DEF_MOD("vin5", 806, R8A77965_CLK_S0D2), diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index f3cd64de4d..9fe372286c 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -96,8 +96,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A77980_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A77980_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A77980_CLK_SD0H, CLK_SDSRC, 0x0074), - DEF_GEN3_SD("sd0", R8A77980_CLK_SD0, R8A77980_CLK_SD0H, 0x0074), + DEF_GEN3_SD("sd0", R8A77980_CLK_SD0, CLK_SDSRC, 0x0074), DEF_FIXED("cl", R8A77980_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A77980_CLK_CP, CLK_EXTAL, 2, 1), diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index faf60f7adc..a582f2ec32 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -100,12 +100,9 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A77990_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A77990_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SDH("sd0h", R8A77990_CLK_SD0H, CLK_SDSRC, 0x0074), - DEF_GEN3_SDH("sd1h", R8A77990_CLK_SD1H, CLK_SDSRC, 0x0078), - DEF_GEN3_SDH("sd3h", R8A77990_CLK_SD3H, CLK_SDSRC, 0x026c), - DEF_GEN3_SD("sd0", R8A77990_CLK_SD0, R8A77990_CLK_SD0H, 0x0074), - DEF_GEN3_SD("sd1", R8A77990_CLK_SD1, R8A77990_CLK_SD1H, 0x0078), - DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, R8A77990_CLK_SD3H, 0x026c), + DEF_GEN3_SD("sd0", R8A77990_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A77990_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, CLK_SDSRC, 0x026c), DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cr", R8A77990_CLK_CR, CLK_PLL1D2, 2, 1), diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index 7713cfd99c..81c0bc1e78 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -103,8 +103,7 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), - DEF_GEN3_SDH("sd0h", R8A77995_CLK_SD0H, CLK_SDSRC, 0x268), - DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, R8A77995_CLK_SD0H, 0x268), + DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268), DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244), DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014), diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 1c09d4ebe9..f16d125ca0 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -10,19 +10,42 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ +#include #include #include #include #include #include #include +#include #include +#include +#include #include #include +#include "rcar-cpg-lib.h" #include "renesas-cpg-mssr.h" -#include "rcar-gen4-cpg.h" + +enum rcar_r8a779a0_clk_types { + CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_R8A779A0_PLL1, + CLK_TYPE_R8A779A0_PLL2X_3X, /* PLL[23][01] */ + CLK_TYPE_R8A779A0_PLL5, + CLK_TYPE_R8A779A0_SD, + CLK_TYPE_R8A779A0_MDSEL, /* Select parent/divider using mode pin */ + CLK_TYPE_R8A779A0_OSC, /* OSC EXTAL predivider and fixed divider */ +}; + +struct rcar_r8a779a0_cpg_pll_config { + u8 extal_div; + u8 pll1_mult; + u8 pll1_div; + u8 pll5_mult; + u8 pll5_div; + u8 osc_prediv; +}; enum clk_ids { /* Core Clock Outputs exported to DT */ @@ -58,18 +81,29 @@ enum clk_ids { }; #define DEF_PLL(_name, _id, _offset) \ - DEF_BASE(_name, _id, CLK_TYPE_GEN4_PLL2X_3X, CLK_MAIN, \ + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \ .offset = _offset) +#define DEF_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_SD, _parent, .offset = _offset) + +#define DEF_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \ + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_MDSEL, \ + (_parent0) << 16 | (_parent1), \ + .div = (_div0) << 16 | (_div1), .offset = _md) + +#define DEF_OSC(_name, _id, _parent, _div) \ + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_OSC, _parent, .div = _div) + static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), DEF_INPUT("extalr", CLK_EXTALR), /* Internal Core Clocks */ - DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN4_MAIN, CLK_EXTAL), - DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN4_PLL1, CLK_MAIN), - DEF_BASE(".pll5", CLK_PLL5, CLK_TYPE_GEN4_PLL5, CLK_MAIN), + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_R8A779A0_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_R8A779A0_PLL1, CLK_MAIN), + DEF_BASE(".pll5", CLK_PLL5, CLK_TYPE_R8A779A0_PLL5, CLK_MAIN), DEF_PLL(".pll20", CLK_PLL20, 0x0834), DEF_PLL(".pll21", CLK_PLL21, 0x0838), DEF_PLL(".pll30", CLK_PLL30, 0x083c), @@ -86,14 +120,8 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL5_DIV4, 1, 1), DEF_RATE(".oco", CLK_OCO, 32768), - DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN4_RPCSRC, CLK_PLL5), - DEF_BASE("rpc", R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC), - DEF_BASE("rpcd2", R8A779A0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, - R8A779A0_CLK_RPC), /* Core Clock Outputs */ - DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL20, 2, 0), - DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL21, 2, 8), DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1), DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1), DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1), @@ -117,16 +145,15 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_FIXED("cp", R8A779A0_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cl16mck", R8A779A0_CLK_CL16MCK, CLK_PLL1_DIV2, 64, 1), - DEF_GEN4_SDH("sdh0", R8A779A0_CLK_SD0H, CLK_SDSRC, 0x870), - DEF_GEN4_SD("sd0", R8A779A0_CLK_SD0, R8A779A0_CLK_SD0H, 0x870), + DEF_SD("sd0", R8A779A0_CLK_SD0, CLK_SDSRC, 0x870), DEF_DIV6P1("mso", R8A779A0_CLK_MSO, CLK_PLL5_DIV4, 0x87c), DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878), DEF_DIV6P1("csi0", R8A779A0_CLK_CSI0, CLK_PLL5_DIV4, 0x880), DEF_DIV6P1("dsi", R8A779A0_CLK_DSI, CLK_PLL5_DIV4, 0x884), - DEF_GEN4_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), - DEF_GEN4_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), + DEF_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), + DEF_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), }; static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { @@ -166,7 +193,6 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("msi3", 621, R8A779A0_CLK_MSO), DEF_MOD("msi4", 622, R8A779A0_CLK_MSO), DEF_MOD("msi5", 623, R8A779A0_CLK_MSO), - DEF_MOD("rpc-if", 629, R8A779A0_CLK_RPCD2), DEF_MOD("scif0", 702, R8A779A0_CLK_S1D8), DEF_MOD("scif1", 703, R8A779A0_CLK_S1D8), DEF_MOD("scif3", 704, R8A779A0_CLK_S1D8), @@ -179,7 +205,6 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("tmu2", 715, R8A779A0_CLK_S1D4), DEF_MOD("tmu3", 716, R8A779A0_CLK_S1D4), DEF_MOD("tmu4", 717, R8A779A0_CLK_S1D4), - DEF_MOD("tpu0", 718, R8A779A0_CLK_S1D8), DEF_MOD("vin00", 730, R8A779A0_CLK_S1D1), DEF_MOD("vin01", 731, R8A779A0_CLK_S1D1), DEF_MOD("vin02", 800, R8A779A0_CLK_S1D1), @@ -230,6 +255,81 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("vspx3", 1031, R8A779A0_CLK_S1D1), }; +static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata; +static unsigned int cpg_clk_extalr __initdata; +static u32 cpg_mode __initdata; + +static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base, + struct raw_notifier_head *notifiers) +{ + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u32 value; + + parent = clks[core->parent & 0xffff]; /* some types use high bits */ + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->type) { + case CLK_TYPE_R8A779A0_MAIN: + div = cpg_pll_config->extal_div; + break; + + case CLK_TYPE_R8A779A0_PLL1: + mult = cpg_pll_config->pll1_mult; + div = cpg_pll_config->pll1_div; + break; + + case CLK_TYPE_R8A779A0_PLL2X_3X: + value = readl(base + core->offset); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_R8A779A0_PLL5: + mult = cpg_pll_config->pll5_mult; + div = cpg_pll_config->pll5_div; + break; + + case CLK_TYPE_R8A779A0_SD: + return cpg_sd_clk_register(core->name, base, core->offset, + __clk_get_name(parent), notifiers, + false); + break; + + case CLK_TYPE_R8A779A0_MDSEL: + /* + * Clock selectable between two parents and two fixed dividers + * using a mode pin + */ + if (cpg_mode & BIT(core->offset)) { + div = core->div & 0xffff; + } else { + parent = clks[core->parent >> 16]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + div = core->div >> 16; + } + mult = 1; + break; + + case CLK_TYPE_R8A779A0_OSC: + /* + * Clock combining OSC EXTAL predivider and a fixed divider + */ + div = cpg_pll_config->osc_prediv * core->div; + break; + + default: + return ERR_PTR(-EINVAL); + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + static const unsigned int r8a779a0_crit_mod_clks[] __initconst = { MOD_CLK_ID(907), /* RWDT */ }; @@ -248,19 +348,17 @@ static const unsigned int r8a779a0_crit_mod_clks[] __initconst = { */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ (((md) & BIT(13)) >> 13)) -static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = { - /* EXTAL div PLL1 mult/div PLL2 mult/div PLL3 mult/div PLL5 mult/div PLL6 mult/div OSC prediv */ - { 1, 128, 1, 0, 0, 0, 0, 192, 1, 0, 0, 16, }, - { 1, 106, 1, 0, 0, 0, 0, 160, 1, 0, 0, 19, }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - { 2, 128, 1, 0, 0, 0, 0, 192, 1, 0, 0, 32, }, -}; +static const struct rcar_r8a779a0_cpg_pll_config cpg_pll_configs[4] = { + /* EXTAL div PLL1 mult/div PLL5 mult/div OSC prediv */ + { 1, 128, 1, 192, 1, 16, }, + { 1, 106, 1, 160, 1, 19, }, + { 0, 0, 0, 0, 0, 0, }, + { 2, 128, 1, 192, 1, 32, }, +}; static int __init r8a779a0_cpg_mssr_init(struct device *dev) { - const struct rcar_gen4_cpg_pll_config *cpg_pll_config; - u32 cpg_mode; int error; error = rcar_rst_read_mode_pins(&cpg_mode); @@ -268,8 +366,10 @@ static int __init r8a779a0_cpg_mssr_init(struct device *dev) return error; cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + cpg_clk_extalr = CLK_EXTALR; + spin_lock_init(&cpg_lock); - return rcar_gen4_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); + return 0; } const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = { @@ -290,7 +390,7 @@ const struct cpg_mssr_info r8a779a0_cpg_mssr_info __initconst = { /* Callbacks */ .init = r8a779a0_cpg_mssr_init, - .cpg_clk_register = rcar_gen4_cpg_clk_register, + .cpg_clk_register = rcar_r8a779a0_cpg_clk_register, - .reg_layout = CLK_REG_LAYOUT_RCAR_GEN4, + .reg_layout = CLK_REG_LAYOUT_RCAR_V3U, }; diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 79042bf46f..1490446985 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -26,45 +26,24 @@ enum clk_ids { CLK_PLL1, CLK_PLL2, CLK_PLL2_DIV2, - CLK_PLL2_DIV2_8, - CLK_PLL2_DIV2_10, + CLK_PLL2_DIV16, + CLK_PLL2_DIV20, CLK_PLL3, - CLK_PLL3_400, - CLK_PLL3_533, CLK_PLL3_DIV2, - CLK_PLL3_DIV2_2, CLK_PLL3_DIV2_4, CLK_PLL3_DIV2_4_2, - CLK_SEL_PLL3_3, - CLK_DIV_PLL3_C, + CLK_PLL3_DIV4, CLK_PLL4, CLK_PLL5, - CLK_PLL5_FOUT3, - CLK_PLL5_250, + CLK_PLL5_DIV2, CLK_PLL6, - CLK_PLL6_250, CLK_P1_DIV2, - CLK_PLL2_800, - CLK_PLL2_SDHI_533, - CLK_PLL2_SDHI_400, - CLK_PLL2_SDHI_266, - CLK_SD0_DIV4, - CLK_SD1_DIV4, - CLK_SEL_GPU2, /* Module Clocks */ MOD_CLK_BASE, }; /* Divider tables */ -static const struct clk_div_table dtable_1_8[] = { - {0, 1}, - {1, 2}, - {2, 4}, - {3, 8}, - {0, 0}, -}; - static const struct clk_div_table dtable_1_32[] = { {0, 1}, {1, 2}, @@ -74,12 +53,6 @@ static const struct clk_div_table dtable_1_32[] = { {0, 0}, }; -/* Mux clock tables */ -static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" }; -static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" }; -static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" }; -static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" }; - static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -90,63 +63,27 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)), DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2), DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2), - DEF_FIXED(".pll3_400", CLK_PLL3_400, CLK_PLL3, 1, 4), - DEF_FIXED(".pll3_533", CLK_PLL3_533, CLK_PLL3, 1, 3), - - DEF_FIXED(".pll5", CLK_PLL5, CLK_EXTAL, 125, 1), - DEF_FIXED(".pll5_fout3", CLK_PLL5_FOUT3, CLK_PLL5, 1, 6), - - DEF_FIXED(".pll6", CLK_PLL6, CLK_EXTAL, 125, 6), DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), - DEF_FIXED(".clk_800", CLK_PLL2_800, CLK_PLL2, 1, 2), - DEF_FIXED(".clk_533", CLK_PLL2_SDHI_533, CLK_PLL2, 1, 3), - DEF_FIXED(".clk_400", CLK_PLL2_SDHI_400, CLK_PLL2_800, 1, 2), - DEF_FIXED(".clk_266", CLK_PLL2_SDHI_266, CLK_PLL2_SDHI_533, 1, 2), - - DEF_FIXED(".pll2_div2_8", CLK_PLL2_DIV2_8, CLK_PLL2_DIV2, 1, 8), - DEF_FIXED(".pll2_div2_10", CLK_PLL2_DIV2_10, CLK_PLL2_DIV2, 1, 10), + DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16), + DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20), DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2), - DEF_FIXED(".pll3_div2_2", CLK_PLL3_DIV2_2, CLK_PLL3_DIV2, 1, 2), DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4), DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2), - DEF_MUX(".sel_pll3_3", CLK_SEL_PLL3_3, SEL_PLL3_3, - sel_pll3_3, ARRAY_SIZE(sel_pll3_3), 0, CLK_MUX_READ_ONLY), - DEF_DIV("divpl3c", CLK_DIV_PLL3_C, CLK_SEL_PLL3_3, - DIVPL3C, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), - - DEF_FIXED(".pll5_250", CLK_PLL5_250, CLK_PLL5_FOUT3, 1, 2), - DEF_FIXED(".pll6_250", CLK_PLL6_250, CLK_PLL6, 1, 2), - DEF_MUX(".sel_gpu2", CLK_SEL_GPU2, SEL_GPU2, - sel_gpu2, ARRAY_SIZE(sel_gpu2), 0, CLK_MUX_READ_ONLY), + DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4), /* Core output clk */ - DEF_DIV("I", R9A07G044_CLK_I, CLK_PLL1, DIVPL1A, dtable_1_8, - CLK_DIVIDER_HIWORD_MASK), - DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV2_8, DIVPL2A, + DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1), + DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2), - DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV2_10, 1, 1), + DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2), DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), - DEF_FIXED("M0", R9A07G044_CLK_M0, CLK_PLL3_DIV2_4, 1, 1), - DEF_FIXED("ZT", R9A07G044_CLK_ZT, CLK_PLL3_DIV2_4_2, 1, 1), - DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, - sel_pll6_2, ARRAY_SIZE(sel_pll6_2), 0, CLK_MUX_HIWORD_MASK), - DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2), - DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), - DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, - sel_shdi, ARRAY_SIZE(sel_shdi)), - DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, - sel_shdi, ARRAY_SIZE(sel_shdi)), - DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4), - DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4), - DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8, - CLK_DIVIDER_HIWORD_MASK), }; static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { @@ -160,50 +97,6 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), - DEF_MOD("ostm0_pclk", R9A07G044_OSTM0_PCLK, R9A07G044_CLK_P0, - 0x534, 0), - DEF_MOD("ostm1_clk", R9A07G044_OSTM1_PCLK, R9A07G044_CLK_P0, - 0x534, 1), - DEF_MOD("ostm2_pclk", R9A07G044_OSTM2_PCLK, R9A07G044_CLK_P0, - 0x534, 2), - DEF_MOD("wdt0_pclk", R9A07G044_WDT0_PCLK, R9A07G044_CLK_P0, - 0x548, 0), - DEF_MOD("wdt0_clk", R9A07G044_WDT0_CLK, R9A07G044_OSCCLK, - 0x548, 1), - DEF_MOD("wdt1_pclk", R9A07G044_WDT1_PCLK, R9A07G044_CLK_P0, - 0x548, 2), - DEF_MOD("wdt1_clk", R9A07G044_WDT1_CLK, R9A07G044_OSCCLK, - 0x548, 3), - DEF_MOD("wdt2_pclk", R9A07G044_WDT2_PCLK, R9A07G044_CLK_P0, - 0x548, 4), - DEF_MOD("wdt2_clk", R9A07G044_WDT2_CLK, R9A07G044_OSCCLK, - 0x548, 5), - DEF_MOD("spi_clk2", R9A07G044_SPI_CLK2, R9A07G044_CLK_SPI1, - 0x550, 0), - DEF_MOD("spi_clk", R9A07G044_SPI_CLK, R9A07G044_CLK_SPI0, - 0x550, 1), - DEF_MOD("sdhi0_imclk", R9A07G044_SDHI0_IMCLK, CLK_SD0_DIV4, - 0x554, 0), - DEF_MOD("sdhi0_imclk2", R9A07G044_SDHI0_IMCLK2, CLK_SD0_DIV4, - 0x554, 1), - DEF_MOD("sdhi0_clk_hs", R9A07G044_SDHI0_CLK_HS, R9A07G044_CLK_SD0, - 0x554, 2), - DEF_MOD("sdhi0_aclk", R9A07G044_SDHI0_ACLK, R9A07G044_CLK_P1, - 0x554, 3), - DEF_MOD("sdhi1_imclk", R9A07G044_SDHI1_IMCLK, CLK_SD1_DIV4, - 0x554, 4), - DEF_MOD("sdhi1_imclk2", R9A07G044_SDHI1_IMCLK2, CLK_SD1_DIV4, - 0x554, 5), - DEF_MOD("sdhi1_clk_hs", R9A07G044_SDHI1_CLK_HS, R9A07G044_CLK_SD1, - 0x554, 6), - DEF_MOD("sdhi1_aclk", R9A07G044_SDHI1_ACLK, R9A07G044_CLK_P1, - 0x554, 7), - DEF_MOD("gpu_clk", R9A07G044_GPU_CLK, R9A07G044_CLK_G, - 0x558, 0), - DEF_MOD("gpu_axi_clk", R9A07G044_GPU_AXI_CLK, R9A07G044_CLK_P1, - 0x558, 1), - DEF_MOD("gpu_ace_clk", R9A07G044_GPU_ACE_CLK, R9A07G044_CLK_P1, - 0x558, 2), DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, 0x570, 0), DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, @@ -228,14 +121,6 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x578, 2), DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1, 0x578, 3), - DEF_COUPLED("eth0_axi", R9A07G044_ETH0_CLK_AXI, R9A07G044_CLK_M0, - 0x57c, 0), - DEF_COUPLED("eth0_chi", R9A07G044_ETH0_CLK_CHI, R9A07G044_CLK_ZT, - 0x57c, 0), - DEF_COUPLED("eth1_axi", R9A07G044_ETH1_CLK_AXI, R9A07G044_CLK_M0, - 0x57c, 1), - DEF_COUPLED("eth1_chi", R9A07G044_ETH1_CLK_CHI, R9A07G044_CLK_ZT, - 0x57c, 1), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, 0x580, 0), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, @@ -256,14 +141,6 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x584, 4), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, 0x588, 0), - DEF_MOD("sci1", R9A07G044_SCI1_CLKP, R9A07G044_CLK_P0, - 0x588, 1), - DEF_MOD("rspi0", R9A07G044_RSPI0_CLKB, R9A07G044_CLK_P0, - 0x590, 0), - DEF_MOD("rspi1", R9A07G044_RSPI1_CLKB, R9A07G044_CLK_P0, - 0x590, 1), - DEF_MOD("rspi2", R9A07G044_RSPI2_CLKB, R9A07G044_CLK_P0, - 0x590, 2), DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0, 0x594, 0), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, @@ -272,8 +149,6 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x5a8, 0), DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0, 0x5a8, 1), - DEF_MOD("tsu_pclk", R9A07G044_TSU_PCLK, R9A07G044_CLK_TSU, - 0x5ac, 0), }; static struct rzg2l_reset r9a07g044_resets[] = { @@ -282,18 +157,6 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), - DEF_RST(R9A07G044_OSTM0_PRESETZ, 0x834, 0), - DEF_RST(R9A07G044_OSTM1_PRESETZ, 0x834, 1), - DEF_RST(R9A07G044_OSTM2_PRESETZ, 0x834, 2), - DEF_RST(R9A07G044_WDT0_PRESETN, 0x848, 0), - DEF_RST(R9A07G044_WDT1_PRESETN, 0x848, 1), - DEF_RST(R9A07G044_WDT2_PRESETN, 0x848, 2), - DEF_RST(R9A07G044_SPI_RST, 0x850, 0), - DEF_RST(R9A07G044_SDHI0_IXRST, 0x854, 0), - DEF_RST(R9A07G044_SDHI1_IXRST, 0x854, 1), - DEF_RST(R9A07G044_GPU_RESETN, 0x858, 0), - DEF_RST(R9A07G044_GPU_AXI_RESETN, 0x858, 1), - DEF_RST(R9A07G044_GPU_ACE_RESETN, 0x858, 2), DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0), DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1), DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2), @@ -302,8 +165,6 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1), DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2), DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3), - DEF_RST(R9A07G044_ETH0_RST_HW_N, 0x87c, 0), - DEF_RST(R9A07G044_ETH1_RST_HW_N, 0x87c, 1), DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), @@ -314,10 +175,6 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A07G044_SCI0_RST, 0x888, 0), - DEF_RST(R9A07G044_SCI1_RST, 0x888, 1), - DEF_RST(R9A07G044_RSPI0_RST, 0x890, 0), - DEF_RST(R9A07G044_RSPI1_RST, 0x890, 1), - DEF_RST(R9A07G044_RSPI2_RST, 0x890, 2), DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0), DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1), DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), @@ -325,7 +182,6 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0), DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1), - DEF_RST(R9A07G044_TSU_PRESETN, 0x8ac, 0), }; static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index e2e0447de1..5678768ee1 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -65,132 +65,206 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, /* * SDn Clock */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) -#define SDnSRCFC_SHIFT 2 -#define STPnHCK BIT(9 - SDnSRCFC_SHIFT) +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) -static const struct clk_div_table cpg_sdh_div_table[] = { - { 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 }, - { STPnHCK | 4, 16 }, { 0, 0 }, -}; - -struct clk * __init cpg_sdh_clk_register(const char *name, - void __iomem *sdnckcr, const char *parent_name, - struct raw_notifier_head *notifiers) -{ - struct cpg_simple_notifier *csn; - struct clk *clk; - - csn = kzalloc(sizeof(*csn), GFP_KERNEL); - if (!csn) - return ERR_PTR(-ENOMEM); - - csn->reg = sdnckcr; - - clk = clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr, - SDnSRCFC_SHIFT, 8, 0, cpg_sdh_div_table, - &cpg_lock); - if (IS_ERR(clk)) { - kfree(csn); - return clk; - } - - cpg_simple_notifier_register(notifiers, csn); - return clk; +#define CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ } -static const struct clk_div_table cpg_sd_div_table[] = { - { 0, 2 }, { 1, 4 }, { 0, 0 }, +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + const struct sd_div_table *div_table; + struct cpg_simple_notifier csn; + unsigned int div_num; + unsigned int cur_div_idx; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck (div) (div) = sd_srcfc x sd_fc + *--------------------------------------------------------- + * 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP) + * 0 1 (2) 1 (4) 8 : SDR50 + * 1 2 (4) 1 (4) 16 : HS / SDR25 + * 1 3 (8) 1 (4) 32 : NS / SDR12 + * 1 4 (16) 1 (4) 64 + * 0 0 (1) 0 (2) 2 + * 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP) + * 1 2 (4) 0 (2) 8 + * 1 3 (8) 0 (2) 16 + * 1 4 (16) 0 (2) 32 + * + * NOTE: There is a quirk option to ignore the first row of the dividers + * table when searching for suitable settings. This is because HS400 on + * early ES versions of H3 and M3-W requires a specific setting to work. + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK, + clock->div_table[clock->cur_div_idx].val & + CPG_SD_STP_MASK); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(readl(clock->csn.reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return DIV_ROUND_CLOSEST(parent_rate, + clock->div_table[clock->cur_div_idx].div); +} + +static int cpg_sd_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + unsigned long best_rate = ULONG_MAX, diff_min = ULONG_MAX; + struct sd_clock *clock = to_sd_clock(hw); + unsigned long calc_rate, diff; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) { + calc_rate = DIV_ROUND_CLOSEST(req->best_parent_rate, + clock->div_table[i].div); + if (calc_rate < req->min_rate || calc_rate > req->max_rate) + continue; + + diff = calc_rate > req->rate ? calc_rate - req->rate + : req->rate - calc_rate; + if (diff < diff_min) { + best_rate = calc_rate; + diff_min = diff; + } + } + + if (best_rate == ULONG_MAX) + return -EINVAL; + + req->rate = best_rate; + return 0; +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (rate == DIV_ROUND_CLOSEST(parent_rate, + clock->div_table[i].div)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + clock->cur_div_idx = i; + + cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK, + clock->div_table[i].val & + (CPG_SD_STP_MASK | CPG_SD_FC_MASK)); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .determine_rate = cpg_sd_clock_determine_rate, + .set_rate = cpg_sd_clock_set_rate, }; struct clk * __init cpg_sd_clk_register(const char *name, - void __iomem *sdnckcr, const char *parent_name) + void __iomem *base, unsigned int offset, const char *parent_name, + struct raw_notifier_head *notifiers, bool skip_first) { - return clk_register_divider_table(NULL, name, parent_name, 0, sdnckcr, - 0, 2, 0, cpg_sd_div_table, &cpg_lock); -} - -struct rpc_clock { - struct clk_divider div; - struct clk_gate gate; - /* - * One notifier covers both RPC and RPCD2 clocks as they are both - * controlled by the same RPCCKCR register... - */ - struct cpg_simple_notifier csn; -}; - -static const struct clk_div_table cpg_rpc_div_table[] = { - { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 }, -}; - -struct clk * __init cpg_rpc_clk_register(const char *name, - void __iomem *rpcckcr, const char *parent_name, - struct raw_notifier_head *notifiers) -{ - struct rpc_clock *rpc; + struct clk_init_data init = {}; + struct sd_clock *clock; struct clk *clk; + u32 val; - rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); - if (!rpc) + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) return ERR_PTR(-ENOMEM); - rpc->div.reg = rpcckcr; - rpc->div.width = 3; - rpc->div.table = cpg_rpc_div_table; - rpc->div.lock = &cpg_lock; + init.name = name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; - rpc->gate.reg = rpcckcr; - rpc->gate.bit_idx = 8; - rpc->gate.flags = CLK_GATE_SET_TO_DISABLE; - rpc->gate.lock = &cpg_lock; + clock->csn.reg = base + offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); - rpc->csn.reg = rpcckcr; - - clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, - &rpc->div.hw, &clk_divider_ops, - &rpc->gate.hw, &clk_gate_ops, - CLK_SET_RATE_PARENT); - if (IS_ERR(clk)) { - kfree(rpc); - return clk; + if (skip_first) { + clock->div_table++; + clock->div_num--; } - cpg_simple_notifier_register(notifiers, &rpc->csn); - return clk; -} + val = readl(clock->csn.reg) & ~CPG_SD_FC_MASK; + val |= CPG_SD_STP_MASK | (clock->div_table[0].val & CPG_SD_FC_MASK); + writel(val, clock->csn.reg); -struct rpcd2_clock { - struct clk_fixed_factor fixed; - struct clk_gate gate; -}; - -struct clk * __init cpg_rpcd2_clk_register(const char *name, - void __iomem *rpcckcr, - const char *parent_name) -{ - struct rpcd2_clock *rpcd2; - struct clk *clk; - - rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL); - if (!rpcd2) - return ERR_PTR(-ENOMEM); - - rpcd2->fixed.mult = 1; - rpcd2->fixed.div = 2; - - rpcd2->gate.reg = rpcckcr; - rpcd2->gate.bit_idx = 9; - rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE; - rpcd2->gate.lock = &cpg_lock; - - clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, - &rpcd2->fixed.hw, &clk_fixed_factor_ops, - &rpcd2->gate.hw, &clk_gate_ops, - CLK_SET_RATE_PARENT); + clk = clk_register(NULL, &clock->hw); if (IS_ERR(clk)) - kfree(rpcd2); + goto free_clock; + cpg_simple_notifier_register(notifiers, &clock->csn); + return clk; + +free_clock: + kfree(clock); return clk; } + diff --git a/drivers/clk/renesas/rcar-cpg-lib.h b/drivers/clk/renesas/rcar-cpg-lib.h index 94627df1c9..d00c91b116 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.h +++ b/drivers/clk/renesas/rcar-cpg-lib.h @@ -26,18 +26,8 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers, void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set); -struct clk * __init cpg_sdh_clk_register(const char *name, - void __iomem *sdnckcr, const char *parent_name, - struct raw_notifier_head *notifiers); - struct clk * __init cpg_sd_clk_register(const char *name, - void __iomem *sdnckcr, const char *parent_name); + void __iomem *base, unsigned int offset, const char *parent_name, + struct raw_notifier_head *notifiers, bool skip_first); -struct clk * __init cpg_rpc_clk_register(const char *name, - void __iomem *rpcckcr, const char *parent_name, - struct raw_notifier_head *notifiers); - -struct clk * __init cpg_rpcd2_clk_register(const char *name, - void __iomem *rpcckcr, - const char *parent_name); #endif diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index e668f23c75..558191c99b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -301,10 +301,95 @@ static struct clk * __init cpg_z_clk_register(const char *name, return clk; } +struct rpc_clock { + struct clk_divider div; + struct clk_gate gate; + /* + * One notifier covers both RPC and RPCD2 clocks as they are both + * controlled by the same RPCCKCR register... + */ + struct cpg_simple_notifier csn; +}; + static const struct clk_div_table cpg_rpcsrc_div_table[] = { { 2, 5 }, { 3, 6 }, { 0, 0 }, }; +static const struct clk_div_table cpg_rpc_div_table[] = { + { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 }, +}; + +static struct clk * __init cpg_rpc_clk_register(const char *name, + void __iomem *base, const char *parent_name, + struct raw_notifier_head *notifiers) +{ + struct rpc_clock *rpc; + struct clk *clk; + + rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); + if (!rpc) + return ERR_PTR(-ENOMEM); + + rpc->div.reg = base + CPG_RPCCKCR; + rpc->div.width = 3; + rpc->div.table = cpg_rpc_div_table; + rpc->div.lock = &cpg_lock; + + rpc->gate.reg = base + CPG_RPCCKCR; + rpc->gate.bit_idx = 8; + rpc->gate.flags = CLK_GATE_SET_TO_DISABLE; + rpc->gate.lock = &cpg_lock; + + rpc->csn.reg = base + CPG_RPCCKCR; + + clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, + &rpc->div.hw, &clk_divider_ops, + &rpc->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); + if (IS_ERR(clk)) { + kfree(rpc); + return clk; + } + + cpg_simple_notifier_register(notifiers, &rpc->csn); + return clk; +} + +struct rpcd2_clock { + struct clk_fixed_factor fixed; + struct clk_gate gate; +}; + +static struct clk * __init cpg_rpcd2_clk_register(const char *name, + void __iomem *base, + const char *parent_name) +{ + struct rpcd2_clock *rpcd2; + struct clk *clk; + + rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL); + if (!rpcd2) + return ERR_PTR(-ENOMEM); + + rpcd2->fixed.mult = 1; + rpcd2->fixed.div = 2; + + rpcd2->gate.reg = base + CPG_RPCCKCR; + rpcd2->gate.bit_idx = 9; + rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE; + rpcd2->gate.lock = &cpg_lock; + + clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, + &rpcd2->fixed.hw, &clk_fixed_factor_ops, + &rpcd2->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); + if (IS_ERR(clk)) + kfree(rpcd2); + + return clk; +} + + static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata; static unsigned int cpg_clk_extalr __initdata; static u32 cpg_mode __initdata; @@ -312,20 +397,29 @@ static u32 cpg_quirks __initdata; #define PLL_ERRATA BIT(0) /* Missing PLL0/2/4 post-divider */ #define RCKCR_CKSEL BIT(1) /* Manual RCLK parent selection */ +#define SD_SKIP_FIRST BIT(2) /* Skip first clock in SD table */ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { { .soc_id = "r8a7795", .revision = "ES1.0", - .data = (void *)(PLL_ERRATA | RCKCR_CKSEL), + .data = (void *)(PLL_ERRATA | RCKCR_CKSEL | SD_SKIP_FIRST), }, { .soc_id = "r8a7795", .revision = "ES1.*", - .data = (void *)(RCKCR_CKSEL), + .data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST), + }, + { + .soc_id = "r8a7795", .revision = "ES2.0", + .data = (void *)SD_SKIP_FIRST, }, { .soc_id = "r8a7796", .revision = "ES1.0", - .data = (void *)(RCKCR_CKSEL), + .data = (void *)(RCKCR_CKSEL | SD_SKIP_FIRST), + }, + { + .soc_id = "r8a7796", .revision = "ES1.1", + .data = (void *)SD_SKIP_FIRST, }, { /* sentinel */ } }; @@ -392,13 +486,10 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, mult *= 2; break; - case CLK_TYPE_GEN3_SDH: - return cpg_sdh_clk_register(core->name, base + core->offset, - __clk_get_name(parent), notifiers); - case CLK_TYPE_GEN3_SD: - return cpg_sd_clk_register(core->name, base + core->offset, - __clk_get_name(parent)); + return cpg_sd_clk_register(core->name, base, core->offset, + __clk_get_name(parent), notifiers, + cpg_quirks & SD_SKIP_FIRST); case CLK_TYPE_GEN3_R: if (cpg_quirks & RCKCR_CKSEL) { @@ -509,11 +600,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, break; case CLK_TYPE_GEN3_RPC: - return cpg_rpc_clk_register(core->name, base + CPG_RPCCKCR, + return cpg_rpc_clk_register(core->name, base, __clk_get_name(parent), notifiers); case CLK_TYPE_GEN3_RPCD2: - return cpg_rpcd2_clk_register(core->name, base + CPG_RPCCKCR, + return cpg_rpcd2_clk_register(core->name, base, __clk_get_name(parent)); default: diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 2bc0afadf6..3d949c4a32 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -17,7 +17,6 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_PLL2, CLK_TYPE_GEN3_PLL3, CLK_TYPE_GEN3_PLL4, - CLK_TYPE_GEN3_SDH, CLK_TYPE_GEN3_SD, CLK_TYPE_GEN3_R, CLK_TYPE_GEN3_MDSEL, /* Select parent/divider using mode pin */ @@ -33,9 +32,6 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_SOC_BASE, }; -#define DEF_GEN3_SDH(_name, _id, _parent, _offset) \ - DEF_BASE(_name, _id, CLK_TYPE_GEN3_SDH, _parent, .offset = _offset) - #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 5d2c3edbaa..21f762aa21 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -57,11 +57,9 @@ static const u16 mstpsr[] = { 0x9A0, 0x9A4, 0x9A8, 0x9AC, }; -static const u16 mstpsr_for_gen4[] = { +static const u16 mstpsr_for_v3u[] = { 0x2E00, 0x2E04, 0x2E08, 0x2E0C, 0x2E10, 0x2E14, 0x2E18, 0x2E1C, - 0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, 0x2E3C, - 0x2E40, 0x2E44, 0x2E48, 0x2E4C, 0x2E50, 0x2E54, 0x2E58, 0x2E5C, - 0x2E60, 0x2E64, 0x2E68, 0x2E6C, + 0x2E20, 0x2E24, 0x2E28, 0x2E2C, 0x2E30, 0x2E34, 0x2E38, }; /* @@ -73,11 +71,9 @@ static const u16 smstpcr[] = { 0x990, 0x994, 0x998, 0x99C, }; -static const u16 mstpcr_for_gen4[] = { +static const u16 mstpcr_for_v3u[] = { 0x2D00, 0x2D04, 0x2D08, 0x2D0C, 0x2D10, 0x2D14, 0x2D18, 0x2D1C, - 0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, 0x2D3C, - 0x2D40, 0x2D44, 0x2D48, 0x2D4C, 0x2D50, 0x2D54, 0x2D58, 0x2D5C, - 0x2D60, 0x2D64, 0x2D68, 0x2D6C, + 0x2D20, 0x2D24, 0x2D28, 0x2D2C, 0x2D30, 0x2D34, 0x2D38, }; /* @@ -99,11 +95,9 @@ static const u16 srcr[] = { 0x920, 0x924, 0x928, 0x92C, }; -static const u16 srcr_for_gen4[] = { +static const u16 srcr_for_v3u[] = { 0x2C00, 0x2C04, 0x2C08, 0x2C0C, 0x2C10, 0x2C14, 0x2C18, 0x2C1C, - 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, 0x2C3C, - 0x2C40, 0x2C44, 0x2C48, 0x2C4C, 0x2C50, 0x2C54, 0x2C58, 0x2C5C, - 0x2C60, 0x2C64, 0x2C68, 0x2C6C, + 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, }; /* @@ -115,11 +109,9 @@ static const u16 srstclr[] = { 0x960, 0x964, 0x968, 0x96C, }; -static const u16 srstclr_for_gen4[] = { +static const u16 srstclr_for_v3u[] = { 0x2C80, 0x2C84, 0x2C88, 0x2C8C, 0x2C90, 0x2C94, 0x2C98, 0x2C9C, - 0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, 0x2CBC, - 0x2CC0, 0x2CC4, 0x2CC8, 0x2CCC, 0x2CD0, 0x2CD4, 0x2CD8, 0x2CDC, - 0x2CE0, 0x2CE4, 0x2CE8, 0x2CEC, + 0x2CA0, 0x2CA4, 0x2CA8, 0x2CAC, 0x2CB0, 0x2CB4, 0x2CB8, }; /** @@ -166,7 +158,7 @@ struct cpg_mssr_priv { struct { u32 mask; u32 val; - } smstpcr_saved[ARRAY_SIZE(mstpsr_for_gen4)]; + } smstpcr_saved[ARRAY_SIZE(mstpsr_for_v3u)]; struct clk *clks[]; }; @@ -560,11 +552,6 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev) pm_clk_destroy(dev); } -static void cpg_mssr_genpd_remove(void *data) -{ - pm_genpd_remove(data); -} - static int __init cpg_mssr_add_clk_domain(struct device *dev, const unsigned int *core_pm_clks, unsigned int num_core_pm_clks) @@ -573,7 +560,6 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, struct generic_pm_domain *genpd; struct cpg_mssr_clk_domain *pd; size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]); - int ret; pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL); if (!pd) @@ -588,17 +574,11 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, GENPD_FLAG_ACTIVE_WAKEUP; genpd->attach_dev = cpg_mssr_attach_dev; genpd->detach_dev = cpg_mssr_detach_dev; - ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, cpg_mssr_genpd_remove, genpd); - if (ret) - return ret; - + pm_genpd_init(genpd, &pm_domain_always_on_gov, false); cpg_mssr_clk_domain = pd; - return of_genpd_add_provider_simple(np, genpd); + of_genpd_add_provider_simple(np, genpd); + return 0; } #ifdef CONFIG_RESET_CONTROLLER @@ -847,12 +827,6 @@ static const struct of_device_id cpg_mssr_match[] = { .compatible = "renesas,r8a779a0-cpg-mssr", .data = &r8a779a0_cpg_mssr_info, }, -#endif -#ifdef CONFIG_CLK_R8A779F0 - { - .compatible = "renesas,r8a779f0-cpg-mssr", - .data = &r8a779f0_cpg_mssr_info, - }, #endif { /* sentinel */ } }; @@ -996,11 +970,11 @@ static int __init cpg_mssr_common_init(struct device *dev, priv->reset_clear_regs = srstclr; } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { priv->control_regs = stbcr; - } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) { - priv->status_regs = mstpsr_for_gen4; - priv->control_regs = mstpcr_for_gen4; - priv->reset_regs = srcr_for_gen4; - priv->reset_clear_regs = srstclr_for_gen4; + } else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) { + priv->status_regs = mstpsr_for_v3u; + priv->control_regs = mstpcr_for_v3u; + priv->reset_regs = srcr_for_v3u; + priv->reset_clear_regs = srstclr_for_v3u; } else { error = -EINVAL; goto out_err; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 16810dd4e6..6b2a0ade48 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -88,7 +88,7 @@ struct device_node; enum clk_reg_layout { CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0, CLK_REG_LAYOUT_RZ_A, - CLK_REG_LAYOUT_RCAR_GEN4, + CLK_REG_LAYOUT_RCAR_V3U, }; /** @@ -178,7 +178,6 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info; -extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info; void __init cpg_mssr_early_init(struct device_node *np, const struct cpg_mssr_info *info); diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index edd0abe34a..1c92e73cd2 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -56,14 +55,6 @@ #define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) #define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) -struct sd_hw_data { - struct clk_hw hw; - u32 conf; - struct rzg2l_cpg_priv *priv; -}; - -#define to_sd_hw_data(_hw) container_of(_hw, struct sd_hw_data, hw) - /** * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data * @@ -74,7 +65,6 @@ struct sd_hw_data { * @clks: Array containing all Core and Module Clocks * @num_core_clks: Number of Core Clocks in clks[] * @num_mod_clks: Number of Module Clocks in clks[] - * @num_resets: Number of Module Resets in info->resets[] * @last_dt_core_clk: ID of the last Core Clock exported to DT * @notifiers: Notifier chain to save/restore clock state for system resume * @info: Pointer to platform data @@ -140,132 +130,6 @@ rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, return clk_hw->clk; } -static struct clk * __init -rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - const struct clk_hw *clk_hw; - - clk_hw = devm_clk_hw_register_mux(priv->dev, core->name, - core->parent_names, core->num_parents, - core->flag, - base + GET_REG_OFFSET(core->conf), - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->mux_flags, &priv->rmw_lock); - if (IS_ERR(clk_hw)) - return ERR_CAST(clk_hw); - - return clk_hw->clk; -} - -static int rzg2l_cpg_sd_clk_mux_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - return clk_mux_determine_rate_flags(hw, req, 0); -} - -static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index) -{ - struct sd_hw_data *hwdata = to_sd_hw_data(hw); - struct rzg2l_cpg_priv *priv = hwdata->priv; - u32 off = GET_REG_OFFSET(hwdata->conf); - u32 shift = GET_SHIFT(hwdata->conf); - const u32 clk_src_266 = 2; - u32 bitmask; - - /* - * As per the HW manual, we should not directly switch from 533 MHz to - * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz) - * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first, - * and then switch to the target setting (2’b01 (533 MHz) or 2’b10 - * (400 MHz)). - * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock - * switching register is prohibited. - * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and - * the index to value mapping is done by adding 1 to the index. - */ - bitmask = (GENMASK(GET_WIDTH(hwdata->conf) - 1, 0) << shift) << 16; - if (index != clk_src_266) { - u32 msk, val; - int ret; - - writel(bitmask | ((clk_src_266 + 1) << shift), priv->base + off); - - msk = off ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS; - - ret = readl_poll_timeout(priv->base + CPG_CLKSTATUS, val, - !(val & msk), 100, - CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US); - if (ret) { - dev_err(priv->dev, "failed to switch clk source\n"); - return ret; - } - } - - writel(bitmask | ((index + 1) << shift), priv->base + off); - - return 0; -} - -static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) -{ - struct sd_hw_data *hwdata = to_sd_hw_data(hw); - struct rzg2l_cpg_priv *priv = hwdata->priv; - u32 val = readl(priv->base + GET_REG_OFFSET(hwdata->conf)); - - val >>= GET_SHIFT(hwdata->conf); - val &= GENMASK(GET_WIDTH(hwdata->conf) - 1, 0); - if (val) { - val--; - } else { - /* Prohibited clk source, change it to 533 MHz(reset value) */ - rzg2l_cpg_sd_clk_mux_set_parent(hw, 0); - } - - return val; -} - -static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = { - .determine_rate = rzg2l_cpg_sd_clk_mux_determine_rate, - .set_parent = rzg2l_cpg_sd_clk_mux_set_parent, - .get_parent = rzg2l_cpg_sd_clk_mux_get_parent, -}; - -static struct clk * __init -rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - struct sd_hw_data *clk_hw_data; - struct clk_init_data init; - struct clk_hw *clk_hw; - int ret; - - clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL); - if (!clk_hw_data) - return ERR_PTR(-ENOMEM); - - clk_hw_data->priv = priv; - clk_hw_data->conf = core->conf; - - init.name = GET_SHIFT(core->conf) ? "sd1" : "sd0"; - init.ops = &rzg2l_cpg_sd_clk_mux_ops; - init.flags = 0; - init.num_parents = core->num_parents; - init.parent_names = core->parent_names; - - clk_hw = &clk_hw_data->hw; - clk_hw->init = &init; - - ret = devm_clk_hw_register(priv->dev, clk_hw); - if (ret) - return ERR_PTR(ret); - - return clk_hw->clk; -} - struct pll_clk { struct clk_hw hw; unsigned int conf; @@ -424,12 +288,6 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, clk = rzg2l_cpg_div_clk_register(core, priv->clks, priv->base, priv); break; - case CLK_TYPE_MUX: - clk = rzg2l_cpg_mux_clk_register(core, priv->base, priv); - break; - case CLK_TYPE_SD_MUX: - clk = rzg2l_cpg_sd_mux_clk_register(core, priv->base, priv); - break; default: goto fail; } @@ -452,17 +310,13 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, * @hw: handle between common and hardware-specific interfaces * @off: register offset * @bit: ON/MON bit - * @enabled: soft state of the clock, if it is coupled with another clock * @priv: CPG/MSTP private data - * @sibling: pointer to the other coupled clock */ struct mstp_clock { struct clk_hw hw; u16 off; u8 bit; - bool enabled; struct rzg2l_cpg_priv *priv; - struct mstp_clock *sibling; }; #define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) @@ -515,41 +369,11 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) static int rzg2l_mod_clock_enable(struct clk_hw *hw) { - struct mstp_clock *clock = to_mod_clock(hw); - - if (clock->sibling) { - struct rzg2l_cpg_priv *priv = clock->priv; - unsigned long flags; - bool enabled; - - spin_lock_irqsave(&priv->rmw_lock, flags); - enabled = clock->sibling->enabled; - clock->enabled = true; - spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (enabled) - return 0; - } - return rzg2l_mod_clock_endisable(hw, true); } static void rzg2l_mod_clock_disable(struct clk_hw *hw) { - struct mstp_clock *clock = to_mod_clock(hw); - - if (clock->sibling) { - struct rzg2l_cpg_priv *priv = clock->priv; - unsigned long flags; - bool enabled; - - spin_lock_irqsave(&priv->rmw_lock, flags); - enabled = clock->sibling->enabled; - clock->enabled = false; - spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (enabled) - return; - } - rzg2l_mod_clock_endisable(hw, false); } @@ -565,9 +389,6 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) return 1; } - if (clock->sibling) - return clock->enabled; - value = readl(priv->base + CLK_MON_R(clock->off)); return value & bitmask; @@ -579,28 +400,6 @@ static const struct clk_ops rzg2l_mod_clock_ops = { .is_enabled = rzg2l_mod_clock_is_enabled, }; -static struct mstp_clock -*rzg2l_mod_clock__get_sibling(struct mstp_clock *clock, - struct rzg2l_cpg_priv *priv) -{ - struct clk_hw *hw; - unsigned int i; - - for (i = 0; i < priv->num_mod_clks; i++) { - struct mstp_clock *clk; - - if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT)) - continue; - - hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]); - clk = to_mod_clock(hw); - if (clock->off == clk->off && clock->bit == clk->bit) - return clk; - } - - return NULL; -} - static void __init rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, const struct rzg2l_cpg_info *info, @@ -662,18 +461,6 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); priv->clks[id] = clk; - - if (mod->is_coupled) { - struct mstp_clock *sibling; - - clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw); - sibling = rzg2l_mod_clock__get_sibling(clock, priv); - if (sibling) { - clock->sibling = sibling; - sibling->sibling = clock; - } - } - return; fail: diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h index 5729d10203..63695280ce 100644 --- a/drivers/clk/renesas/rzg2l-cpg.h +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -9,20 +9,8 @@ #ifndef __RENESAS_RZG2L_CPG_H__ #define __RENESAS_RZG2L_CPG_H__ -#define CPG_PL1_DDIV (0x200) #define CPG_PL2_DDIV (0x204) #define CPG_PL3A_DDIV (0x208) -#define CPG_PL6_DDIV (0x210) -#define CPG_PL2SDHI_DSEL (0x218) -#define CPG_CLKSTATUS (0x280) -#define CPG_PL3_SSEL (0x408) -#define CPG_PL6_SSEL (0x414) -#define CPG_PL6_ETH_SSEL (0x418) - -#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28) -#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29) - -#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000 /* n = 0/1/2 for PLL1/4/6 */ #define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) @@ -32,22 +20,9 @@ #define DDIV_PACK(offset, bitpos, size) \ (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) -#define DIVPL1A DDIV_PACK(CPG_PL1_DDIV, 0, 2) #define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) #define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) #define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) -#define DIVPL3C DDIV_PACK(CPG_PL3A_DDIV, 8, 3) -#define DIVGPU DDIV_PACK(CPG_PL6_DDIV, 0, 2) - -#define SEL_PLL_PACK(offset, bitpos, size) \ - (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) - -#define SEL_PLL3_3 SEL_PLL_PACK(CPG_PL3_SSEL, 8, 1) -#define SEL_PLL6_2 SEL_PLL_PACK(CPG_PL6_ETH_SSEL, 0, 1) -#define SEL_GPU2 SEL_PLL_PACK(CPG_PL6_SSEL, 12, 1) - -#define SEL_SDHI0 DDIV_PACK(CPG_PL2SDHI_DSEL, 0, 2) -#define SEL_SDHI1 DDIV_PACK(CPG_PL2SDHI_DSEL, 4, 2) /** * Definitions of CPG Core Clocks @@ -68,7 +43,6 @@ struct cpg_core_clk { const struct clk_div_table *dtable; const char * const *parent_names; int flag; - int mux_flags; int num_parents; }; @@ -80,12 +54,6 @@ enum clk_types { /* Clock with divider */ CLK_TYPE_DIV, - - /* Clock with clock source selector */ - CLK_TYPE_MUX, - - /* Clock with SD clock source selector */ - CLK_TYPE_SD_MUX, }; #define DEF_TYPE(_name, _id, _type...) \ @@ -101,14 +69,6 @@ enum clk_types { #define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ .parent = _parent, .dtable = _dtable, .flag = _flag) -#define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _flag, \ - _mux_flags) \ - DEF_TYPE(_name, _id, CLK_TYPE_MUX, .conf = _conf, \ - .parent_names = _parent_names, .num_parents = _num_parents, \ - .flag = _flag, .mux_flags = _mux_flags) -#define DEF_SD_MUX(_name, _id, _conf, _parent_names, _num_parents) \ - DEF_TYPE(_name, _id, CLK_TYPE_SD_MUX, .conf = _conf, \ - .parent_names = _parent_names, .num_parents = _num_parents) /** * struct rzg2l_mod_clk - Module Clocks definitions @@ -118,7 +78,6 @@ enum clk_types { * @parent: id of parent clock * @off: register offset * @bit: ON/MON bit - * @is_coupled: flag to indicate coupled clock */ struct rzg2l_mod_clk { const char *name; @@ -126,25 +85,17 @@ struct rzg2l_mod_clk { unsigned int parent; u16 off; u8 bit; - bool is_coupled; }; -#define DEF_MOD_BASE(_name, _id, _parent, _off, _bit, _is_coupled) \ +#define DEF_MOD(_name, _id, _parent, _off, _bit) \ { \ .name = _name, \ .id = MOD_CLK_BASE + (_id), \ .parent = (_parent), \ .off = (_off), \ .bit = (_bit), \ - .is_coupled = (_is_coupled), \ } -#define DEF_MOD(_name, _id, _parent, _off, _bit) \ - DEF_MOD_BASE(_name, _id, _parent, _off, _bit, false) - -#define DEF_COUPLED(_name, _id, _parent, _off, _bit) \ - DEF_MOD_BASE(_name, _id, _parent, _off, _bit, true) - /** * struct rzg2l_reset - Reset definitions * @@ -174,9 +125,6 @@ struct rzg2l_reset { * @num_mod_clks: Number of entries in mod_clks[] * @num_hw_mod_clks: Number of Module Clocks supported by the hardware * - * @resets: Array of Module Reset definitions - * @num_resets: Number of entries in resets[] - * * @crit_mod_clks: Array with Module Clock IDs of critical clocks that * should not be disabled without a knowledgeable driver * @num_crit_mod_clks: Number of entries in crit_mod_clks[] diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig index 3067bdb6e1..2dfd6a3833 100644 --- a/drivers/clk/rockchip/Kconfig +++ b/drivers/clk/rockchip/Kconfig @@ -80,14 +80,14 @@ config CLK_RK3368 Build the driver for RK3368 Clock Driver. config CLK_RK3399 - bool "Rockchip RK3399 clock controller support" + tristate "Rockchip RK3399 clock controller support" depends on ARM64 || COMPILE_TEST default y help Build the driver for RK3399 Clock Driver. config CLK_RK3568 - bool "Rockchip RK3568 clock controller support" + tristate "Rockchip RK3568 clock controller support" depends on ARM64 || COMPILE_TEST default y help diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index 306910a3a0..62a4f25439 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -481,7 +481,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "atclk_core_l", "armclkl", CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3399_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_NOMUX(PCLK_COREDBG_L, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED, + COMPOSITE_NOMUX(0, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(1), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3399_CLKGATE_CON(0), 6, GFLAGS), @@ -531,7 +531,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_core_adb400_core_b_2_gic", "armclkb", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(14), 4, GFLAGS), - DIV(PCLK_COREDBG_B, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, + DIV(0, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(3), 13, 2, DFLAGS | CLK_DIVIDER_READ_ONLY), GATE(0, "pclk_dbg_cxcs_pd_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, @@ -1514,10 +1514,7 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { "aclk_vio_noc", /* ddrc */ - "sclk_ddrc", - - "armclkl", - "armclkb", + "sclk_ddrc" }; static const char *const rk3399_pmucru_critical_clocks[] __initconst = { @@ -1552,6 +1549,9 @@ static void __init rk3399_clk_init(struct device_node *np) rockchip_clk_register_branches(ctx, rk3399_clk_branches, ARRAY_SIZE(rk3399_clk_branches)); + rockchip_clk_protect_critical(rk3399_cru_critical_clocks, + ARRAY_SIZE(rk3399_cru_critical_clocks)); + rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl", mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), &rk3399_cpuclkl_data, rk3399_cpuclkl_rates, @@ -1562,9 +1562,6 @@ static void __init rk3399_clk_init(struct device_node *np) &rk3399_cpuclkb_data, rk3399_cpuclkb_rates, ARRAY_SIZE(rk3399_cpuclkb_rates)); - rockchip_clk_protect_critical(rk3399_cru_critical_clocks, - ARRAY_SIZE(rk3399_cru_critical_clocks)); - rockchip_register_softrst(np, 21, reg_base + RK3399_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK); @@ -1630,6 +1627,7 @@ static const struct of_device_id clk_rk3399_match_table[] = { }, { } }; +MODULE_DEVICE_TABLE(of, clk_rk3399_match_table); static int __init clk_rk3399_probe(struct platform_device *pdev) { @@ -1656,3 +1654,6 @@ static struct platform_driver clk_rk3399_driver = { }, }; builtin_platform_driver_probe(clk_rk3399_driver, clk_rk3399_probe); + +MODULE_DESCRIPTION("Rockchip RK3399 Clock Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 69a9e8069a..75ca855e72 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -1693,6 +1693,7 @@ static const struct of_device_id clk_rk3568_match_table[] = { }, { } }; +MODULE_DEVICE_TABLE(of, clk_rk3568_match_table); static int __init clk_rk3568_probe(struct platform_device *pdev) { @@ -1719,3 +1720,6 @@ static struct platform_driver clk_rk3568_driver = { }, }; builtin_platform_driver_probe(clk_rk3568_driver, clk_rk3568_probe); + +MODULE_DESCRIPTION("Rockchip RK3568 Clock Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index 0e18d6ff29..0441c4f73a 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -67,8 +67,7 @@ config EXYNOS_5420_COMMON_CLK depends on COMMON_CLK_SAMSUNG help Support for the clock controller present on the Samsung - Exynos5420/Exynos5422/Exynos5800 SoCs. Choose Y here only if you - build for this SoC. + Exynos5420 SoCs. Choose Y here only if you build for this SoC. config EXYNOS_ARM64_COMMON_CLK bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST @@ -80,47 +79,38 @@ config EXYNOS_AUDSS_CLK_CON default y if ARCH_EXYNOS help Support for the Audio Subsystem CLKCON clock controller present - on some Samsung Exynos SoC variants. Choose M or Y here if you want - to use audio devices such as I2S, PCM, etc. + on some Exynos SoC variants. Choose M or Y here if you want to + use audio devices such as I2S, PCM, etc. config EXYNOS_CLKOUT tristate "Samsung Exynos clock output driver" depends on COMMON_CLK_SAMSUNG default y if ARCH_EXYNOS help - Support for the clock output (XCLKOUT) present on some of Samsung - Exynos SoC variants. Usually the XCLKOUT is used to monitor the - status of the certains clocks from SoC, but it could also be tied to - other devices as an input clock. + Support for the clock output (XCLKOUT) present on some of Exynos SoC + variants. Usually the XCLKOUT is used to monitor the status of the + certains clocks from SoC, but it could also be tied to other devices + as an input clock. # For S3C24XX platforms, select following symbols: config S3C2410_COMMON_CLK bool "Samsung S3C2410 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG help - Support for the clock controller present on the Samsung - S3C2410/S3C2440/S3C2442 SoCs. Choose Y here only if you build for - this SoC. + Build the s3c2410 clock driver based on the common clock framework. config S3C2410_COMMON_DCLK bool select COMMON_CLK_SAMSUNG select REGMAP_MMIO help - Support for the dclk clock controller present on the Samsung - S3C2410/S3C2412/S3C2440/S3C2443 SoCs. Choose Y here only if you build - for this SoC. + Temporary symbol to build the dclk driver based on the common clock + framework. config S3C2412_COMMON_CLK bool "Samsung S3C2412 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG - help - Support for the clock controller present on the Samsung S3C2412 SoCs. - Choose Y here only if you build for this SoC. config S3C2443_COMMON_CLK bool "Samsung S3C2443 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG - help - Support for the clock controller present on the Samsung - S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC. diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 0df74916a8..028b2e27a3 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5-subcmu.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o -obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos-arm64.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o -obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7885.o -obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos850.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 3e62ade120..00ef4d1b08 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -400,7 +400,7 @@ static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb, } /* helper function to register a CPU clock */ -static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, +int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, unsigned int lookup_id, const char *name, const struct clk_hw *parent, const struct clk_hw *alt_parent, unsigned long offset, const struct exynos_cpuclk_cfg_data *cfg, @@ -469,21 +469,3 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, kfree(cpuclk); return ret; } - -void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx, - const struct samsung_cpu_clock *list, unsigned int nr_clk) -{ - unsigned int idx; - unsigned int num_cfgs; - struct clk_hw **hws = ctx->clk_data.hws; - - for (idx = 0; idx < nr_clk; idx++, list++) { - /* find count of configuration rates in cfg */ - for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; ) - num_cfgs++; - - exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id], - hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs, - list->flags); - } -} diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h index fc9f67a3b2..af74686db9 100644 --- a/drivers/clk/samsung/clk-cpu.h +++ b/drivers/clk/samsung/clk-cpu.h @@ -62,4 +62,11 @@ struct exynos_cpuclk { #define CLK_CPU_HAS_E5433_REGS_LAYOUT (1 << 2) }; +int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, + unsigned int lookup_id, const char *name, + const struct clk_hw *parent, const struct clk_hw *alt_parent, + unsigned long offset, + const struct exynos_cpuclk_cfg_data *cfg, + unsigned long num_cfgs, unsigned long flags); + #endif /* __SAMSUNG_CLK_CPU_H */ diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 9cc127a162..42b5d32c6c 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -129,6 +129,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in; const struct exynos_audss_clk_drvdata *variant; struct clk_hw **clk_table; + struct resource *res; struct device *dev = &pdev->dev; int i, ret = 0; @@ -136,7 +137,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) if (!variant) return -EINVAL; - reg_base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c index 6cc65ccf86..17df7f9755 100644 --- a/drivers/clk/samsung/clk-exynos3250.c +++ b/drivers/clk/samsung/clk-exynos3250.c @@ -748,31 +748,6 @@ static const struct samsung_pll_clock exynos3250_plls[] __initconst = { UPLL_LOCK, UPLL_CON0, exynos3250_pll_rates), }; -#define E3250_CPU_DIV0(apll, pclk_dbg, atb, corem) \ - (((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) | \ - ((corem) << 4)) -#define E3250_CPU_DIV1(hpm, copy) \ - (((hpm) << 4) | ((copy) << 0)) - -static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = { - { 1000000, E3250_CPU_DIV0(1, 7, 4, 1), E3250_CPU_DIV1(7, 7), }, - { 900000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 800000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 700000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 600000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 500000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 400000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 300000, E3250_CPU_DIV0(1, 5, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 200000, E3250_CPU_DIV0(1, 3, 3, 1), E3250_CPU_DIV1(7, 7), }, - { 100000, E3250_CPU_DIV0(1, 1, 1, 1), E3250_CPU_DIV1(7, 7), }, - { 0 }, -}; - -static const struct samsung_cpu_clock exynos3250_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C, - CLK_CPU_HAS_DIV1, 0x14200, e3250_armclk_d), -}; - static void __init exynos3_core_down_clock(void __iomem *reg_base) { unsigned int tmp; @@ -805,21 +780,46 @@ static const struct samsung_cmu_info cmu_info __initconst = { .nr_gate_clks = ARRAY_SIZE(gate_clks), .fixed_factor_clks = fixed_factor_clks, .nr_fixed_factor_clks = ARRAY_SIZE(fixed_factor_clks), - .cpu_clks = exynos3250_cpu_clks, - .nr_cpu_clks = ARRAY_SIZE(exynos3250_cpu_clks), .nr_clk_ids = CLK_NR_CLKS, .clk_regs = exynos3250_cmu_clk_regs, .nr_clk_regs = ARRAY_SIZE(exynos3250_cmu_clk_regs), }; +#define E3250_CPU_DIV0(apll, pclk_dbg, atb, corem) \ + (((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) | \ + ((corem) << 4)) +#define E3250_CPU_DIV1(hpm, copy) \ + (((hpm) << 4) | ((copy) << 0)) + +static const struct exynos_cpuclk_cfg_data e3250_armclk_d[] __initconst = { + { 1000000, E3250_CPU_DIV0(1, 7, 4, 1), E3250_CPU_DIV1(7, 7), }, + { 900000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 800000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 700000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 600000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 500000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 400000, E3250_CPU_DIV0(1, 7, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 300000, E3250_CPU_DIV0(1, 5, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 200000, E3250_CPU_DIV0(1, 3, 3, 1), E3250_CPU_DIV1(7, 7), }, + { 100000, E3250_CPU_DIV0(1, 1, 1, 1), E3250_CPU_DIV1(7, 7), }, + { 0 }, +}; + static void __init exynos3250_cmu_init(struct device_node *np) { struct samsung_clk_provider *ctx; + struct clk_hw **hws; ctx = samsung_cmu_register_one(np, &cmu_info); if (!ctx) return; + hws = ctx->clk_data.hws; + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C], + 0x14200, e3250_armclk_d, ARRAY_SIZE(e3250_armclk_d), + CLK_CPU_HAS_DIV1); + exynos3_core_down_clock(ctx->reg_base); } CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init); diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 22009cb534..bf13e29a65 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -437,7 +437,7 @@ static const struct samsung_mux_clock exynos4_mux_clks[] __initconst = { /* list of mux clocks supported in exynos4210 soc */ static const struct samsung_mux_clock exynos4210_mux_early[] __initconst = { - MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), + MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), }; static const struct samsung_mux_clock exynos4210_mux_clks[] __initconst = { @@ -603,7 +603,7 @@ static const struct samsung_div_clock exynos4_div_clks[] __initconst = { DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3), DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3), DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3), - DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3), DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3), DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3), DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6), @@ -1228,16 +1228,6 @@ static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = { { 0 }, }; -static const struct samsung_cpu_clock exynos4210_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_SCLK_MPLL, - CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4210_armclk_d), -}; - -static const struct samsung_cpu_clock exynos4412_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL_USER_C, - CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1, 0x14200, e4412_armclk_d), -}; - /* register exynos4 clocks */ static void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc soc) @@ -1264,21 +1254,21 @@ static void __init exynos4_clk_init(struct device_node *np, samsung_clk_register_mux(ctx, exynos4210_mux_early, ARRAY_SIZE(exynos4210_mux_early)); - if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24000000) { + if (_get_rate("fin_pll") == 24000000) { exynos4210_plls[apll].rate_table = exynos4210_apll_rates; exynos4210_plls[epll].rate_table = exynos4210_epll_rates; } - if (clk_hw_get_rate(hws[CLK_MOUT_VPLLSRC]) == 24000000) + if (_get_rate("mout_vpllsrc") == 24000000) exynos4210_plls[vpll].rate_table = exynos4210_vpll_rates; samsung_clk_register_pll(ctx, exynos4210_plls, ARRAY_SIZE(exynos4210_plls), reg_base); } else { - if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24000000) { + if (_get_rate("fin_pll") == 24000000) { exynos4x12_plls[apll].rate_table = exynos4x12_apll_rates; exynos4x12_plls[epll].rate_table = @@ -1314,8 +1304,10 @@ static void __init exynos4_clk_init(struct device_node *np, samsung_clk_register_fixed_factor(ctx, exynos4210_fixed_factor_clks, ARRAY_SIZE(exynos4210_fixed_factor_clks)); - samsung_clk_register_cpu(ctx, exynos4210_cpu_clks, - ARRAY_SIZE(exynos4210_cpu_clks)); + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_SCLK_MPLL], 0x14200, + e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d), + CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1); } else { samsung_clk_register_mux(ctx, exynos4x12_mux_clks, ARRAY_SIZE(exynos4x12_mux_clks)); @@ -1326,8 +1318,11 @@ static void __init exynos4_clk_init(struct device_node *np, samsung_clk_register_fixed_factor(ctx, exynos4x12_fixed_factor_clks, ARRAY_SIZE(exynos4x12_fixed_factor_clks)); - samsung_clk_register_cpu(ctx, exynos4412_cpu_clks, - ARRAY_SIZE(exynos4412_cpu_clks)); + + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL_USER_C], 0x14200, + e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d), + CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1); } if (soc == EXYNOS4X12) @@ -1349,11 +1344,9 @@ static void __init exynos4_clk_init(struct device_node *np, pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", - clk_hw_get_rate(hws[CLK_SCLK_APLL]), - clk_hw_get_rate(hws[CLK_SCLK_MPLL]), - clk_hw_get_rate(hws[CLK_SCLK_EPLL]), - clk_hw_get_rate(hws[CLK_SCLK_VPLL]), - clk_hw_get_rate(hws[CLK_DIV_CORE2])); + _get_rate("sclk_apll"), _get_rate("sclk_mpll"), + _get_rate("sclk_epll"), _get_rate("sclk_vpll"), + _get_rate("div_core2")); } diff --git a/drivers/clk/samsung/clk-exynos4412-isp.c b/drivers/clk/samsung/clk-exynos4412-isp.c index 471a6fb826..b69e381b8c 100644 --- a/drivers/clk/samsung/clk-exynos4412-isp.c +++ b/drivers/clk/samsung/clk-exynos4412-isp.c @@ -110,9 +110,11 @@ static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev) struct samsung_clk_provider *ctx; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + struct resource *res; void __iomem *reg_base; - reg_base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 113df773ee..06588fab40 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -239,7 +239,7 @@ static const struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __ }; static const struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initconst = { - MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), + MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), }; static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = { @@ -351,7 +351,7 @@ static const struct samsung_div_clock exynos5250_div_clks[] __initconst = { */ DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3), - DIV(CLK_DIV_ARM2, "div_arm2", "div_arm", DIV_CPU0, 28, 3), + DIV(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3), /* * CMU_TOP @@ -772,11 +772,6 @@ static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = { { 0 }, }; -static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200, - exynos5250_armclk_d), -}; - static const struct of_device_id ext_clk_match[] __initconst = { { .compatible = "samsung,clock-xxti", .data = (void *)0, }, { }, @@ -806,12 +801,12 @@ static void __init exynos5250_clk_init(struct device_node *np) samsung_clk_register_mux(ctx, exynos5250_pll_pmux_clks, ARRAY_SIZE(exynos5250_pll_pmux_clks)); - if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24 * MHZ) { + if (_get_rate("fin_pll") == 24 * MHZ) { exynos5250_plls[epll].rate_table = epll_24mhz_tbl; exynos5250_plls[apll].rate_table = apll_24mhz_tbl; } - if (clk_hw_get_rate(hws[CLK_MOUT_VPLLSRC]) == 24 * MHZ) + if (_get_rate("mout_vpllsrc") == 24 * MHZ) exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; samsung_clk_register_pll(ctx, exynos5250_plls, @@ -827,8 +822,10 @@ static void __init exynos5250_clk_init(struct device_node *np) ARRAY_SIZE(exynos5250_div_clks)); samsung_clk_register_gate(ctx, exynos5250_gate_clks, ARRAY_SIZE(exynos5250_gate_clks)); - samsung_clk_register_cpu(ctx, exynos5250_cpu_clks, - ARRAY_SIZE(exynos5250_cpu_clks)); + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_MOUT_MPLL], 0x200, + exynos5250_armclk_d, ARRAY_SIZE(exynos5250_armclk_d), + CLK_CPU_HAS_DIV1); /* * Enable arm clock down (in idle) and set arm divider @@ -858,6 +855,6 @@ static void __init exynos5250_clk_init(struct device_node *np) samsung_clk_of_add_provider(np, ctx); pr_info("Exynos5250: clock setup completed, armclk=%ld\n", - clk_hw_get_rate(hws[CLK_DIV_ARM2])); + _get_rate("div_arm2")); } CLK_OF_DECLARE_DRIVER(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index caad74dee2..3ccd4eabd2 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1551,20 +1551,6 @@ static const struct exynos_cpuclk_cfg_data exynos5420_kfcclk_d[] __initconst = { { 0 }, }; -static const struct samsung_cpu_clock exynos5420_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200, - exynos5420_eglclk_d), - CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200, - exynos5420_kfcclk_d), -}; - -static const struct samsung_cpu_clock exynos5800_cpu_clks[] __initconst = { - CPU_CLK(CLK_ARM_CLK, "armclk", CLK_MOUT_APLL, CLK_MOUT_MSPLL_CPU, 0, 0x200, - exynos5800_eglclk_d), - CPU_CLK(CLK_KFC_CLK, "kfcclk", CLK_MOUT_KPLL, CLK_MOUT_MSPLL_KFC, 0, 0x28200, - exynos5420_kfcclk_d), -}; - static const struct of_device_id ext_clk_match[] __initconst = { { .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, }, { }, @@ -1594,7 +1580,7 @@ static void __init exynos5x_clk_init(struct device_node *np, ARRAY_SIZE(exynos5x_fixed_rate_ext_clks), ext_clk_match); - if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24 * MHZ) { + if (_get_rate("fin_pll") == 24 * MHZ) { exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl; exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl; exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl; @@ -1639,12 +1625,17 @@ static void __init exynos5x_clk_init(struct device_node *np, } if (soc == EXYNOS5420) { - samsung_clk_register_cpu(ctx, exynos5420_cpu_clks, - ARRAY_SIZE(exynos5420_cpu_clks)); + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200, + exynos5420_eglclk_d, ARRAY_SIZE(exynos5420_eglclk_d), 0); } else { - samsung_clk_register_cpu(ctx, exynos5800_cpu_clks, - ARRAY_SIZE(exynos5800_cpu_clks)); + exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", + hws[CLK_MOUT_APLL], hws[CLK_MOUT_MSPLL_CPU], 0x200, + exynos5800_eglclk_d, ARRAY_SIZE(exynos5800_eglclk_d), 0); } + exynos_register_cpu_clock(ctx, CLK_KFC_CLK, "kfcclk", + hws[CLK_MOUT_KPLL], hws[CLK_MOUT_MSPLL_KFC], 0x28200, + exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0); samsung_clk_extended_sleep_init(reg_base, exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs), diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index f9daae20f3..f203074d85 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3675,32 +3675,44 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst { 0 }, }; -static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = { - CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL, - CLK_MOUT_BUS_PLL_APOLLO_USER, - CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200, - exynos5433_apolloclk_d), -}; - -static const struct samsung_cmu_info apollo_cmu_info __initconst = { - .pll_clks = apollo_pll_clks, - .nr_pll_clks = ARRAY_SIZE(apollo_pll_clks), - .mux_clks = apollo_mux_clks, - .nr_mux_clks = ARRAY_SIZE(apollo_mux_clks), - .div_clks = apollo_div_clks, - .nr_div_clks = ARRAY_SIZE(apollo_div_clks), - .gate_clks = apollo_gate_clks, - .nr_gate_clks = ARRAY_SIZE(apollo_gate_clks), - .cpu_clks = apollo_cpu_clks, - .nr_cpu_clks = ARRAY_SIZE(apollo_cpu_clks), - .nr_clk_ids = APOLLO_NR_CLK, - .clk_regs = apollo_clk_regs, - .nr_clk_regs = ARRAY_SIZE(apollo_clk_regs), -}; - static void __init exynos5433_cmu_apollo_init(struct device_node *np) { - samsung_cmu_register_one(np, &apollo_cmu_info); + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + struct clk_hw **hws; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + panic("%s: failed to map registers\n", __func__); + return; + } + + ctx = samsung_clk_init(np, reg_base, APOLLO_NR_CLK); + if (!ctx) { + panic("%s: unable to allocate ctx\n", __func__); + return; + } + + samsung_clk_register_pll(ctx, apollo_pll_clks, + ARRAY_SIZE(apollo_pll_clks), reg_base); + samsung_clk_register_mux(ctx, apollo_mux_clks, + ARRAY_SIZE(apollo_mux_clks)); + samsung_clk_register_div(ctx, apollo_div_clks, + ARRAY_SIZE(apollo_div_clks)); + samsung_clk_register_gate(ctx, apollo_gate_clks, + ARRAY_SIZE(apollo_gate_clks)); + + hws = ctx->clk_data.hws; + + exynos_register_cpu_clock(ctx, CLK_SCLK_APOLLO, "apolloclk", + hws[CLK_MOUT_APOLLO_PLL], hws[CLK_MOUT_BUS_PLL_APOLLO_USER], 0x200, + exynos5433_apolloclk_d, ARRAY_SIZE(exynos5433_apolloclk_d), + CLK_CPU_HAS_E5433_REGS_LAYOUT); + + samsung_clk_sleep_init(reg_base, apollo_clk_regs, + ARRAY_SIZE(apollo_clk_regs)); + + samsung_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo", exynos5433_cmu_apollo_init); @@ -3920,32 +3932,44 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst = { 0 }, }; -static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = { - CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL, - CLK_MOUT_BUS_PLL_ATLAS_USER, - CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200, - exynos5433_atlasclk_d), -}; - -static const struct samsung_cmu_info atlas_cmu_info __initconst = { - .pll_clks = atlas_pll_clks, - .nr_pll_clks = ARRAY_SIZE(atlas_pll_clks), - .mux_clks = atlas_mux_clks, - .nr_mux_clks = ARRAY_SIZE(atlas_mux_clks), - .div_clks = atlas_div_clks, - .nr_div_clks = ARRAY_SIZE(atlas_div_clks), - .gate_clks = atlas_gate_clks, - .nr_gate_clks = ARRAY_SIZE(atlas_gate_clks), - .cpu_clks = atlas_cpu_clks, - .nr_cpu_clks = ARRAY_SIZE(atlas_cpu_clks), - .nr_clk_ids = ATLAS_NR_CLK, - .clk_regs = atlas_clk_regs, - .nr_clk_regs = ARRAY_SIZE(atlas_clk_regs), -}; - static void __init exynos5433_cmu_atlas_init(struct device_node *np) { - samsung_cmu_register_one(np, &atlas_cmu_info); + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + struct clk_hw **hws; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + panic("%s: failed to map registers\n", __func__); + return; + } + + ctx = samsung_clk_init(np, reg_base, ATLAS_NR_CLK); + if (!ctx) { + panic("%s: unable to allocate ctx\n", __func__); + return; + } + + samsung_clk_register_pll(ctx, atlas_pll_clks, + ARRAY_SIZE(atlas_pll_clks), reg_base); + samsung_clk_register_mux(ctx, atlas_mux_clks, + ARRAY_SIZE(atlas_mux_clks)); + samsung_clk_register_div(ctx, atlas_div_clks, + ARRAY_SIZE(atlas_div_clks)); + samsung_clk_register_gate(ctx, atlas_gate_clks, + ARRAY_SIZE(atlas_gate_clks)); + + hws = ctx->clk_data.hws; + + exynos_register_cpu_clock(ctx, CLK_SCLK_ATLAS, "atlasclk", + hws[CLK_MOUT_ATLAS_PLL], hws[CLK_MOUT_BUS_PLL_ATLAS_USER], 0x200, + exynos5433_atlasclk_d, ARRAY_SIZE(exynos5433_atlasclk_d), + CLK_CPU_HAS_E5433_REGS_LAYOUT); + + samsung_clk_sleep_init(reg_base, atlas_clk_regs, + ARRAY_SIZE(atlas_clk_regs)); + + samsung_clk_of_add_provider(np, ctx); } CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas", exynos5433_cmu_atlas_init); @@ -5540,6 +5564,7 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev) struct exynos5433_cmu_data *data; struct samsung_clk_provider *ctx; struct device *dev = &pdev->dev; + struct resource *res; void __iomem *reg_base; int i; @@ -5552,7 +5577,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev) return -ENOMEM; ctx = &data->ctx; - reg_base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 70cdc87f71..5873a9354b 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -415,186 +415,6 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, }; -/* - * PLL0822x Clock Type - */ -/* Maximum lock time can be 150 * PDIV cycles */ -#define PLL0822X_LOCK_FACTOR (150) - -#define PLL0822X_MDIV_MASK (0x3FF) -#define PLL0822X_PDIV_MASK (0x3F) -#define PLL0822X_SDIV_MASK (0x7) -#define PLL0822X_MDIV_SHIFT (16) -#define PLL0822X_PDIV_SHIFT (8) -#define PLL0822X_SDIV_SHIFT (0) -#define PLL0822X_LOCK_STAT_SHIFT (29) -#define PLL0822X_ENABLE_SHIFT (31) - -static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 mdiv, pdiv, sdiv, pll_con3; - u64 fvco = parent_rate; - - pll_con3 = readl_relaxed(pll->con_reg); - mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK; - pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK; - sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK; - - fvco *= mdiv; - do_div(fvco, (pdiv << sdiv)); - - return (unsigned long)fvco; -} - -static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - const struct samsung_pll_rate_table *rate; - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 pll_con3; - - /* Get required rate settings from table */ - rate = samsung_get_pll_settings(pll, drate); - if (!rate) { - pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, - drate, clk_hw_get_name(hw)); - return -EINVAL; - } - - /* Change PLL PMS values */ - pll_con3 = readl_relaxed(pll->con_reg); - pll_con3 &= ~((PLL0822X_MDIV_MASK << PLL0822X_MDIV_SHIFT) | - (PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) | - (PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT)); - pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) | - (rate->pdiv << PLL0822X_PDIV_SHIFT) | - (rate->sdiv << PLL0822X_SDIV_SHIFT); - - /* Set PLL lock time */ - writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR, - pll->lock_reg); - - /* Write PMS values */ - writel_relaxed(pll_con3, pll->con_reg); - - /* Wait for PLL lock if the PLL is enabled */ - if (pll_con3 & BIT(pll->enable_offs)) - return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); - - return 0; -} - -static const struct clk_ops samsung_pll0822x_clk_ops = { - .recalc_rate = samsung_pll0822x_recalc_rate, - .round_rate = samsung_pll_round_rate, - .set_rate = samsung_pll0822x_set_rate, - .enable = samsung_pll3xxx_enable, - .disable = samsung_pll3xxx_disable, -}; - -static const struct clk_ops samsung_pll0822x_clk_min_ops = { - .recalc_rate = samsung_pll0822x_recalc_rate, -}; - -/* - * PLL0831x Clock Type - */ -/* Maximum lock time can be 500 * PDIV cycles */ -#define PLL0831X_LOCK_FACTOR (500) - -#define PLL0831X_KDIV_MASK (0xFFFF) -#define PLL0831X_MDIV_MASK (0x1FF) -#define PLL0831X_PDIV_MASK (0x3F) -#define PLL0831X_SDIV_MASK (0x7) -#define PLL0831X_MDIV_SHIFT (16) -#define PLL0831X_PDIV_SHIFT (8) -#define PLL0831X_SDIV_SHIFT (0) -#define PLL0831X_KDIV_SHIFT (0) -#define PLL0831X_LOCK_STAT_SHIFT (29) -#define PLL0831X_ENABLE_SHIFT (31) - -static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 mdiv, pdiv, sdiv, pll_con3, pll_con5; - s16 kdiv; - u64 fvco = parent_rate; - - pll_con3 = readl_relaxed(pll->con_reg); - pll_con5 = readl_relaxed(pll->con_reg + 8); - mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK; - pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK; - sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK; - kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK); - - fvco *= (mdiv << 16) + kdiv; - do_div(fvco, (pdiv << sdiv)); - fvco >>= 16; - - return (unsigned long)fvco; -} - -static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long parent_rate) -{ - const struct samsung_pll_rate_table *rate; - struct samsung_clk_pll *pll = to_clk_pll(hw); - u32 pll_con3, pll_con5; - - /* Get required rate settings from table */ - rate = samsung_get_pll_settings(pll, drate); - if (!rate) { - pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, - drate, clk_hw_get_name(hw)); - return -EINVAL; - } - - pll_con3 = readl_relaxed(pll->con_reg); - pll_con5 = readl_relaxed(pll->con_reg + 8); - - /* Change PLL PMSK values */ - pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) | - (PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) | - (PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT)); - pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) | - (rate->pdiv << PLL0831X_PDIV_SHIFT) | - (rate->sdiv << PLL0831X_SDIV_SHIFT); - pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT); - /* - * kdiv is 16-bit 2's complement (s16), but stored as unsigned int. - * Cast it to u16 to avoid leading 0xffff's in case of negative value. - */ - pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT); - - /* Set PLL lock time */ - writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg); - - /* Write PMSK values */ - writel_relaxed(pll_con3, pll->con_reg); - writel_relaxed(pll_con5, pll->con_reg + 8); - - /* Wait for PLL lock if the PLL is enabled */ - if (pll_con3 & BIT(pll->enable_offs)) - return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); - - return 0; -} - -static const struct clk_ops samsung_pll0831x_clk_ops = { - .recalc_rate = samsung_pll0831x_recalc_rate, - .set_rate = samsung_pll0831x_set_rate, - .round_rate = samsung_pll_round_rate, - .enable = samsung_pll3xxx_enable, - .disable = samsung_pll3xxx_disable, -}; - -static const struct clk_ops samsung_pll0831x_clk_min_ops = { - .recalc_rate = samsung_pll0831x_recalc_rate, -}; - /* * PLL45xx Clock Type */ @@ -1476,15 +1296,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll35xx_clk_ops; break; - case pll_1417x: - case pll_0822x: - pll->enable_offs = PLL0822X_ENABLE_SHIFT; - pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT; - if (!pll->rate_table) - init.ops = &samsung_pll0822x_clk_min_ops; - else - init.ops = &samsung_pll0822x_clk_ops; - break; case pll_4500: init.ops = &samsung_pll45xx_clk_min_ops; break; @@ -1505,14 +1316,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll36xx_clk_ops; break; - case pll_0831x: - pll->enable_offs = PLL0831X_ENABLE_SHIFT; - pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT; - if (!pll->rate_table) - init.ops = &samsung_pll0831x_clk_min_ops; - else - init.ops = &samsung_pll0831x_clk_ops; - break; case pll_6552: case pll_6552_s3c2416: init.ops = &samsung_pll6552_clk_ops; diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index c83a20195f..79e41c226b 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -32,13 +32,10 @@ enum samsung_pll_type { pll_2550xx, pll_2650x, pll_2650xx, - pll_1417x, pll_1450x, pll_1451x, pll_1452x, pll_1460x, - pll_0822x, - pll_0831x, }; #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \ diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index 3d152a4616..5831d06060 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -323,7 +323,6 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, void __iomem *base) { struct samsung_clk_provider *ctx; - struct clk_hw **hws; reg_base = base; if (np) { @@ -333,14 +332,13 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, } ctx = samsung_clk_init(np, reg_base, NR_CLKS); - hws = ctx->clk_data.hws; /* Register external clocks only in non-dt cases */ if (!np) s3c2410_common_clk_register_fixed_ext(ctx, xti_f); if (current_soc == S3C2410) { - if (clk_hw_get_rate(hws[XTI]) == 12 * MHZ) { + if (_get_rate("xti") == 12 * MHZ) { s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl; s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl; } @@ -350,7 +348,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, ARRAY_SIZE(s3c2410_plls), reg_base); } else { /* S3C2440, S3C2442 */ - if (clk_hw_get_rate(hws[XTI]) == 12 * MHZ) { + if (_get_rate("xti") == 12 * MHZ) { /* * plls follow different calculation schemes, with the * upll following the same scheme as the s3c2410 plls diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index d6b432a26d..56f95b63f7 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -394,7 +394,6 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, void __iomem *base) { struct samsung_clk_provider *ctx; - struct clk_hw **hws; reg_base = base; is_s3c6400 = s3c6400; @@ -406,7 +405,6 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, } ctx = samsung_clk_init(np, reg_base, NR_CLKS); - hws = ctx->clk_data.hws; /* Register external clocks. */ if (!np) @@ -461,10 +459,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, pr_info("%s clocks: apll = %lu, mpll = %lu\n" "\tepll = %lu, arm_clk = %lu\n", is_s3c6400 ? "S3C6400" : "S3C6410", - clk_hw_get_rate(hws[MOUT_APLL]), - clk_hw_get_rate(hws[MOUT_MPLL]), - clk_hw_get_rate(hws[MOUT_EPLL]), - clk_hw_get_rate(hws[ARMCLK])); + _get_rate("fout_apll"), _get_rate("fout_mpll"), + _get_rate("fout_epll"), _get_rate("armclk")); } static void __init s3c6400_clk_init(struct device_node *np) diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index b31c00ea33..a7827a1206 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -63,13 +63,15 @@ static struct syscore_ops s5pv210_audss_clk_syscore_ops = { static int s5pv210_audss_clk_probe(struct platform_device *pdev) { int i, ret = 0; + struct resource *res; const char *mout_audss_p[2]; const char *mout_i2s_p[3]; const char *hclk_p; struct clk_hw **clk_table; struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio; - reg_base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg_base)) return PTR_ERR(reg_base); diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index 4425186bdc..e7b68ffe36 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -741,10 +741,8 @@ static void __init __s5pv210_clk_init(struct device_node *np, bool is_s5p6442) { struct samsung_clk_provider *ctx; - struct clk_hw **hws; ctx = samsung_clk_init(np, reg_base, NR_CLKS); - hws = ctx->clk_data.hws; samsung_clk_register_mux(ctx, early_mux_clks, ARRAY_SIZE(early_mux_clks)); @@ -791,10 +789,8 @@ static void __init __s5pv210_clk_init(struct device_node *np, pr_info("%s clocks: mout_apll = %ld, mout_mpll = %ld\n" "\tmout_epll = %ld, mout_vpll = %ld\n", is_s5p6442 ? "S5P6442" : "S5PV210", - clk_hw_get_rate(hws[MOUT_APLL]), - clk_hw_get_rate(hws[MOUT_MPLL]), - clk_hw_get_rate(hws[MOUT_EPLL]), - clk_hw_get_rate(hws[MOUT_VPLL])); + _get_rate("mout_apll"), _get_rate("mout_mpll"), + _get_rate("mout_epll"), _get_rate("mout_vpll")); } static void __init s5pv210_clk_dt_init(struct device_node *np) diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index bca4731b14..1949ae7851 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -268,6 +268,20 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); } +/* utility function to get the rate of a specified clock */ +unsigned long _get_rate(const char *clk_name) +{ + struct clk *clk; + + clk = __clk_lookup(clk_name); + if (!clk) { + pr_err("%s: could not find clock %s\n", __func__, clk_name); + return 0; + } + + return clk_get_rate(clk); +} + #ifdef CONFIG_PM_SLEEP static int samsung_clk_suspend(void) { @@ -364,8 +378,6 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( samsung_clk_extended_sleep_init(reg_base, cmu->clk_regs, cmu->nr_clk_regs, cmu->suspend_regs, cmu->nr_suspend_regs); - if (cmu->cpu_clks) - samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index b46e83a258..c1e1a6b2f4 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -271,27 +271,6 @@ struct samsung_pll_clock { __PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \ _con, _rtable) -struct samsung_cpu_clock { - unsigned int id; - const char *name; - unsigned int parent_id; - unsigned int alt_parent_id; - unsigned long flags; - int offset; - const struct exynos_cpuclk_cfg_data *cfg; -}; - -#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \ - { \ - .id = _id, \ - .name = _name, \ - .parent_id = _pid, \ - .alt_parent_id = _apid, \ - .flags = _flags, \ - .offset = _offset, \ - .cfg = _cfg, \ - } - struct samsung_clock_reg_cache { struct list_head node; void __iomem *reg_base; @@ -322,9 +301,6 @@ struct samsung_cmu_info { unsigned int nr_fixed_factor_clks; /* total number of clocks with IDs assigned*/ unsigned int nr_clk_ids; - /* list of cpu clocks and respective count */ - const struct samsung_cpu_clock *cpu_clks; - unsigned int nr_cpu_clks; /* list and number of clocks registers */ const unsigned long *clk_regs; @@ -337,52 +313,52 @@ struct samsung_cmu_info { const char *clk_name; }; -struct samsung_clk_provider * samsung_clk_init( +extern struct samsung_clk_provider *__init samsung_clk_init( struct device_node *np, void __iomem *base, unsigned long nr_clks); -void samsung_clk_of_add_provider(struct device_node *np, +extern void __init samsung_clk_of_add_provider(struct device_node *np, struct samsung_clk_provider *ctx); -void samsung_clk_of_register_fixed_ext( +extern void __init samsung_clk_of_register_fixed_ext( struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, const struct of_device_id *clk_matches); -void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, +extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk_hw *clk_hw, unsigned int id); -void samsung_clk_register_alias(struct samsung_clk_provider *ctx, +extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, const struct samsung_clock_alias *list, unsigned int nr_clk); -void samsung_clk_register_fixed_rate( +extern void __init samsung_clk_register_fixed_rate( struct samsung_clk_provider *ctx, const struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); -void samsung_clk_register_fixed_factor( +extern void __init samsung_clk_register_fixed_factor( struct samsung_clk_provider *ctx, const struct samsung_fixed_factor_clock *list, unsigned int nr_clk); -void samsung_clk_register_mux(struct samsung_clk_provider *ctx, +extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, const struct samsung_mux_clock *clk_list, unsigned int nr_clk); -void samsung_clk_register_div(struct samsung_clk_provider *ctx, +extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, const struct samsung_div_clock *clk_list, unsigned int nr_clk); -void samsung_clk_register_gate(struct samsung_clk_provider *ctx, +extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, const struct samsung_gate_clock *clk_list, unsigned int nr_clk); -void samsung_clk_register_pll(struct samsung_clk_provider *ctx, +extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, const struct samsung_pll_clock *pll_list, unsigned int nr_clk, void __iomem *base); -void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, - const struct samsung_cpu_clock *list, unsigned int nr_clk); -struct samsung_clk_provider *samsung_cmu_register_one( +extern struct samsung_clk_provider __init *samsung_cmu_register_one( struct device_node *, const struct samsung_cmu_info *); +extern unsigned long _get_rate(const char *clk_name); + #ifdef CONFIG_PM_SLEEP -void samsung_clk_extended_sleep_init(void __iomem *reg_base, +extern void samsung_clk_extended_sleep_init(void __iomem *reg_base, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, @@ -397,13 +373,13 @@ static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, #define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) -void samsung_clk_save(void __iomem *base, +extern void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs); -void samsung_clk_restore(void __iomem *base, +extern void samsung_clk_restore(void __iomem *base, const struct samsung_clk_reg_dump *rd, unsigned int num_regs); -struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( +extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( const unsigned long *rdump, unsigned long nr_rdump); diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index 74d21bd827..bf8cd928c2 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -500,10 +500,12 @@ static int n5x_clkmgr_init(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; struct stratix10_clock_data *clk_data; + struct resource *res; void __iomem *base; int i, num_clks; - base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c index 53d6e3ec43..1ec9678d8c 100644 --- a/drivers/clk/socfpga/clk-gate.c +++ b/drivers/clk/socfpga/clk-gate.c @@ -34,7 +34,7 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) if (streq(name, SOCFPGA_L4_MP_CLK)) { l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC); - return l4_src & 0x1; + return l4_src &= 0x1; } if (streq(name, SOCFPGA_L4_SP_CLK)) { l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC); @@ -43,7 +43,7 @@ static u8 socfpga_clk_get_parent(struct clk_hw *hwclk) perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC); if (streq(name, SOCFPGA_MMC_CLK)) - return perpll_src & 0x3; + return perpll_src &= 0x3; if (streq(name, SOCFPGA_NAND_CLK) || streq(name, SOCFPGA_NAND_X_CLK)) return (perpll_src >> 2) & 3; diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index e444e4a0ee..70076a8014 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -113,7 +113,7 @@ static unsigned long clk_boot_clk_recalc_rate(struct clk_hw *hwclk, SWCTRLBTCLKSEL_MASK) >> SWCTRLBTCLKSEL_SHIFT); div += 1; - return parent_rate / div; + return parent_rate /= div; } diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 4e508a844b..b532d51faa 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c @@ -388,10 +388,12 @@ static int s10_clkmgr_init(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; struct stratix10_clock_data *clk_data; + struct resource *res; void __iomem *base; int i, num_clks; - base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) { pr_err("%s: failed to map clock registers\n", __func__); return PTR_ERR(base); diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 582a22c049..164285d6be 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -988,18 +988,9 @@ static void __init st_of_quadfs_setup(struct device_node *np, void __iomem *reg; spinlock_t *lock; - /* - * First check for reg property within the node to keep backward - * compatibility, then if reg doesn't exist look at the parent node - */ reg = of_iomap(np, 0); - if (!reg) { - reg = of_iomap(of_get_parent(np), 0); - if (!reg) { - pr_err("%s: Failed to get base address\n", __func__); - return; - } - } + if (!reg) + return; clk_parent_name = of_clk_get_parent_name(np, 0); if (!clk_parent_name) diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index ee39af7a0b..ce583ded96 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -57,17 +57,10 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np, const char **parents; int num_parents = 0; - /* - * First check for reg property within the node to keep backward - * compatibility, then if reg doesn't exist look at the parent node - */ reg = of_iomap(np, 0); if (!reg) { - reg = of_iomap(of_get_parent(np), 0); - if (!reg) { - pr_err("%s: Failed to get base address\n", __func__); - return; - } + pr_err("%s: Failed to get base address\n", __func__); + return; } parents = clkgen_mux_get_parents(np, &num_parents); diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 68a94e5af8..cd46d88538 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only config SUNXI_CCU - tristate "Clock support for Allwinner SoCs" + bool "Clock support for Allwinner SoCs" depends on ARCH_SUNXI || COMPILE_TEST select RESET_CONTROLLER default ARCH_SUNXI @@ -8,52 +8,42 @@ config SUNXI_CCU if SUNXI_CCU config SUNIV_F1C100S_CCU - tristate "Support for the Allwinner newer F1C100s CCU" + bool "Support for the Allwinner newer F1C100s CCU" default MACH_SUNIV depends on MACH_SUNIV || COMPILE_TEST -config SUN20I_D1_CCU - tristate "Support for the Allwinner D1 CCU" - default RISCV && ARCH_SUNXI - depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST - -config SUN20I_D1_R_CCU - tristate "Support for the Allwinner D1 PRCM CCU" - default RISCV && ARCH_SUNXI - depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST - config SUN50I_A64_CCU - tristate "Support for the Allwinner A64 CCU" + bool "Support for the Allwinner A64 CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN50I_A100_CCU - tristate "Support for the Allwinner A100 CCU" + bool "Support for the Allwinner A100 CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN50I_A100_R_CCU - tristate "Support for the Allwinner A100 PRCM CCU" + bool "Support for the Allwinner A100 PRCM CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN50I_H6_CCU - tristate "Support for the Allwinner H6 CCU" + bool "Support for the Allwinner H6 CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN50I_H616_CCU - tristate "Support for the Allwinner H616 CCU" + bool "Support for the Allwinner H616 CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN50I_H6_R_CCU - tristate "Support for the Allwinner H6 and H616 PRCM CCU" + bool "Support for the Allwinner H6 and H616 PRCM CCU" default ARM64 && ARCH_SUNXI depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN4I_A10_CCU - tristate "Support for the Allwinner A10/A20 CCU" + bool "Support for the Allwinner A10/A20 CCU" default MACH_SUN4I default MACH_SUN7I depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST @@ -62,54 +52,52 @@ config SUN5I_CCU bool "Support for the Allwinner sun5i family CCM" default MACH_SUN5I depends on MACH_SUN5I || COMPILE_TEST - depends on SUNXI_CCU=y config SUN6I_A31_CCU - tristate "Support for the Allwinner A31/A31s CCU" + bool "Support for the Allwinner A31/A31s CCU" default MACH_SUN6I depends on MACH_SUN6I || COMPILE_TEST config SUN8I_A23_CCU - tristate "Support for the Allwinner A23 CCU" + bool "Support for the Allwinner A23 CCU" default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST config SUN8I_A33_CCU - tristate "Support for the Allwinner A33 CCU" + bool "Support for the Allwinner A33 CCU" default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST config SUN8I_A83T_CCU - tristate "Support for the Allwinner A83T CCU" + bool "Support for the Allwinner A83T CCU" default MACH_SUN8I - depends on MACH_SUN8I || COMPILE_TEST config SUN8I_H3_CCU - tristate "Support for the Allwinner H3 CCU" + bool "Support for the Allwinner H3 CCU" default MACH_SUN8I || (ARM64 && ARCH_SUNXI) depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST config SUN8I_V3S_CCU - tristate "Support for the Allwinner V3s CCU" + bool "Support for the Allwinner V3s CCU" default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST config SUN8I_DE2_CCU - tristate "Support for the Allwinner SoCs DE2 CCU" + bool "Support for the Allwinner SoCs DE2 CCU" default MACH_SUN8I || (ARM64 && ARCH_SUNXI) config SUN8I_R40_CCU - tristate "Support for the Allwinner R40 CCU" + bool "Support for the Allwinner R40 CCU" default MACH_SUN8I depends on MACH_SUN8I || COMPILE_TEST config SUN9I_A80_CCU - tristate "Support for the Allwinner A80 CCU" + bool "Support for the Allwinner A80 CCU" default MACH_SUN9I depends on MACH_SUN9I || COMPILE_TEST config SUN8I_R_CCU - tristate "Support for Allwinner SoCs' PRCM CCUs" + bool "Support for Allwinner SoCs' PRCM CCUs" default MACH_SUN8I || (ARCH_SUNXI && ARM64) endif diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index ec931cb7aa..96c324306d 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -1,73 +1,44 @@ # SPDX-License-Identifier: GPL-2.0 - -obj-$(CONFIG_SUNXI_CCU) += sunxi-ccu.o - # Common objects -sunxi-ccu-y += ccu_common.o -sunxi-ccu-y += ccu_mmc_timing.o -sunxi-ccu-y += ccu_reset.o +obj-y += ccu_common.o +obj-y += ccu_mmc_timing.o +obj-y += ccu_reset.o # Base clock types -sunxi-ccu-y += ccu_div.o -sunxi-ccu-y += ccu_frac.o -sunxi-ccu-y += ccu_gate.o -sunxi-ccu-y += ccu_mux.o -sunxi-ccu-y += ccu_mult.o -sunxi-ccu-y += ccu_phase.o -sunxi-ccu-y += ccu_sdm.o +obj-y += ccu_div.o +obj-y += ccu_frac.o +obj-y += ccu_gate.o +obj-y += ccu_mux.o +obj-y += ccu_mult.o +obj-y += ccu_phase.o +obj-y += ccu_sdm.o # Multi-factor clocks -sunxi-ccu-y += ccu_nk.o -sunxi-ccu-y += ccu_nkm.o -sunxi-ccu-y += ccu_nkmp.o -sunxi-ccu-y += ccu_nm.o -sunxi-ccu-y += ccu_mp.o +obj-y += ccu_nk.o +obj-y += ccu_nkm.o +obj-y += ccu_nkmp.o +obj-y += ccu_nm.o +obj-y += ccu_mp.o # SoC support -obj-$(CONFIG_SUNIV_F1C100S_CCU) += suniv-f1c100s-ccu.o -obj-$(CONFIG_SUN20I_D1_CCU) += sun20i-d1-ccu.o -obj-$(CONFIG_SUN20I_D1_R_CCU) += sun20i-d1-r-ccu.o -obj-$(CONFIG_SUN50I_A64_CCU) += sun50i-a64-ccu.o -obj-$(CONFIG_SUN50I_A100_CCU) += sun50i-a100-ccu.o -obj-$(CONFIG_SUN50I_A100_R_CCU) += sun50i-a100-r-ccu.o -obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o -obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o -obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o -obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o -obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o -obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o -obj-$(CONFIG_SUN8I_A23_CCU) += sun8i-a23-ccu.o -obj-$(CONFIG_SUN8I_A33_CCU) += sun8i-a33-ccu.o -obj-$(CONFIG_SUN8I_A83T_CCU) += sun8i-a83t-ccu.o -obj-$(CONFIG_SUN8I_H3_CCU) += sun8i-h3-ccu.o -obj-$(CONFIG_SUN8I_R40_CCU) += sun8i-r40-ccu.o -obj-$(CONFIG_SUN8I_V3S_CCU) += sun8i-v3s-ccu.o -obj-$(CONFIG_SUN8I_DE2_CCU) += sun8i-de2-ccu.o -obj-$(CONFIG_SUN8I_R_CCU) += sun8i-r-ccu.o -obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-ccu.o -obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-de-ccu.o -obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-usb-ccu.o - -suniv-f1c100s-ccu-y += ccu-suniv-f1c100s.o -sun20i-d1-ccu-y += ccu-sun20i-d1.o -sun20i-d1-r-ccu-y += ccu-sun20i-d1-r.o -sun50i-a64-ccu-y += ccu-sun50i-a64.o -sun50i-a100-ccu-y += ccu-sun50i-a100.o -sun50i-a100-r-ccu-y += ccu-sun50i-a100-r.o -sun50i-h6-ccu-y += ccu-sun50i-h6.o -sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o -sun50i-h616-ccu-y += ccu-sun50i-h616.o -sun4i-a10-ccu-y += ccu-sun4i-a10.o -sun5i-ccu-y += ccu-sun5i.o -sun6i-a31-ccu-y += ccu-sun6i-a31.o -sun8i-a23-ccu-y += ccu-sun8i-a23.o -sun8i-a33-ccu-y += ccu-sun8i-a33.o -sun8i-a83t-ccu-y += ccu-sun8i-a83t.o -sun8i-h3-ccu-y += ccu-sun8i-h3.o -sun8i-r40-ccu-y += ccu-sun8i-r40.o -sun8i-v3s-ccu-y += ccu-sun8i-v3s.o -sun8i-de2-ccu-y += ccu-sun8i-de2.o -sun8i-r-ccu-y += ccu-sun8i-r.o -sun9i-a80-ccu-y += ccu-sun9i-a80.o -sun9i-a80-de-ccu-y += ccu-sun9i-a80-de.o -sun9i-a80-usb-ccu-y += ccu-sun9i-a80-usb.o +obj-$(CONFIG_SUNIV_F1C100S_CCU) += ccu-suniv-f1c100s.o +obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o +obj-$(CONFIG_SUN50I_A100_CCU) += ccu-sun50i-a100.o +obj-$(CONFIG_SUN50I_A100_R_CCU) += ccu-sun50i-a100-r.o +obj-$(CONFIG_SUN50I_H6_CCU) += ccu-sun50i-h6.o +obj-$(CONFIG_SUN50I_H616_CCU) += ccu-sun50i-h616.o +obj-$(CONFIG_SUN50I_H6_R_CCU) += ccu-sun50i-h6-r.o +obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o +obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o +obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o +obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o +obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o +obj-$(CONFIG_SUN8I_A83T_CCU) += ccu-sun8i-a83t.o +obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o +obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o +obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o +obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o +obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o +obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o +obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o +obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index c19828f1aa..bd9a8782fe 100644 --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c @@ -7,9 +7,7 @@ #include #include -#include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -1427,19 +1425,18 @@ static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = { .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets), }; -static int sun4i_a10_ccu_probe(struct platform_device *pdev) +static void __init sun4i_ccu_init(struct device_node *node, + const struct sunxi_ccu_desc *desc) { - const struct sunxi_ccu_desc *desc; void __iomem *reg; u32 val; - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; - - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%s: Could not map the clock registers\n", + of_node_full_name(node)); + return; + } val = readl(reg + SUN4I_PLL_AUDIO_REG); @@ -1467,30 +1464,19 @@ static int sun4i_a10_ccu_probe(struct platform_device *pdev) val &= ~GENMASK(7, 6); writel(val | (2 << 6), reg + SUN4I_AHB_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); } -static const struct of_device_id sun4i_a10_ccu_ids[] = { - { - .compatible = "allwinner,sun4i-a10-ccu", - .data = &sun4i_a10_ccu_desc, - }, - { - .compatible = "allwinner,sun7i-a20-ccu", - .data = &sun7i_a20_ccu_desc, - }, - { } -}; +static void __init sun4i_a10_ccu_setup(struct device_node *node) +{ + sun4i_ccu_init(node, &sun4i_a10_ccu_desc); +} +CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu", + sun4i_a10_ccu_setup); -static struct platform_driver sun4i_a10_ccu_driver = { - .probe = sun4i_a10_ccu_probe, - .driver = { - .name = "sun4i-a10-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun4i_a10_ccu_ids, - }, -}; -module_platform_driver(sun4i_a10_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +static void __init sun7i_a20_ccu_setup(struct device_node *node) +{ + sun4i_ccu_init(node, &sun7i_a20_ccu_desc); +} +CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu", + sun7i_a20_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c index fddd6c877c..6f2a589705 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c @@ -5,6 +5,7 @@ #include #include +#include #include #include "ccu_common.h" @@ -207,11 +208,7 @@ static struct platform_driver sun50i_a100_r_ccu_driver = { .probe = sun50i_a100_r_ccu_probe, .driver = { .name = "sun50i-a100-r-ccu", - .suppress_bind_attrs = true, .of_match_table = sun50i_a100_r_ccu_ids, }, }; module_platform_driver(sun50i_a100_r_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c index 5f93b5526e..913bb08e6d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "ccu_common.h" @@ -1269,11 +1270,7 @@ static struct platform_driver sun50i_a100_ccu_driver = { .probe = sun50i_a100_ccu_probe, .driver = { .name = "sun50i-a100-ccu", - .suppress_bind_attrs = true, .of_match_table = sun50i_a100_ccu_ids, }, }; module_platform_driver(sun50i_a100_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 4151918560..54f25c624f 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -938,11 +938,13 @@ static struct ccu_mux_nb sun50i_a64_cpu_nb = { static int sun50i_a64_ccu_probe(struct platform_device *pdev) { + struct resource *res; void __iomem *reg; u32 val; int ret; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -976,11 +978,7 @@ static struct platform_driver sun50i_a64_ccu_driver = { .probe = sun50i_a64_ccu_probe, .driver = { .name = "sun50i-a64-ccu", - .suppress_bind_attrs = true, .of_match_table = sun50i_a64_ccu_ids, }, }; -module_platform_driver(sun50i_a64_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun50i_a64_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index a8c11c0b4e..54d1f96f4b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -51,6 +51,8 @@ #define CLK_USB_OHCI1_12M 92 +#define CLK_DRAM 94 + /* All the DRAM gates are exported */ /* And the DSI and GPU module clock is exported */ diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c index 712e103382..f30d7eb542 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c @@ -4,8 +4,7 @@ */ #include -#include -#include +#include #include #include "ccu_common.h" @@ -222,43 +221,30 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = { .num_resets = ARRAY_SIZE(sun50i_h616_r_ccu_resets), }; -static int sun50i_h6_r_ccu_probe(struct platform_device *pdev) +static void __init sunxi_r_ccu_init(struct device_node *node, + const struct sunxi_ccu_desc *desc) { - const struct sunxi_ccu_desc *desc; void __iomem *reg; - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); } -static const struct of_device_id sun50i_h6_r_ccu_ids[] = { - { - .compatible = "allwinner,sun50i-h6-r-ccu", - .data = &sun50i_h6_r_ccu_desc, - }, - { - .compatible = "allwinner,sun50i-h616-r-ccu", - .data = &sun50i_h616_r_ccu_desc, - }, - { } -}; +static void __init sun50i_h6_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun50i_h6_r_ccu_desc); +} +CLK_OF_DECLARE(sun50i_h6_r_ccu, "allwinner,sun50i-h6-r-ccu", + sun50i_h6_r_ccu_setup); -static struct platform_driver sun50i_h6_r_ccu_driver = { - .probe = sun50i_h6_r_ccu_probe, - .driver = { - .name = "sun50i-h6-r-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun50i_h6_r_ccu_ids, - }, -}; -module_platform_driver(sun50i_h6_r_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +static void __init sun50i_h616_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun50i_h616_r_ccu_desc); +} +CLK_OF_DECLARE(sun50i_h616_r_ccu, "allwinner,sun50i-h616-r-ccu", + sun50i_h616_r_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index 1a5e418923..c0800da2fa 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -1183,11 +1183,13 @@ static const u32 usb2_clk_regs[] = { static int sun50i_h6_ccu_probe(struct platform_device *pdev) { + struct resource *res; void __iomem *reg; u32 val; int i; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -1250,11 +1252,7 @@ static struct platform_driver sun50i_h6_ccu_driver = { .probe = sun50i_h6_ccu_probe, .driver = { .name = "sun50i-h6-ccu", - .suppress_bind_attrs = true, .of_match_table = sun50i_h6_ccu_ids, }, }; -module_platform_driver(sun50i_h6_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun50i_h6_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index 49a2474cf3..22eb18079a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -1082,15 +1082,17 @@ static const u32 usb2_clk_regs[] = { SUN50I_H616_USB3_CLK_REG, }; -static int sun50i_h616_ccu_probe(struct platform_device *pdev) +static void __init sun50i_h616_ccu_setup(struct device_node *node) { void __iomem *reg; u32 val; int i; - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map clock registers\n", node); + return; + } /* Enable the lock bits and the output enable bits on all PLLs */ for (i = 0; i < ARRAY_SIZE(pll_regs); i++) { @@ -1139,23 +1141,8 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev) val |= BIT(24); writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc); + of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); } -static const struct of_device_id sun50i_h616_ccu_ids[] = { - { .compatible = "allwinner,sun50i-h616-ccu" }, - { } -}; - -static struct platform_driver sun50i_h616_ccu_driver = { - .probe = sun50i_h616_ccu_probe, - .driver = { - .name = "sun50i-h616-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun50i_h616_ccu_ids, - }, -}; -module_platform_driver(sun50i_h616_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu", + sun50i_h616_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 0762deffb3..3df5c0b415 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -9,8 +9,7 @@ #include #include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -1227,15 +1226,16 @@ static struct ccu_mux_nb sun6i_a31_cpu_nb = { .bypass_index = 1, /* index of 24 MHz oscillator */ }; -static int sun6i_a31_ccu_probe(struct platform_device *pdev) +static void __init sun6i_a31_ccu_setup(struct device_node *node) { void __iomem *reg; - int ret; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN6I_A31_PLL_AUDIO_REG); @@ -1257,30 +1257,10 @@ static int sun6i_a31_ccu_probe(struct platform_device *pdev) val |= 0x3 << 12; writel(val, reg + SUN6I_A31_AHB1_REG); - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc); - if (ret) - return ret; + of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, &sun6i_a31_cpu_nb); - - return 0; } - -static const struct of_device_id sun6i_a31_ccu_ids[] = { - { .compatible = "allwinner,sun6i-a31-ccu" }, - { } -}; - -static struct platform_driver sun6i_a31_ccu_driver = { - .probe = sun6i_a31_ccu_probe, - .driver = { - .name = "sun6i-a31-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun6i_a31_ccu_ids, - }, -}; -module_platform_driver(sun6i_a31_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu", + sun6i_a31_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index e80cc3864e..577bb235d6 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c @@ -5,8 +5,7 @@ #include #include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -725,14 +724,16 @@ static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = { .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets), }; -static int sun8i_a23_ccu_probe(struct platform_device *pdev) +static void __init sun8i_a23_ccu_setup(struct device_node *node) { void __iomem *reg; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN8I_A23_PLL_AUDIO_REG); @@ -744,23 +745,7 @@ static int sun8i_a23_ccu_probe(struct platform_device *pdev) val &= ~BIT(16); writel(val, reg + SUN8I_A23_PLL_MIPI_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a23_ccu_desc); + of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); } - -static const struct of_device_id sun8i_a23_ccu_ids[] = { - { .compatible = "allwinner,sun8i-a23-ccu" }, - { } -}; - -static struct platform_driver sun8i_a23_ccu_driver = { - .probe = sun8i_a23_ccu_probe, - .driver = { - .name = "sun8i-a23-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun8i_a23_ccu_ids, - }, -}; -module_platform_driver(sun8i_a23_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", + sun8i_a23_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index d12878a1ba..8f65cd03f5 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c @@ -5,8 +5,7 @@ #include #include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -785,15 +784,16 @@ static struct ccu_mux_nb sun8i_a33_cpu_nb = { .bypass_index = 1, /* index of 24 MHz oscillator */ }; -static int sun8i_a33_ccu_probe(struct platform_device *pdev) +static void __init sun8i_a33_ccu_setup(struct device_node *node) { void __iomem *reg; - int ret; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN8I_A33_PLL_AUDIO_REG); @@ -805,9 +805,7 @@ static int sun8i_a33_ccu_probe(struct platform_device *pdev) val &= ~BIT(16); writel(val, reg + SUN8I_A33_PLL_MIPI_REG); - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a33_ccu_desc); - if (ret) - return ret; + of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); /* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb); @@ -815,24 +813,6 @@ static int sun8i_a33_ccu_probe(struct platform_device *pdev) /* Reparent CPU during PLL CPU rate changes */ ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, &sun8i_a33_cpu_nb); - - return 0; } - -static const struct of_device_id sun8i_a33_ccu_ids[] = { - { .compatible = "allwinner,sun8i-a33-ccu" }, - { } -}; - -static struct platform_driver sun8i_a33_ccu_driver = { - .probe = sun8i_a33_ccu_probe, - .driver = { - .name = "sun8i-a33-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun8i_a33_ccu_ids, - }, -}; -module_platform_driver(sun8i_a33_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu", + sun8i_a33_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index 76cbd9e9e8..c2ddcd2dda 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -887,10 +887,12 @@ static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg) static int sun8i_a83t_ccu_probe(struct platform_device *pdev) { + struct resource *res; void __iomem *reg; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -916,11 +918,7 @@ static struct platform_driver sun8i_a83t_ccu_driver = { .probe = sun8i_a83t_ccu_probe, .driver = { .name = "sun8i-a83t-ccu", - .suppress_bind_attrs = true, .of_match_table = sun8i_a83t_ccu_ids, }, }; -module_platform_driver(sun8i_a83t_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_a83t_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index e7e3ddf4a2..4b94b6041b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -280,6 +280,7 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { static int sunxi_de2_clk_probe(struct platform_device *pdev) { + struct resource *res; struct clk *bus_clk, *mod_clk; struct reset_control *rstc; void __iomem *reg; @@ -290,7 +291,8 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) if (!ccu_desc) return -EINVAL; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -394,7 +396,4 @@ static struct platform_driver sunxi_de2_clk_driver = { .of_match_table = sunxi_de2_clk_ids, }, }; -module_platform_driver(sunxi_de2_clk_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sunxi_de2_clk_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index e058cf691a..d2fc290378 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -5,9 +5,7 @@ #include #include -#include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -1139,29 +1137,24 @@ static struct ccu_mux_nb sun8i_h3_cpu_nb = { .bypass_index = 1, /* index of 24 MHz oscillator */ }; -static int sun8i_h3_ccu_probe(struct platform_device *pdev) +static void __init sunxi_h3_h5_ccu_init(struct device_node *node, + const struct sunxi_ccu_desc *desc) { - const struct sunxi_ccu_desc *desc; void __iomem *reg; - int ret; u32 val; - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; - - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN8I_H3_PLL_AUDIO_REG); val &= ~GENMASK(19, 16); writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, desc); - if (ret) - return ret; + of_sunxi_ccu_probe(node, reg, desc); /* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb); @@ -1169,31 +1162,18 @@ static int sun8i_h3_ccu_probe(struct platform_device *pdev) /* Reparent CPU during PLL CPU rate changes */ ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, &sun8i_h3_cpu_nb); - - return 0; } -static const struct of_device_id sun8i_h3_ccu_ids[] = { - { - .compatible = "allwinner,sun8i-h3-ccu", - .data = &sun8i_h3_ccu_desc, - }, - { - .compatible = "allwinner,sun50i-h5-ccu", - .data = &sun50i_h5_ccu_desc, - }, - { } -}; +static void __init sun8i_h3_ccu_setup(struct device_node *node) +{ + sunxi_h3_h5_ccu_init(node, &sun8i_h3_ccu_desc); +} +CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu", + sun8i_h3_ccu_setup); -static struct platform_driver sun8i_h3_ccu_driver = { - .probe = sun8i_h3_ccu_probe, - .driver = { - .name = "sun8i-h3-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun8i_h3_ccu_ids, - }, -}; -module_platform_driver(sun8i_h3_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +static void __init sun50i_h5_ccu_setup(struct device_node *node) +{ + sunxi_h3_h5_ccu_init(node, &sun50i_h5_ccu_desc); +} +CLK_OF_DECLARE(sun50i_h5_ccu, "allwinner,sun50i-h5-ccu", + sun50i_h5_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index e13f3c4b57..d8c38447e1 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h @@ -42,6 +42,8 @@ /* The first bunch of module clocks are exported */ +#define CLK_DRAM 96 + /* All the DRAM gates are exported */ /* Some more module clocks are exported */ diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index 5b7fab832a..9e754d1f75 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -4,8 +4,7 @@ */ #include -#include -#include +#include #include #include "ccu_common.h" @@ -255,47 +254,37 @@ static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = { .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets), }; -static int sun8i_r_ccu_probe(struct platform_device *pdev) +static void __init sunxi_r_ccu_init(struct device_node *node, + const struct sunxi_ccu_desc *desc) { - const struct sunxi_ccu_desc *desc; void __iomem *reg; - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); - - return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); } -static const struct of_device_id sun8i_r_ccu_ids[] = { - { - .compatible = "allwinner,sun8i-a83t-r-ccu", - .data = &sun8i_a83t_r_ccu_desc, - }, - { - .compatible = "allwinner,sun8i-h3-r-ccu", - .data = &sun8i_h3_r_ccu_desc, - }, - { - .compatible = "allwinner,sun50i-a64-r-ccu", - .data = &sun50i_a64_r_ccu_desc, - }, - { } -}; +static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); +} +CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", + sun8i_a83t_r_ccu_setup); -static struct platform_driver sun8i_r_ccu_driver = { - .probe = sun8i_r_ccu_probe, - .driver = { - .name = "sun8i-r-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun8i_r_ccu_ids, - }, -}; -module_platform_driver(sun8i_r_ccu_driver); +static void __init sun8i_h3_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); +} +CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu", + sun8i_h3_r_ccu_setup); -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +static void __init sun50i_a64_r_ccu_setup(struct device_node *node) +{ + sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc); +} +CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu", + sun50i_a64_r_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 31eca0d3bc..002e0c3a04 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -1308,12 +1307,14 @@ static struct regmap_config sun8i_r40_ccu_regmap_config = { static int sun8i_r40_ccu_probe(struct platform_device *pdev) { + struct resource *res; struct regmap *regmap; void __iomem *reg; u32 val; int ret; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -1368,11 +1369,7 @@ static struct platform_driver sun8i_r40_ccu_driver = { .probe = sun8i_r40_ccu_probe, .driver = { .name = "sun8i-r40-ccu", - .suppress_bind_attrs = true, .of_match_table = sun8i_r40_ccu_ids, }, }; -module_platform_driver(sun8i_r40_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_r40_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index 87f87d6ea3..ce150f83ab 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -8,9 +8,7 @@ #include #include -#include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -807,49 +805,38 @@ static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = { .num_resets = ARRAY_SIZE(sun8i_v3_ccu_resets), }; -static int sun8i_v3s_ccu_probe(struct platform_device *pdev) +static void __init sun8i_v3_v3s_ccu_init(struct device_node *node, + const struct sunxi_ccu_desc *ccu_desc) { - const struct sunxi_ccu_desc *desc; void __iomem *reg; u32 val; - desc = of_device_get_match_data(&pdev->dev); - if (!desc) - return -EINVAL; - - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG); val &= ~GENMASK(19, 16); writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, desc); + of_sunxi_ccu_probe(node, reg, ccu_desc); } -static const struct of_device_id sun8i_v3s_ccu_ids[] = { - { - .compatible = "allwinner,sun8i-v3-ccu", - .data = &sun8i_v3_ccu_desc, - }, - { - .compatible = "allwinner,sun8i-v3s-ccu", - .data = &sun8i_v3s_ccu_desc, - }, - { } -}; +static void __init sun8i_v3s_ccu_setup(struct device_node *node) +{ + sun8i_v3_v3s_ccu_init(node, &sun8i_v3s_ccu_desc); +} -static struct platform_driver sun8i_v3s_ccu_driver = { - .probe = sun8i_v3s_ccu_probe, - .driver = { - .name = "sun8i-v3s-ccu", - .suppress_bind_attrs = true, - .of_match_table = sun8i_v3s_ccu_ids, - }, -}; -module_platform_driver(sun8i_v3s_ccu_driver); +static void __init sun8i_v3_ccu_setup(struct device_node *node) +{ + sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc); +} -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu", + sun8i_v3s_ccu_setup); + +CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu", + sun8i_v3_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c index f2fe0e1cc3..261e64416f 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -203,12 +203,14 @@ static const struct sunxi_ccu_desc sun9i_a80_de_clk_desc = { static int sun9i_a80_de_clk_probe(struct platform_device *pdev) { + struct resource *res; struct clk *bus_clk; struct reset_control *rstc; void __iomem *reg; int ret; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -266,11 +268,7 @@ static struct platform_driver sun9i_a80_de_clk_driver = { .probe = sun9i_a80_de_clk_probe, .driver = { .name = "sun9i-a80-de-clks", - .suppress_bind_attrs = true, .of_match_table = sun9i_a80_de_clk_ids, }, }; -module_platform_driver(sun9i_a80_de_clk_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun9i_a80_de_clk_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c index 575ae4ccc6..596243b3e0 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -92,11 +92,13 @@ static const struct sunxi_ccu_desc sun9i_a80_usb_clk_desc = { static int sun9i_a80_usb_clk_probe(struct platform_device *pdev) { + struct resource *res; struct clk *bus_clk; void __iomem *reg; int ret; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -138,7 +140,4 @@ static struct platform_driver sun9i_a80_usb_clk_driver = { .of_match_table = sun9i_a80_usb_clk_ids, }, }; -module_platform_driver(sun9i_a80_usb_clk_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun9i_a80_usb_clk_driver); diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c index 730fd8e280..97aaed0e68 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include "ccu_common.h" @@ -1213,10 +1213,12 @@ static void sun9i_a80_cpu_pll_fixup(void __iomem *reg) static int sun9i_a80_ccu_probe(struct platform_device *pdev) { + struct resource *res; void __iomem *reg; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -1241,11 +1243,7 @@ static struct platform_driver sun9i_a80_ccu_driver = { .probe = sun9i_a80_ccu_probe, .driver = { .name = "sun9i-a80-ccu", - .suppress_bind_attrs = true, .of_match_table = sun9i_a80_ccu_ids, }, }; -module_platform_driver(sun9i_a80_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun9i_a80_ccu_driver); diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c index ed097c4f78..61ad7ee91c 100644 --- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c +++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c @@ -6,8 +6,7 @@ #include #include -#include -#include +#include #include "ccu_common.h" #include "ccu_reset.h" @@ -523,24 +522,23 @@ static struct ccu_mux_nb suniv_cpu_nb = { .bypass_index = 1, /* index of 24 MHz oscillator */ }; -static int suniv_f1c100s_ccu_probe(struct platform_device *pdev) +static void __init suniv_f1c100s_ccu_setup(struct device_node *node) { void __iomem *reg; - int ret; u32 val; - reg = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(reg)) - return PTR_ERR(reg); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(reg)) { + pr_err("%pOF: Could not map the clock registers\n", node); + return; + } /* Force the PLL-Audio-1x divider to 4 */ val = readl(reg + SUNIV_PLL_AUDIO_REG); val &= ~GENMASK(19, 16); writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG); - ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &suniv_ccu_desc); - if (ret) - return ret; + of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc); /* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&suniv_pll_cpu_nb); @@ -548,24 +546,6 @@ static int suniv_f1c100s_ccu_probe(struct platform_device *pdev) /* Reparent CPU during PLL CPU rate changes */ ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, &suniv_cpu_nb); - - return 0; } - -static const struct of_device_id suniv_f1c100s_ccu_ids[] = { - { .compatible = "allwinner,suniv-f1c100s-ccu" }, - { } -}; - -static struct platform_driver suniv_f1c100s_ccu_driver = { - .probe = suniv_f1c100s_ccu_probe, - .driver = { - .name = "suniv-f1c100s-ccu", - .suppress_bind_attrs = true, - .of_match_table = suniv_f1c100s_ccu_ids, - }, -}; -module_platform_driver(suniv_f1c100s_ccu_driver); - -MODULE_IMPORT_NS(SUNXI_CCU); -MODULE_LICENSE("GPL"); +CLK_OF_DECLARE(suniv_f1c100s_ccu, "allwinner,suniv-f1c100s-ccu", + suniv_f1c100s_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 8d28a7a079..88cb569e58 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include "ccu_common.h" @@ -18,10 +17,11 @@ struct sunxi_ccu { const struct sunxi_ccu_desc *desc; - spinlock_t lock; struct ccu_reset reset; }; +static DEFINE_SPINLOCK(ccu_lock); + void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) { void __iomem *addr; @@ -37,7 +37,6 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000)); } -EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, SUNXI_CCU); /* * This clock notifier is called when the frequency of a PLL clock is @@ -85,7 +84,6 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb) return clk_notifier_register(pll_nb->common->hw.clk, &pll_nb->clk_nb); } -EXPORT_SYMBOL_NS_GPL(ccu_pll_notifier_register, SUNXI_CCU); static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, struct device_node *node, void __iomem *reg, @@ -96,8 +94,6 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, ccu->desc = desc; - spin_lock_init(&ccu->lock); - for (i = 0; i < desc->num_ccu_clks; i++) { struct ccu_common *cclk = desc->ccu_clks[i]; @@ -105,7 +101,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, continue; cclk->base = reg; - cclk->lock = &ccu->lock; + cclk->lock = &ccu_lock; } for (i = 0; i < desc->hw_clks->num ; i++) { @@ -137,7 +133,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE; reset->rcdev.nr_resets = desc->num_resets; reset->base = reg; - reset->lock = &ccu->lock; + reset->lock = &ccu_lock; reset->reset_map = desc->resets; ret = reset_controller_register(&reset->rcdev); @@ -197,7 +193,6 @@ int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, return 0; } -EXPORT_SYMBOL_NS_GPL(devm_sunxi_ccu_probe, SUNXI_CCU); void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, const struct sunxi_ccu_desc *desc) @@ -215,5 +210,3 @@ void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, kfree(ccu); } } - -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index cb10a3ea23..4c29708948 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -141,4 +141,3 @@ const struct clk_ops ccu_div_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_div_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index 948e2b0c0c..6682fde604 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h @@ -108,22 +108,6 @@ struct ccu_div { _shift, _width, _table, 0, \ _flags) -#define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg, \ - _shift, _width, \ - _table, _flags) \ - struct ccu_div _struct = { \ - .div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \ - _table), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_HW(_name, \ - _parent, \ - &ccu_div_ops, \ - _flags), \ - } \ - } - - #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ _parents, _table, \ _reg, \ @@ -182,68 +166,6 @@ struct ccu_div { SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ _mshift, _mwidth, 0, _flags) -#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _muxshift, _muxwidth, \ - _gate, _flags) \ - struct ccu_div _struct = { \ - .enable = _gate, \ - .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ - .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ - _parents, \ - &ccu_div_ops, \ - _flags), \ - }, \ - } - -#define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _muxshift, _muxwidth, \ - _flags) \ - SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _muxshift, _muxwidth, \ - 0, _flags) - -#define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, _muxshift, _muxwidth, \ - _gate, _flags) \ - struct ccu_div _struct = { \ - .enable = _gate, \ - .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ - .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_HW(_name, \ - _parents, \ - &ccu_div_ops, \ - _flags), \ - }, \ - } - -#define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \ - _mshift, _mwidth, _gate, \ - _flags) \ - struct ccu_div _struct = { \ - .enable = _gate, \ - .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_HWS(_name, \ - _parent, \ - &ccu_div_ops, \ - _flags), \ - }, \ - } - -#define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift, \ - _mwidth, _flags) \ - SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \ - _mshift, _mwidth, 0, _flags) - static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); diff --git a/drivers/clk/sunxi-ng/ccu_frac.c b/drivers/clk/sunxi-ng/ccu_frac.c index b31f3ad946..44fcded8b3 100644 --- a/drivers/clk/sunxi-ng/ccu_frac.c +++ b/drivers/clk/sunxi-ng/ccu_frac.c @@ -18,7 +18,6 @@ bool ccu_frac_helper_is_enabled(struct ccu_common *common, return !(readl(common->base + common->reg) & cf->enable); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_is_enabled, SUNXI_CCU); void ccu_frac_helper_enable(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -34,7 +33,6 @@ void ccu_frac_helper_enable(struct ccu_common *common, writel(reg & ~cf->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_enable, SUNXI_CCU); void ccu_frac_helper_disable(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -50,7 +48,6 @@ void ccu_frac_helper_disable(struct ccu_common *common, writel(reg | cf->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_disable, SUNXI_CCU); bool ccu_frac_helper_has_rate(struct ccu_common *common, struct ccu_frac_internal *cf, @@ -61,7 +58,6 @@ bool ccu_frac_helper_has_rate(struct ccu_common *common, return (cf->rates[0] == rate) || (cf->rates[1] == rate); } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_has_rate, SUNXI_CCU); unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, struct ccu_frac_internal *cf) @@ -83,7 +79,6 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_read_rate, SUNXI_CCU); int ccu_frac_helper_set_rate(struct ccu_common *common, struct ccu_frac_internal *cf, @@ -112,4 +107,3 @@ int ccu_frac_helper_set_rate(struct ccu_common *common, return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_set_rate, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c index a2115a2180..3d5ca092b0 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.c +++ b/drivers/clk/sunxi-ng/ccu_gate.c @@ -24,7 +24,6 @@ void ccu_gate_helper_disable(struct ccu_common *common, u32 gate) spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_disable, SUNXI_CCU); static void ccu_gate_disable(struct clk_hw *hw) { @@ -50,7 +49,6 @@ int ccu_gate_helper_enable(struct ccu_common *common, u32 gate) return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_enable, SUNXI_CCU); static int ccu_gate_enable(struct clk_hw *hw) { @@ -66,7 +64,6 @@ int ccu_gate_helper_is_enabled(struct ccu_common *common, u32 gate) return readl(common->base + common->reg) & gate; } -EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_is_enabled, SUNXI_CCU); static int ccu_gate_is_enabled(struct clk_hw *hw) { @@ -127,4 +124,3 @@ const struct clk_ops ccu_gate_ops = { .set_rate = ccu_gate_set_rate, .recalc_rate = ccu_gate_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_gate_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_gate.h b/drivers/clk/sunxi-ng/ccu_gate.h index dc05ce0673..c386689a95 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.h +++ b/drivers/clk/sunxi-ng/ccu_gate.h @@ -53,7 +53,7 @@ struct ccu_gate { } /* - * The following macros allow the re-use of the data structure + * The following two macros allow the re-use of the data structure * holding the parent info. */ #define SUNXI_CCU_GATE_HWS(_struct, _name, _parent, _reg, _gate, _flags) \ @@ -68,21 +68,6 @@ struct ccu_gate { } \ } -#define SUNXI_CCU_GATE_HWS_WITH_PREDIV(_struct, _name, _parent, _reg, \ - _gate, _prediv, _flags) \ - struct ccu_gate _struct = { \ - .enable = _gate, \ - .common = { \ - .reg = _reg, \ - .prediv = _prediv, \ - .features = CCU_FEATURE_ALL_PREDIV, \ - .hw.init = CLK_HW_INIT_HWS(_name, \ - _parent, \ - &ccu_gate_ops, \ - _flags), \ - } \ - } - #define SUNXI_CCU_GATE_DATA(_struct, _name, _data, _reg, _gate, _flags) \ struct ccu_gate _struct = { \ .enable = _gate, \ @@ -96,21 +81,6 @@ struct ccu_gate { } \ } -#define SUNXI_CCU_GATE_DATA_WITH_PREDIV(_struct, _name, _parent, _reg, \ - _gate, _prediv, _flags) \ - struct ccu_gate _struct = { \ - .enable = _gate, \ - .common = { \ - .reg = _reg, \ - .prediv = _prediv, \ - .features = CCU_FEATURE_ALL_PREDIV, \ - .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ - _parent, \ - &ccu_gate_ops, \ - _flags), \ - } \ - } - static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index 57cf2d6151..9d3a76604d 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -245,7 +245,6 @@ const struct clk_ops ccu_mp_ops = { .recalc_rate = ccu_mp_recalc_rate, .set_rate = ccu_mp_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mp_ops, SUNXI_CCU); /* * Support for MMC timing mode switching @@ -326,4 +325,3 @@ const struct clk_ops ccu_mp_mmc_ops = { .recalc_rate = ccu_mp_mmc_recalc_rate, .set_rate = ccu_mp_mmc_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mp_mmc_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h index 6e50f3728f..b392e0d575 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.h +++ b/drivers/clk/sunxi-ng/ccu_mp.h @@ -82,55 +82,6 @@ struct ccu_mp { _muxshift, _muxwidth, \ 0, _flags) -#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _pshift, _pwidth, \ - _muxshift, _muxwidth, \ - _gate, _flags) \ - struct ccu_mp _struct = { \ - .enable = _gate, \ - .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ - .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ - .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ - _parents, \ - &ccu_mp_ops, \ - _flags), \ - } \ - } - -#define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _pshift, _pwidth, \ - _muxshift, _muxwidth, \ - _flags) \ - SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _pshift, _pwidth, \ - _muxshift, _muxwidth, \ - 0, _flags) - -#define SUNXI_CCU_MP_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ - _mshift, _mwidth, \ - _pshift, _pwidth, \ - _muxshift, _muxwidth, \ - _gate, _flags) \ - struct ccu_mp _struct = { \ - .enable = _gate, \ - .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ - .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ - .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_HW(_name, \ - _parents, \ - &ccu_mp_ops, \ - _flags), \ - } \ - } - static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 7bee217ef1..7c8cf2e04e 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -170,4 +170,3 @@ const struct clk_ops ccu_mult_ops = { .recalc_rate = ccu_mult_recalc_rate, .set_rate = ccu_mult_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mult_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 2306a1cd83..7d75da9a1f 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -64,7 +64,6 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, { return parent_rate / ccu_mux_get_prediv(common, cm, parent_index); } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, SUNXI_CCU); static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, struct ccu_mux_internal *cm, @@ -153,7 +152,6 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, req->rate = best_rate; return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_determine_rate, SUNXI_CCU); u8 ccu_mux_helper_get_parent(struct ccu_common *common, struct ccu_mux_internal *cm) @@ -176,7 +174,6 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common, return parent; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_get_parent, SUNXI_CCU); int ccu_mux_helper_set_parent(struct ccu_common *common, struct ccu_mux_internal *cm, @@ -198,7 +195,6 @@ int ccu_mux_helper_set_parent(struct ccu_common *common, return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_set_parent, SUNXI_CCU); static void ccu_mux_disable(struct clk_hw *hw) { @@ -255,7 +251,6 @@ const struct clk_ops ccu_mux_ops = { .determine_rate = __clk_mux_determine_rate, .recalc_rate = ccu_mux_recalc_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, SUNXI_CCU); /* * This clock notifier is called when the frequency of the of the parent @@ -290,4 +285,3 @@ int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb) return clk_notifier_register(clk, &mux_nb->clk_nb); } -EXPORT_SYMBOL_NS_GPL(ccu_mux_notifier_register, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h index 2c1811a445..f165395eff 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.h +++ b/drivers/clk/sunxi-ng/ccu_mux.h @@ -40,6 +40,7 @@ struct ccu_mux_internal { _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL) struct ccu_mux { + u16 reg; u32 enable; struct ccu_mux_internal mux; @@ -72,39 +73,6 @@ struct ccu_mux { SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ _reg, _shift, _width, 0, _flags) -#define SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg, \ - _shift, _width, _gate, _flags) \ - struct ccu_mux _struct = { \ - .enable = _gate, \ - .mux = _SUNXI_CCU_MUX(_shift, _width), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \ - _parents, \ - &ccu_mux_ops, \ - _flags), \ - } \ - } - -#define SUNXI_CCU_MUX_DATA(_struct, _name, _parents, _reg, \ - _shift, _width, _flags) \ - SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg, \ - _shift, _width, 0, _flags) - -#define SUNXI_CCU_MUX_HW_WITH_GATE(_struct, _name, _parents, _reg, \ - _shift, _width, _gate, _flags) \ - struct ccu_mux _struct = { \ - .enable = _gate, \ - .mux = _SUNXI_CCU_MUX(_shift, _width), \ - .common = { \ - .reg = _reg, \ - .hw.init = CLK_HW_INIT_PARENTS_HW(_name, \ - _parents, \ - &ccu_mux_ops, \ - _flags), \ - } \ - } - static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c index c4fb82af97..aee68b00f3 100644 --- a/drivers/clk/sunxi-ng/ccu_nk.c +++ b/drivers/clk/sunxi-ng/ccu_nk.c @@ -157,4 +157,3 @@ const struct clk_ops ccu_nk_ops = { .round_rate = ccu_nk_round_rate, .set_rate = ccu_nk_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 67da2c189b..b9cfee0276 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -206,4 +206,3 @@ const struct clk_ops ccu_nkm_ops = { .recalc_rate = ccu_nkm_recalc_rate, .set_rate = ccu_nkm_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 39413cb098..bda87b38c4 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -230,4 +230,3 @@ const struct clk_ops ccu_nkmp_ops = { .round_rate = ccu_nkmp_round_rate, .set_rate = ccu_nkmp_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index 9ca9257f44..e6bcc0a717 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -238,4 +238,3 @@ const struct clk_ops ccu_nm_ops = { .round_rate = ccu_nm_round_rate, .set_rate = ccu_nm_set_rate, }; -EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_phase.c b/drivers/clk/sunxi-ng/ccu_phase.c index e4cae2afe9..92ab8bd664 100644 --- a/drivers/clk/sunxi-ng/ccu_phase.c +++ b/drivers/clk/sunxi-ng/ccu_phase.c @@ -121,4 +121,3 @@ const struct clk_ops ccu_phase_ops = { .get_phase = ccu_phase_get_phase, .set_phase = ccu_phase_set_phase, }; -EXPORT_SYMBOL_NS_GPL(ccu_phase_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_reset.c b/drivers/clk/sunxi-ng/ccu_reset.c index 6577aa18cb..483100e45d 100644 --- a/drivers/clk/sunxi-ng/ccu_reset.c +++ b/drivers/clk/sunxi-ng/ccu_reset.c @@ -75,4 +75,3 @@ const struct reset_control_ops ccu_reset_ops = { .reset = ccu_reset_reset, .status = ccu_reset_status, }; -EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU); diff --git a/drivers/clk/sunxi-ng/ccu_sdm.c b/drivers/clk/sunxi-ng/ccu_sdm.c index 41937ed076..79581a1c64 100644 --- a/drivers/clk/sunxi-ng/ccu_sdm.c +++ b/drivers/clk/sunxi-ng/ccu_sdm.c @@ -20,7 +20,6 @@ bool ccu_sdm_helper_is_enabled(struct ccu_common *common, return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_is_enabled, SUNXI_CCU); void ccu_sdm_helper_enable(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -50,7 +49,6 @@ void ccu_sdm_helper_enable(struct ccu_common *common, writel(reg | sdm->enable, common->base + common->reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_enable, SUNXI_CCU); void ccu_sdm_helper_disable(struct ccu_common *common, struct ccu_sdm_internal *sdm) @@ -71,7 +69,6 @@ void ccu_sdm_helper_disable(struct ccu_common *common, writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg); spin_unlock_irqrestore(common->lock, flags); } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_disable, SUNXI_CCU); /* * Sigma delta modulation provides a way to do fractional-N frequency @@ -105,7 +102,6 @@ bool ccu_sdm_helper_has_rate(struct ccu_common *common, return false; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_has_rate, SUNXI_CCU); unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -136,7 +132,6 @@ unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common, /* We can't calculate the effective clock rate, so just fail. */ return 0; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_read_rate, SUNXI_CCU); int ccu_sdm_helper_get_factors(struct ccu_common *common, struct ccu_sdm_internal *sdm, @@ -158,4 +153,3 @@ int ccu_sdm_helper_get_factors(struct ccu_common *common, /* nothing found */ return -EINVAL; } -EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_get_factors, SUNXI_CCU); diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 51800289ad..f9d715ec99 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -88,12 +88,14 @@ CLK_OF_DECLARE_DRIVER(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct resource *r; void __iomem *reg; if (!np) return -ENODEV; - reg = devm_platform_ioremap_resource(pdev, 0); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index e4cf1180b0..4c75b0770c 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -40,6 +40,7 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) const struct gates_data *data; const char *clk_parent; const char *clk_name; + struct resource *r; void __iomem *reg; int ngates; int i; @@ -52,7 +53,8 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) if (!data) return -ENODEV; - reg = devm_platform_ioremap_resource(pdev, 0); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c index f80c67bafe..10f70c35c2 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0.c @@ -32,10 +32,12 @@ static int sun6i_a31_apb0_clk_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; const char *clk_name = np->name; const char *clk_parent; + struct resource *r; void __iomem *reg; struct clk *clk; - reg = devm_platform_ioremap_resource(pdev, 0); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 9f9a2cf54f..54babc2b4b 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -71,10 +71,12 @@ static DEFINE_SPINLOCK(sun6i_ar100_lock); static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct resource *r; void __iomem *reg; struct clk *clk; - reg = devm_platform_ioremap_resource(pdev, 0); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c index f605ecca87..fc5d6e3b77 100644 --- a/drivers/clk/sunxi/clk-sun8i-apb0.c +++ b/drivers/clk/sunxi/clk-sun8i-apb0.c @@ -87,10 +87,12 @@ CLK_OF_DECLARE_DRIVER(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk", static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct resource *r; void __iomem *reg; struct clk *clk; - reg = devm_platform_ioremap_resource(pdev, 0); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(reg)) return PTR_ERR(reg); diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile index a0715cdfc1..7b1816856e 100644 --- a/drivers/clk/tegra/Makefile +++ b/drivers/clk/tegra/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += clk.o obj-y += clk-audio-sync.o -obj-y += clk-device.o obj-y += clk-dfll.o obj-y += clk-divider.o obj-y += clk-periph.o diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 100b5d9b7e..eaa079c177 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1914,7 +1914,7 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll, /* Data in .init is copied by clk_register(), so stack variable OK */ pll->hw.init = &init; - return tegra_clk_dev_register(&pll->hw); + return clk_register(NULL, &pll->hw); } struct clk *tegra_clk_register_pll(const char *name, const char *parent_name, diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index a98a420398..6099c6e9ac 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -226,7 +226,7 @@ struct clk *tegra_clk_register_super_mux(const char *name, /* Data in .init is copied by clk_register(), so stack variable OK */ super->hw.init = &init; - clk = tegra_clk_dev_register(&super->hw); + clk = clk_register(NULL, &super->hw); if (IS_ERR(clk)) kfree(super); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index ef718c4b38..bc9e47a4cb 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -1158,7 +1158,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA114_CLK_XUSB_HS_SRC, TEGRA114_CLK_XUSB_SS_DIV2, 61200000, 0 }, { TEGRA114_CLK_XUSB_FALCON_SRC, TEGRA114_CLK_PLL_P, 204000000, 0 }, { TEGRA114_CLK_XUSB_HOST_SRC, TEGRA114_CLK_PLL_P, 102000000, 0 }, - { TEGRA114_CLK_VDE, TEGRA114_CLK_PLL_P, 408000000, 0 }, + { TEGRA114_CLK_VDE, TEGRA114_CLK_CLK_MAX, 600000000, 0 }, { TEGRA114_CLK_SPDIF_IN_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 }, { TEGRA114_CLK_I2S0_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 }, { TEGRA114_CLK_I2S1_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 }, diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index be3c33441c..3664593a5b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -6,11 +6,8 @@ #include #include #include -#include #include #include -#include -#include #include #include #include @@ -417,7 +414,7 @@ static struct tegra_clk_pll_params pll_e_params = { .fixed_rate = 100000000, }; -static struct tegra_devclk devclks[] = { +static struct tegra_devclk devclks[] __initdata = { { .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C }, { .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 }, { .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P }, @@ -713,6 +710,13 @@ static void tegra20_super_clk_init(void) NULL); clks[TEGRA20_CLK_CCLK] = clk; + /* SCLK */ + clk = tegra_clk_register_super_mux("sclk", sclk_parents, + ARRAY_SIZE(sclk_parents), + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); + clks[TEGRA20_CLK_SCLK] = clk; + /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4); clks[TEGRA20_CLK_TWD] = clk; @@ -1010,7 +1014,7 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = { #endif }; -static struct tegra_clk_init_table init_table[] = { +static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1 }, { TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1 }, { TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 }, @@ -1048,6 +1052,11 @@ static struct tegra_clk_init_table init_table[] = { { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 }, }; +static void __init tegra20_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); +} + /* * Some clocks may be used by different drivers depending on the board * configuration. List those here to register them twice in the clock lookup @@ -1067,8 +1076,6 @@ static const struct of_device_id pmc_match[] __initconst = { { }, }; -static bool tegra20_car_initialized; - static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) { @@ -1076,16 +1083,6 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, struct clk_hw *hw; struct clk *clk; - /* - * Timer clocks are needed early, the rest of the clocks shouldn't be - * available to device drivers until clock tree is fully initialized. - */ - if (clkspec->args[0] != TEGRA20_CLK_RTC && - clkspec->args[0] != TEGRA20_CLK_TWD && - clkspec->args[0] != TEGRA20_CLK_TIMER && - !tegra20_car_initialized) - return ERR_PTR(-EPROBE_DEFER); - clk = of_clk_src_onecell_get(clkspec, data); if (IS_ERR(clk)) return clk; @@ -1152,48 +1149,10 @@ static void __init tegra20_clock_init(struct device_node *np) tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX); tegra_add_of_provider(np, tegra20_clk_src_onecell_get); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); + + tegra_clk_apply_init_table = tegra20_clock_apply_init_table; tegra_cpu_car_ops = &tegra20_cpu_car_ops; } -CLK_OF_DECLARE_DRIVER(tegra20, "nvidia,tegra20-car", tegra20_clock_init); - -/* - * Clocks that use runtime PM can't be created at the tegra20_clock_init - * time because drivers' base isn't initialized yet, and thus platform - * devices can't be created for the clocks. Hence we need to split the - * registration of the clocks into two phases. The first phase registers - * essential clocks which don't require RPM and are actually used during - * early boot. The second phase registers clocks which use RPM and this - * is done when device drivers' core API is ready. - */ -static int tegra20_car_probe(struct platform_device *pdev) -{ - struct clk *clk; - - clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), - CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, - clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL); - clks[TEGRA20_CLK_SCLK] = clk; - - tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); - tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX); - tegra20_car_initialized = true; - - return 0; -} - -static const struct of_device_id tegra20_car_match[] = { - { .compatible = "nvidia,tegra20-car" }, - { } -}; - -static struct platform_driver tegra20_car_driver = { - .driver = { - .name = "tegra20-car", - .of_match_table = tegra20_car_match, - .suppress_bind_attrs = true, - }, - .probe = tegra20_car_probe, -}; -builtin_platform_driver(tegra20_car_driver); +CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 04b4961238..64121bc66d 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -7,11 +7,8 @@ #include #include #include -#include #include #include -#include -#include #include #include @@ -535,7 +532,7 @@ static unsigned long tegra30_input_freq[] = { [12] = 26000000, }; -static struct tegra_devclk devclks[] = { +static struct tegra_devclk devclks[] __initdata = { { .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C }, { .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 }, { .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P }, @@ -815,6 +812,11 @@ static void __init tegra30_pll_init(void) { struct clk *clk; + /* PLLC */ + clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, + &pll_c_params, NULL); + clks[TEGRA30_CLK_PLL_C] = clk; + /* PLLC_OUT1 */ clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c", clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP, @@ -824,6 +826,11 @@ static void __init tegra30_pll_init(void) 0, NULL); clks[TEGRA30_CLK_PLL_C_OUT1] = clk; + /* PLLM */ + clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, + CLK_SET_RATE_GATE, &pll_m_params, NULL); + clks[TEGRA30_CLK_PLL_M] = clk; + /* PLLM_OUT1 */ clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m", clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP, @@ -873,6 +880,9 @@ static void __init tegra30_pll_init(void) ARRAY_SIZE(pll_e_parents), CLK_SET_RATE_NO_REPARENT, clk_base + PLLE_AUX, 2, 1, 0, NULL); + clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, + CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); + clks[TEGRA30_CLK_PLL_E] = clk; } static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m", @@ -961,6 +971,14 @@ static void __init tegra30_super_clk_init(void) NULL); clks[TEGRA30_CLK_CCLK_LP] = clk; + /* SCLK */ + clk = tegra_clk_register_super_mux("sclk", sclk_parents, + ARRAY_SIZE(sclk_parents), + CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + clk_base + SCLK_BURST_POLICY, + 0, 4, 0, 0, NULL); + clks[TEGRA30_CLK_SCLK] = clk; + /* twd */ clk = clk_register_fixed_factor(NULL, "twd", "cclk_g", CLK_SET_RATE_PARENT, 1, 2); @@ -1196,7 +1214,7 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { #endif }; -static struct tegra_clk_init_table init_table[] = { +static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0 }, { TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0 }, { TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0 }, @@ -1241,6 +1259,11 @@ static struct tegra_clk_init_table init_table[] = { { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, }; +static void __init tegra30_clock_apply_init_table(void) +{ + tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); +} + /* * Some clocks may be used by different drivers depending on the board * configuration. List those here to register them twice in the clock lookup @@ -1271,24 +1294,12 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = { { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, }; -static bool tegra30_car_initialized; - static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) { struct clk_hw *hw; struct clk *clk; - /* - * Timer clocks are needed early, the rest of the clocks shouldn't be - * available to device drivers until clock tree is fully initialized. - */ - if (clkspec->args[0] != TEGRA30_CLK_RTC && - clkspec->args[0] != TEGRA30_CLK_TWD && - clkspec->args[0] != TEGRA30_CLK_TIMER && - !tegra30_car_initialized) - return ERR_PTR(-EPROBE_DEFER); - clk = of_clk_src_onecell_get(clkspec, data); if (IS_ERR(clk)) return clk; @@ -1346,75 +1357,10 @@ static void __init tegra30_clock_init(struct device_node *np) tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); tegra_add_of_provider(np, tegra30_clk_src_onecell_get); + tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); + + tegra_clk_apply_init_table = tegra30_clock_apply_init_table; tegra_cpu_car_ops = &tegra30_cpu_car_ops; } -CLK_OF_DECLARE_DRIVER(tegra30, "nvidia,tegra30-car", tegra30_clock_init); - -/* - * Clocks that use runtime PM can't be created at the tegra30_clock_init - * time because drivers' base isn't initialized yet, and thus platform - * devices can't be created for the clocks. Hence we need to split the - * registration of the clocks into two phases. The first phase registers - * essential clocks which don't require RPM and are actually used during - * early boot. The second phase registers clocks which use RPM and this - * is done when device drivers' core API is ready. - */ -static int tegra30_car_probe(struct platform_device *pdev) -{ - struct clk *clk; - - /* PLLC */ - clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0, - &pll_c_params, NULL); - clks[TEGRA30_CLK_PLL_C] = clk; - - /* PLLE */ - clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base, - CLK_GET_RATE_NOCACHE, &pll_e_params, NULL); - clks[TEGRA30_CLK_PLL_E] = clk; - - /* PLLM */ - clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base, - CLK_SET_RATE_GATE, &pll_m_params, NULL); - clks[TEGRA30_CLK_PLL_M] = clk; - - /* SCLK */ - clk = tegra_clk_register_super_mux("sclk", sclk_parents, - ARRAY_SIZE(sclk_parents), - CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, - clk_base + SCLK_BURST_POLICY, - 0, 4, 0, 0, NULL); - clks[TEGRA30_CLK_SCLK] = clk; - - tegra_register_devclks(devclks, ARRAY_SIZE(devclks)); - tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX); - tegra30_car_initialized = true; - - return 0; -} - -static const struct of_device_id tegra30_car_match[] = { - { .compatible = "nvidia,tegra30-car" }, - { } -}; - -static struct platform_driver tegra30_car_driver = { - .driver = { - .name = "tegra30-car", - .of_match_table = tegra30_car_match, - .suppress_bind_attrs = true, - }, - .probe = tegra30_car_probe, -}; - -/* - * Clock driver must be registered before memory controller driver, - * which doesn't support deferred probing for today and is registered - * from arch init-level. - */ -static int tegra30_car_init(void) -{ - return platform_driver_register(&tegra30_car_driver); -} -postcore_initcall(tegra30_car_init); +CLK_OF_DECLARE(tegra30, "nvidia,tegra30-car", tegra30_clock_init); diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 26bda45813..f6cdce441c 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -9,19 +9,14 @@ #include #include #include -#include #include -#include -#include #include -#include #include #include "clk.h" /* Global data of Tegra CPU CAR ops */ -static struct device_node *tegra_car_np; static struct tegra_cpu_car_ops dummy_car_ops; struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; @@ -266,8 +261,8 @@ void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, } } -void tegra_init_from_table(struct tegra_clk_init_table *tbl, - struct clk *clks[], int clk_max) +void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, + struct clk *clks[], int clk_max) { struct clk *clk; @@ -325,8 +320,6 @@ void __init tegra_add_of_provider(struct device_node *np, { int i; - tegra_car_np = np; - for (i = 0; i < clk_num; i++) { if (IS_ERR(clks[i])) { pr_err @@ -355,7 +348,7 @@ void __init tegra_init_special_resets(unsigned int num, special_reset_deassert = deassert; } -void tegra_register_devclks(struct tegra_devclk *dev_clks, int num) +void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) { int i; @@ -379,68 +372,6 @@ struct clk ** __init tegra_lookup_dt_id(int clk_id, return NULL; } -static struct device_node *tegra_clk_get_of_node(struct clk_hw *hw) -{ - struct device_node *np; - char *node_name; - - node_name = kstrdup(hw->init->name, GFP_KERNEL); - if (!node_name) - return NULL; - - strreplace(node_name, '_', '-'); - - for_each_child_of_node(tegra_car_np, np) { - if (!strcmp(np->name, node_name)) - break; - } - - kfree(node_name); - - return np; -} - -struct clk *tegra_clk_dev_register(struct clk_hw *hw) -{ - struct platform_device *pdev, *parent; - const char *dev_name = NULL; - struct device *dev = NULL; - struct device_node *np; - - np = tegra_clk_get_of_node(hw); - - if (!of_device_is_available(np)) - goto put_node; - - dev_name = kasprintf(GFP_KERNEL, "tegra_clk_%s", hw->init->name); - if (!dev_name) - goto put_node; - - parent = of_find_device_by_node(tegra_car_np); - if (parent) { - pdev = of_platform_device_create(np, dev_name, &parent->dev); - put_device(&parent->dev); - - if (!pdev) { - pr_err("%s: failed to create device for %pOF\n", - __func__, np); - goto free_name; - } - - dev = &pdev->dev; - pm_runtime_enable(dev); - } else { - WARN(1, "failed to find device for %pOF\n", tegra_car_np); - } - -free_name: - kfree(dev_name); -put_node: - of_node_put(np); - - return clk_register(dev, hw); -} - tegra_clk_apply_init_table_func tegra_clk_apply_init_table; static int __init tegra_clocks_apply_init_table(void) diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 5d80d8b79b..0c3ba0ccce 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -927,6 +927,4 @@ struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter); struct clk *tegra210_clk_register_emc(struct device_node *np, void __iomem *regs); -struct clk *tegra_clk_dev_register(struct clk_hw *hw); - #endif /* TEGRA_CLK_H */ diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index 962502ca7f..b341cd990b 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -807,7 +807,7 @@ static int ti_adpll_init_registers(struct ti_adpll_data *d) static int ti_adpll_init_inputs(struct ti_adpll_data *d) { - static const char error[] = "need at least %i inputs"; + const char *error = "need at least %i inputs"; struct clk *clock; int nr_inputs; diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 6e97a541cf..46c0add995 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -116,7 +116,6 @@ static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { { AM4_L3S_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, { AM4_L3S_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, { AM4_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, - { AM4_L3S_ADC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, { AM4_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" }, { AM4_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" }, { AM4_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index 46c66fac48..12380236d7 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c @@ -132,10 +132,6 @@ static const struct of_device_id uniphier_clk_match[] = { .compatible = "socionext,uniphier-pxs3-clock", .data = uniphier_pxs3_sys_clk_data, }, - { - .compatible = "socionext,uniphier-nx1-clock", - .data = uniphier_nx1_sys_clk_data, - }, /* Media I/O clock, SD clock */ { .compatible = "socionext,uniphier-ld4-mio-clock", @@ -169,10 +165,6 @@ static const struct of_device_id uniphier_clk_match[] = { .compatible = "socionext,uniphier-pxs3-sd-clock", .data = uniphier_pro5_sd_clk_data, }, - { - .compatible = "socionext,uniphier-nx1-sd-clock", - .data = uniphier_pro5_sd_clk_data, - }, /* Peripheral clock */ { .compatible = "socionext,uniphier-ld4-peri-clock", @@ -206,15 +198,6 @@ static const struct of_device_id uniphier_clk_match[] = { .compatible = "socionext,uniphier-pxs3-peri-clock", .data = uniphier_pro4_peri_clk_data, }, - { - .compatible = "socionext,uniphier-nx1-peri-clock", - .data = uniphier_pro4_peri_clk_data, - }, - /* SoC-glue clock */ - { - .compatible = "socionext,uniphier-pro4-sg-clock", - .data = uniphier_pro4_sg_clk_data, - }, { /* sentinel */ } }; diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c index 0180470b24..32b3017241 100644 --- a/drivers/clk/uniphier/clk-uniphier-sys.c +++ b/drivers/clk/uniphier/clk-uniphier-sys.c @@ -20,10 +20,6 @@ UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \ UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) -#define UNIPHIER_NX1_SYS_CLK_SD \ - UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 4), \ - UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 6) - #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 32), \ UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x2104, 2) @@ -292,8 +288,6 @@ const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x210c, 7), UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x210c, 8), UNIPHIER_CLK_GATE("sata-phy", 30, NULL, 0x210c, 21), - UNIPHIER_LD11_SYS_CLK_AIO(40), - UNIPHIER_LD11_SYS_CLK_EXIV(42), /* CPU gears */ UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), @@ -306,44 +300,3 @@ const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { "spll/4", "spll/8", "s2pll/4", "s2pll/8"), { /* sentinel */ } }; - -const struct uniphier_clk_data uniphier_nx1_sys_clk_data[] = { - UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 100, 1), /* ARM: 2500 MHz */ - UNIPHIER_CLK_FACTOR("spll", -1, "ref", 32, 1), /* 800 MHz */ - UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 6), - UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), - UNIPHIER_NX1_SYS_CLK_SD, - UNIPHIER_CLK_GATE("emmc", 4, NULL, 0x2108, 8), - UNIPHIER_CLK_GATE("ether", 6, NULL, 0x210c, 0), - UNIPHIER_CLK_GATE("usb30-0", 12, NULL, 0x210c, 16), /* =GIO */ - UNIPHIER_CLK_GATE("usb30-1", 13, NULL, 0x210c, 20), /* =GIO1P */ - UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x210c, 24), - UNIPHIER_CLK_GATE("usb30-ssphy0", 17, NULL, 0x210c, 25), - UNIPHIER_CLK_GATE("usb30-ssphy1", 18, NULL, 0x210c, 26), - UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 8), - UNIPHIER_CLK_GATE("voc", 52, NULL, 0x2110, 0), - UNIPHIER_CLK_GATE("hdmitx", 58, NULL, 0x2110, 8), - /* CPU gears */ - UNIPHIER_CLK_DIV5("cpll", 2, 4, 8, 16, 32), - UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 5, - "cpll/2", "cpll/4", "cpll/8", "cpll/16", - "cpll/32"), - { /* sentinel */ } -}; - -const struct uniphier_clk_data uniphier_pro4_sg_clk_data[] = { - UNIPHIER_CLK_DIV("gpll", 4), - { - .name = "sata-ref", - .type = UNIPHIER_CLK_TYPE_MUX, - .idx = 0, - .data.mux = { - .parent_names = { "gpll/4", "ref", }, - .num_parents = 2, - .reg = 0x1a28, - .masks = { 0x1, 0x1, }, - .vals = { 0x0, 0x1, }, - }, - }, - { /* sentinel */ } -}; diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h index dea0c7829a..9e30362e55 100644 --- a/drivers/clk/uniphier/clk-uniphier.h +++ b/drivers/clk/uniphier/clk-uniphier.h @@ -119,10 +119,6 @@ struct uniphier_clk_data { UNIPHIER_CLK_DIV2(parent, div0, div1), \ UNIPHIER_CLK_DIV2(parent, div2, div3) -#define UNIPHIER_CLK_DIV5(parent, div0, div1, div2, div3, div4) \ - UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3), \ - UNIPHIER_CLK_DIV(parent, div4) - struct clk_hw *uniphier_clk_register_cpugear(struct device *dev, struct regmap *regmap, const char *name, @@ -150,11 +146,9 @@ extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[]; extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[]; -extern const struct uniphier_clk_data uniphier_nx1_sys_clk_data[]; extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[]; extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[]; extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[]; extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[]; -extern const struct uniphier_clk_data uniphier_pro4_sg_clk_data[]; #endif /* __CLK_UNIPHIER_H__ */ diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile index c29b83df40..53fd290024 100644 --- a/drivers/clk/ux500/Makefile +++ b/drivers/clk/ux500/Makefile @@ -8,9 +8,6 @@ obj-y += clk-prcc.o obj-y += clk-prcmu.o obj-y += clk-sysctrl.o -# Reset control -obj-y += reset-prcc.o - # Clock definitions obj-y += u8500_of_clk.o diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index e86ed2eec3..528c5bb397 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -10,10 +10,10 @@ #include #include #include - #include "clk.h" -#include "prcc.h" -#include "reset-prcc.h" + +#define PRCC_NUM_PERIPH_CLUSTERS 6 +#define PRCC_PERIPHS_PER_CLUSTER 32 static struct clk *prcmu_clk[PRCMU_NUM_CLKS]; static struct clk *prcc_pclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_CLUSTER]; @@ -46,6 +46,16 @@ static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, return PRCC_SHOW(clk_data, base, bit); } +/* CLKRST4 is missing making it hard to index things */ +enum clkrst_index { + CLKRST1_INDEX = 0, + CLKRST2_INDEX, + CLKRST3_INDEX, + CLKRST5_INDEX, + CLKRST6_INDEX, + CLKRST_MAX, +}; + static void u8500_clk_init(struct device_node *np) { struct prcmu_fw_version *fw_version; @@ -53,18 +63,8 @@ static void u8500_clk_init(struct device_node *np) const char *sgaclk_parent = NULL; struct clk *clk, *rtc_clk, *twd_clk; u32 bases[CLKRST_MAX]; - struct u8500_prcc_reset *rstc; int i; - /* - * We allocate the reset controller here so that we can fill in the - * base addresses properly and pass to the reset controller init - * function later on. - */ - rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); - if (!rstc) - return; - for (i = 0; i < ARRAY_SIZE(bases); i++) { struct resource r; @@ -73,7 +73,6 @@ static void u8500_clk_init(struct device_node *np) pr_err("failed to get CLKRST %d base address\n", i + 1); bases[i] = r.start; - rstc->phy_base[i] = r.start; } /* Clock sources */ @@ -564,9 +563,6 @@ static void u8500_clk_init(struct device_node *np) if (of_node_name_eq(child, "smp-twd-clock")) of_clk_add_provider(child, of_clk_src_simple_get, twd_clk); - - if (of_node_name_eq(child, "prcc-reset-controller")) - u8500_prcc_reset_init(child, rstc); } } CLK_OF_DECLARE(u8500_clks, "stericsson,u8500-clks", u8500_clk_init); diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig index 403f164954..481de5657d 100644 --- a/drivers/clk/versatile/Kconfig +++ b/drivers/clk/versatile/Kconfig @@ -2,9 +2,8 @@ menu "Clock driver for ARM Reference designs" depends on HAS_IOMEM - depends on ARM || ARM64 || COMPILE_TEST -config CLK_ICST +config ICST bool "Clock driver for ARM Reference designs ICST" select REGMAP_MMIO help diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index e7d05308e4..4ff563e6e3 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only # Makefile for Versatile-specific clocks -obj-$(CONFIG_CLK_ICST) += icst.o clk-icst.o clk-versatile.o +obj-$(CONFIG_ICST) += icst.o clk-icst.o clk-versatile.o obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o obj-$(CONFIG_CLK_SP810) += clk-sp810.o obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index d5cb372f09..fdd6aa3cb1 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -484,7 +484,7 @@ static void __init of_syscon_icst_setup(struct device_node *np) struct device_node *parent; struct regmap *map; struct clk_icst_desc icst_desc; - const char *name; + const char *name = np->name; const char *parent_name; struct clk *regclk; enum icst_control_type ctype; @@ -501,8 +501,7 @@ static void __init of_syscon_icst_setup(struct device_node *np) return; } - if (of_property_read_u32(np, "reg", &icst_desc.vco_offset) && - of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) { + if (of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) { pr_err("no VCO register offset for ICST clock\n"); return; } @@ -533,18 +532,16 @@ static void __init of_syscon_icst_setup(struct device_node *np) icst_desc.params = &icst525_apcp_cm_params; ctype = ICST_INTEGRATOR_CP_CM_MEM; } else { - pr_err("unknown ICST clock %pOF\n", np); + pr_err("unknown ICST clock %s\n", name); return; } /* Parent clock name is not the same as node parent */ parent_name = of_clk_get_parent_name(np, 0); - name = kasprintf(GFP_KERNEL, "%pOFP", np); regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype); if (IS_ERR(regclk)) { pr_err("error setting up syscon ICST clock %s\n", name); - kfree(name); return; } of_clk_add_provider(np, of_clk_src_simple_get, regclk); diff --git a/drivers/clk/x86/clk-fch.c b/drivers/clk/x86/clk-fch.c index fdc060e758..8f7c5142b0 100644 --- a/drivers/clk/x86/clk-fch.c +++ b/drivers/clk/x86/clk-fch.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT /* - * clock framework for AMD FCH controller block + * clock framework for AMD Stoney based clocks * * Copyright 2018 Advanced Micro Devices, Inc. */ @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -27,37 +26,22 @@ #define ST_CLK_GATE 3 #define ST_MAX_CLKS 4 -#define CLK_48M_FIXED 0 -#define CLK_GATE_FIXED 1 -#define CLK_MAX_FIXED 2 - -/* List of supported CPU ids for clk mux with 25Mhz clk support */ -#define AMD_CPU_ID_ST 0x1576 +#define RV_CLK_48M 0 +#define RV_CLK_GATE 1 +#define RV_MAX_CLKS 2 static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" }; static struct clk_hw *hws[ST_MAX_CLKS]; -static const struct pci_device_id fch_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_ST) }, - { } -}; - static int fch_clk_probe(struct platform_device *pdev) { struct fch_clk_data *fch_data; - struct pci_dev *rdev; fch_data = dev_get_platdata(&pdev->dev); if (!fch_data || !fch_data->base) return -EINVAL; - rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); - if (!rdev) { - dev_err(&pdev->dev, "FCH device not found\n"); - return -ENODEV; - } - - if (pci_match_id(fch_pci_ids, rdev)) { + if (!fch_data->is_rv) { hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0, 48000000); hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz", @@ -75,38 +59,34 @@ static int fch_clk_probe(struct platform_device *pdev) OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL); devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE], - fch_data->name, NULL); + "oscout1", NULL); } else { - hws[CLK_48M_FIXED] = clk_hw_register_fixed_rate(NULL, "clk48MHz", + hws[RV_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0, 48000000); - hws[CLK_GATE_FIXED] = clk_hw_register_gate(NULL, "oscout1", + hws[RV_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "clk48MHz", 0, fch_data->base + MISCCLKCNTL1, - OSCCLKENB, 0, NULL); + OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL); - devm_clk_hw_register_clkdev(&pdev->dev, hws[CLK_GATE_FIXED], - fch_data->name, NULL); + devm_clk_hw_register_clkdev(&pdev->dev, hws[RV_CLK_GATE], + "oscout1", NULL); } - pci_dev_put(rdev); return 0; } static int fch_clk_remove(struct platform_device *pdev) { int i, clks; - struct pci_dev *rdev; + struct fch_clk_data *fch_data; - rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); - if (!rdev) - return -ENODEV; + fch_data = dev_get_platdata(&pdev->dev); - clks = pci_match_id(fch_pci_ids, rdev) ? CLK_MAX_FIXED : ST_MAX_CLKS; + clks = fch_data->is_rv ? RV_MAX_CLKS : ST_MAX_CLKS; for (i = 0; i < clks; i++) clk_hw_unregister(hws[i]); - pci_dev_put(rdev); return 0; } diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index e5f8fb704d..54f4184de8 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -12,7 +12,7 @@ #include /** - * struct zynq_pll - pll clock + * struct zynq_pll * @hw: Handle between common and hardware-specific interfaces * @pll_ctrl: PLL control register * @pll_status: PLL status register @@ -46,7 +46,7 @@ struct zynq_pll { * @hw: Handle between common and hardware-specific interfaces * @rate: Desired clock frequency * @prate: Clock frequency of parent clock - * Return: frequency closest to @rate the hardware can generate. + * Returns frequency closest to @rate the hardware can generate. */ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) @@ -66,7 +66,7 @@ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, * zynq_pll_recalc_rate() - Recalculate clock frequency * @hw: Handle between common and hardware-specific interfaces * @parent_rate: Clock frequency of parent clock - * Return: current clock frequency. + * Returns current clock frequency. */ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -87,7 +87,7 @@ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw, /** * zynq_pll_is_enabled - Check if a clock is enabled * @hw: Handle between common and hardware-specific interfaces - * Return: 1 if the clock is enabled, 0 otherwise. + * Returns 1 if the clock is enabled, 0 otherwise. * * Not sure this is a good idea, but since disabled means bypassed for * this clock implementation we say we are always enabled. @@ -110,7 +110,7 @@ static int zynq_pll_is_enabled(struct clk_hw *hw) /** * zynq_pll_enable - Enable clock * @hw: Handle between common and hardware-specific interfaces - * Return: 0 on success + * Returns 0 on success */ static int zynq_pll_enable(struct clk_hw *hw) { @@ -179,7 +179,7 @@ static const struct clk_ops zynq_pll_ops = { * @pll_status: Pointer to PLL status register * @lock_index: Bit index to this PLL's lock status bit in @pll_status * @lock: Register lock - * Return: handle to the registered clock. + * Returns handle to the registered clock. */ struct clk *clk_register_zynq_pll(const char *name, const char *parent, void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index cfb8ea0df3..08f8cb944a 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -419,14 +419,12 @@ config ATMEL_TCB_CLKSRC config CLKSRC_EXYNOS_MCT bool "Exynos multi core timer driver" if COMPILE_TEST depends on ARM || ARM64 - depends on ARCH_EXYNOS || COMPILE_TEST help Support for Multi Core Timer controller on Exynos SoCs. config CLKSRC_SAMSUNG_PWM bool "PWM timer driver for Samsung S3C, S5P" if COMPILE_TEST depends on HAS_IOMEM - depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 || COMPILE_TEST help This is a new clocksource driver for the PWM timer found in Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver @@ -510,8 +508,7 @@ config SH_TIMER_MTU2 This hardware comes with 16-bit timer registers. config RENESAS_OSTM - bool "Renesas OSTM timer driver" - depends on ARCH_RENESAS || COMPILE_TEST + bool "Renesas OSTM timer driver" if COMPILE_TEST select CLKSRC_MMIO select TIMER_OF help @@ -672,15 +669,6 @@ config MILBEAUT_TIMER help Enables the support for Milbeaut timer driver. -config MSC313E_TIMER - bool "MSC313E timer driver" if COMPILE_TEST - select TIMER_OF - select CLKSRC_MMIO - help - Enables support for the MStar MSC313E timer driver. - This provides access to multiple interrupt generating - programmable 32-bit free running incrementing counters. - config INGENIC_TIMER bool "Clocksource/timer using the TCU in Ingenic JZ SoCs" default MACH_INGENIC diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index fa5f624ead..c17ee32a71 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -88,4 +88,3 @@ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o -obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o diff --git a/drivers/clocksource/arc_timer.c b/drivers/clocksource/arc_timer.c index cb18524cc1..de93dd1a8c 100644 --- a/drivers/clocksource/arc_timer.c +++ b/drivers/clocksource/arc_timer.c @@ -225,7 +225,7 @@ static int __init arc_cs_setup_timer1(struct device_node *node) write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX); write_aux_reg(ARC_REG_TIMER1_CNT, 0); - write_aux_reg(ARC_REG_TIMER1_CTRL, ARC_TIMER_CTRL_NH); + write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH); sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq); @@ -245,7 +245,7 @@ static void arc_timer_event_setup(unsigned int cycles) write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles); write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */ - write_aux_reg(ARC_REG_TIMER0_CTRL, ARC_TIMER_CTRL_IE | ARC_TIMER_CTRL_NH); + write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH); } @@ -294,7 +294,7 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id) * explicitly clears IP bit * 2. Re-arm interrupt if periodic by writing to IE bit [0] */ - write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | ARC_TIMER_CTRL_NH); + write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH); evt->event_handler(evt); diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 1ecd52f903..be6d741d40 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -44,29 +44,23 @@ #define CNTACR_RWVT BIT(4) #define CNTACR_RWPT BIT(5) -#define CNTVCT_LO 0x00 -#define CNTPCT_LO 0x08 +#define CNTVCT_LO 0x08 +#define CNTVCT_HI 0x0c #define CNTFRQ 0x10 -#define CNTP_CVAL_LO 0x20 +#define CNTP_TVAL 0x28 #define CNTP_CTL 0x2c -#define CNTV_CVAL_LO 0x30 +#define CNTV_TVAL 0x38 #define CNTV_CTL 0x3c -/* - * The minimum amount of time a generic counter is guaranteed to not roll over - * (40 years) - */ -#define MIN_ROLLOVER_SECS (40ULL * 365 * 24 * 3600) - static unsigned arch_timers_present __initdata; +static void __iomem *arch_counter_base __ro_after_init; + struct arch_timer { void __iomem *base; struct clock_event_device evt; }; -static struct arch_timer *arch_timer_mem __ro_after_init; - #define to_arch_timer(e) container_of(e, struct arch_timer, evt) static u32 arch_timer_rate __ro_after_init; @@ -101,58 +95,33 @@ static int __init early_evtstrm_cfg(char *buf) } early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg); -/* - * Makes an educated guess at a valid counter width based on the Generic Timer - * specification. Of note: - * 1) the system counter is at least 56 bits wide - * 2) a roll-over time of not less than 40 years - * - * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details. - */ -static int arch_counter_get_width(void) -{ - u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate; - - /* guarantee the returned width is within the valid range */ - return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64); -} - /* * Architected system timer support. */ static __always_inline -void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val, +void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, struct clock_event_device *clk) { if (access == ARCH_TIMER_MEM_PHYS_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed((u32)val, timer->base + CNTP_CTL); + writel_relaxed(val, timer->base + CNTP_CTL); break; - case ARCH_TIMER_REG_CVAL: - /* - * Not guaranteed to be atomic, so the timer - * must be disabled at this point. - */ - writeq_relaxed(val, timer->base + CNTP_CVAL_LO); + case ARCH_TIMER_REG_TVAL: + writel_relaxed(val, timer->base + CNTP_TVAL); break; - default: - BUILD_BUG(); } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); switch (reg) { case ARCH_TIMER_REG_CTRL: - writel_relaxed((u32)val, timer->base + CNTV_CTL); + writel_relaxed(val, timer->base + CNTV_CTL); break; - case ARCH_TIMER_REG_CVAL: - /* Same restriction as above */ - writeq_relaxed(val, timer->base + CNTV_CVAL_LO); + case ARCH_TIMER_REG_TVAL: + writel_relaxed(val, timer->base + CNTV_TVAL); break; - default: - BUILD_BUG(); } } else { arch_timer_reg_write_cp15(access, reg, val); @@ -171,8 +140,9 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_CTRL: val = readl_relaxed(timer->base + CNTP_CTL); break; - default: - BUILD_BUG(); + case ARCH_TIMER_REG_TVAL: + val = readl_relaxed(timer->base + CNTP_TVAL); + break; } } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { struct arch_timer *timer = to_arch_timer(clk); @@ -180,8 +150,9 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, case ARCH_TIMER_REG_CTRL: val = readl_relaxed(timer->base + CNTV_CTL); break; - default: - BUILD_BUG(); + case ARCH_TIMER_REG_TVAL: + val = readl_relaxed(timer->base + CNTV_TVAL); + break; } } else { val = arch_timer_reg_read_cp15(access, reg); @@ -234,11 +205,13 @@ static struct clocksource clocksource_counter = { .id = CSID_ARM_ARCH_COUNTER, .rating = 400, .read = arch_counter_read, + .mask = CLOCKSOURCE_MASK(56), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static struct cyclecounter cyclecounter __ro_after_init = { .read = arch_counter_read_cc, + .mask = CLOCKSOURCE_MASK(56), }; struct ate_acpi_oem_info { @@ -266,6 +239,16 @@ struct ate_acpi_oem_info { _new; \ }) +static u32 notrace fsl_a008585_read_cntp_tval_el0(void) +{ + return __fsl_a008585_read_reg(cntp_tval_el0); +} + +static u32 notrace fsl_a008585_read_cntv_tval_el0(void) +{ + return __fsl_a008585_read_reg(cntv_tval_el0); +} + static u64 notrace fsl_a008585_read_cntpct_el0(void) { return __fsl_a008585_read_reg(cntpct_el0); @@ -302,6 +285,16 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void) _new; \ }) +static u32 notrace hisi_161010101_read_cntp_tval_el0(void) +{ + return __hisi_161010101_read_reg(cntp_tval_el0); +} + +static u32 notrace hisi_161010101_read_cntv_tval_el0(void) +{ + return __hisi_161010101_read_reg(cntv_tval_el0); +} + static u64 notrace hisi_161010101_read_cntpct_el0(void) { return __hisi_161010101_read_reg(cntpct_el0); @@ -386,6 +379,16 @@ static u64 notrace sun50i_a64_read_cntvct_el0(void) { return __sun50i_a64_read_reg(cntvct_el0); } + +static u32 notrace sun50i_a64_read_cntp_tval_el0(void) +{ + return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0(); +} + +static u32 notrace sun50i_a64_read_cntv_tval_el0(void) +{ + return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0(); +} #endif #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND @@ -394,13 +397,8 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0); -/* - * Force the inlining of this function so that the register accesses - * can be themselves correctly inlined. - */ -static __always_inline -void erratum_set_next_event_generic(const int access, unsigned long evt, - struct clock_event_device *clk) +static void erratum_set_next_event_tval_generic(const int access, unsigned long evt, + struct clock_event_device *clk) { unsigned long ctrl; u64 cval; @@ -420,17 +418,17 @@ void erratum_set_next_event_generic(const int access, unsigned long evt, arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); } -static __maybe_unused int erratum_set_next_event_virt(unsigned long evt, +static __maybe_unused int erratum_set_next_event_tval_virt(unsigned long evt, struct clock_event_device *clk) { - erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk); + erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk); return 0; } -static __maybe_unused int erratum_set_next_event_phys(unsigned long evt, +static __maybe_unused int erratum_set_next_event_tval_phys(unsigned long evt, struct clock_event_device *clk) { - erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk); + erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk); return 0; } @@ -440,10 +438,12 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "fsl,erratum-a008585", .desc = "Freescale erratum a005858", + .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0, + .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0, .read_cntpct_el0 = fsl_a008585_read_cntpct_el0, .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_phys, - .set_next_event_virt = erratum_set_next_event_virt, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, }, #endif #ifdef CONFIG_HISILICON_ERRATUM_161010101 @@ -451,19 +451,23 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "hisilicon,erratum-161010101", .desc = "HiSilicon erratum 161010101", + .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, + .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_phys, - .set_next_event_virt = erratum_set_next_event_virt, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, }, { .match_type = ate_match_acpi_oem_info, .id = hisi_161010101_oem_info, .desc = "HiSilicon erratum 161010101", + .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, + .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, .read_cntpct_el0 = hisi_161010101_read_cntpct_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_phys, - .set_next_event_virt = erratum_set_next_event_virt, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, }, #endif #ifdef CONFIG_ARM64_ERRATUM_858921 @@ -480,10 +484,12 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { .match_type = ate_match_dt, .id = "allwinner,erratum-unknown1", .desc = "Allwinner erratum UNKNOWN1", + .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0, + .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0, .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, - .set_next_event_phys = erratum_set_next_event_phys, - .set_next_event_virt = erratum_set_next_event_virt, + .set_next_event_phys = erratum_set_next_event_tval_phys, + .set_next_event_virt = erratum_set_next_event_tval_virt, }, #endif #ifdef CONFIG_ARM64_ERRATUM_1418040 @@ -721,18 +727,10 @@ static __always_inline void set_next_event(const int access, unsigned long evt, struct clock_event_device *clk) { unsigned long ctrl; - u64 cnt; - ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; - - if (access == ARCH_TIMER_PHYS_ACCESS) - cnt = __arch_counter_get_cntpct(); - else - cnt = __arch_counter_get_cntvct(); - - arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk); + arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); } @@ -750,79 +748,23 @@ static int arch_timer_set_next_event_phys(unsigned long evt, return 0; } -static u64 arch_counter_get_cnt_mem(struct arch_timer *t, int offset_lo) -{ - u32 cnt_lo, cnt_hi, tmp_hi; - - do { - cnt_hi = readl_relaxed(t->base + offset_lo + 4); - cnt_lo = readl_relaxed(t->base + offset_lo); - tmp_hi = readl_relaxed(t->base + offset_lo + 4); - } while (cnt_hi != tmp_hi); - - return ((u64) cnt_hi << 32) | cnt_lo; -} - -static __always_inline void set_next_event_mem(const int access, unsigned long evt, - struct clock_event_device *clk) -{ - struct arch_timer *timer = to_arch_timer(clk); - unsigned long ctrl; - u64 cnt; - - ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); - ctrl |= ARCH_TIMER_CTRL_ENABLE; - ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; - - if (access == ARCH_TIMER_MEM_VIRT_ACCESS) - cnt = arch_counter_get_cnt_mem(timer, CNTVCT_LO); - else - cnt = arch_counter_get_cnt_mem(timer, CNTPCT_LO); - - arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk); - arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); -} - static int arch_timer_set_next_event_virt_mem(unsigned long evt, struct clock_event_device *clk) { - set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk); + set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk); return 0; } static int arch_timer_set_next_event_phys_mem(unsigned long evt, struct clock_event_device *clk) { - set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk); + set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk); return 0; } -static u64 __arch_timer_check_delta(void) -{ -#ifdef CONFIG_ARM64 - const struct midr_range broken_cval_midrs[] = { - /* - * XGene-1 implements CVAL in terms of TVAL, meaning - * that the maximum timer range is 32bit. Shame on them. - */ - MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, - APM_CPU_PART_POTENZA)), - {}, - }; - - if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) { - pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits"); - return CLOCKSOURCE_MASK(32); - } -#endif - return CLOCKSOURCE_MASK(arch_counter_get_width()); -} - static void __arch_timer_setup(unsigned type, struct clock_event_device *clk) { - u64 max_delta; - clk->features = CLOCK_EVT_FEAT_ONESHOT; if (type == ARCH_TIMER_TYPE_CP15) { @@ -854,7 +796,6 @@ static void __arch_timer_setup(unsigned type, } clk->set_next_event = sne; - max_delta = __arch_timer_check_delta(); } else { clk->features |= CLOCK_EVT_FEAT_DYNIRQ; clk->name = "arch_mem_timer"; @@ -871,13 +812,11 @@ static void __arch_timer_setup(unsigned type, clk->set_next_event = arch_timer_set_next_event_phys_mem; } - - max_delta = CLOCKSOURCE_MASK(56); } clk->set_state_shutdown(clk); - clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta); + clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); } static void arch_timer_evtstrm_enable(int divider) @@ -1047,7 +986,15 @@ bool arch_timer_evtstrm_available(void) static u64 arch_counter_get_cntvct_mem(void) { - return arch_counter_get_cnt_mem(arch_timer_mem, CNTVCT_LO); + u32 vct_lo, vct_hi, tmp_hi; + + do { + vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); + vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO); + tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); + } while (vct_hi != tmp_hi); + + return ((u64) vct_hi << 32) | vct_lo; } static struct arch_timer_kvm_info arch_timer_kvm_info; @@ -1060,7 +1007,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; - int width; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -1085,10 +1031,6 @@ static void __init arch_counter_register(unsigned type) arch_timer_read_counter = arch_counter_get_cntvct_mem; } - width = arch_counter_get_width(); - clocksource_counter.mask = CLOCKSOURCE_MASK(width); - cyclecounter.mask = CLOCKSOURCE_MASK(width); - if (!arch_counter_suspend_stop) clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; start_count = arch_timer_read_counter(); @@ -1098,7 +1040,8 @@ static void __init arch_counter_register(unsigned type) timecounter_init(&arch_timer_kvm_info.timecounter, &cyclecounter, start_count); - sched_clock_register(arch_timer_read_counter, width, arch_timer_rate); + /* 56 bits minimum, so we assume worst case rollover */ + sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate); } static void arch_timer_stop(struct clock_event_device *clk) @@ -1239,25 +1182,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq) { int ret; irq_handler_t func; + struct arch_timer *t; - arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL); - if (!arch_timer_mem) + t = kzalloc(sizeof(*t), GFP_KERNEL); + if (!t) return -ENOMEM; - arch_timer_mem->base = base; - arch_timer_mem->evt.irq = irq; - __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt); + t->base = base; + t->evt.irq = irq; + __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt); if (arch_timer_mem_use_virtual) func = arch_timer_handler_virt_mem; else func = arch_timer_handler_phys_mem; - ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt); + ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt); if (ret) { pr_err("Failed to request mem timer irq\n"); - kfree(arch_timer_mem); - arch_timer_mem = NULL; + kfree(t); } return ret; @@ -1515,6 +1458,7 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame) return ret; } + arch_counter_base = base; arch_timers_present |= ARCH_TIMER_TYPE_MEM; return 0; diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 6db3d5511b..5e3e96d3d1 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -467,7 +467,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu) evt->tick_resume = set_state_shutdown; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERCPU; - evt->rating = MCT_CLKEVENTS_RATING; + evt->rating = MCT_CLKEVENTS_RATING, exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); @@ -504,14 +504,11 @@ static int exynos4_mct_dying_cpu(unsigned int cpu) return 0; } -static int __init exynos4_timer_resources(struct device_node *np) +static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base) { + int err, cpu; struct clk *mct_clk, *tick_clk; - reg_base = of_iomap(np, 0); - if (!reg_base) - panic("%s: unable to ioremap mct address space\n", __func__); - tick_clk = of_clk_get_by_name(np, "fin_pll"); if (IS_ERR(tick_clk)) panic("%s: unable to determine tick clock rate\n", __func__); @@ -522,27 +519,9 @@ static int __init exynos4_timer_resources(struct device_node *np) panic("%s: unable to retrieve mct clock instance\n", __func__); clk_prepare_enable(mct_clk); - return 0; -} - -static int __init exynos4_timer_interrupts(struct device_node *np, - unsigned int int_type) -{ - int nr_irqs, i, err, cpu; - - mct_int_type = int_type; - - /* This driver uses only one global timer interrupt */ - mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); - - /* - * Find out the number of local irqs specified. The local - * timer irqs are specified after the four global timer - * irqs are specified. - */ - nr_irqs = of_irq_count(np); - for (i = MCT_L0_IRQ; i < nr_irqs; i++) - mct_irqs[i] = irq_of_parse_and_map(np, i); + reg_base = base; + if (!reg_base) + panic("%s: unable to ioremap mct address space\n", __func__); if (mct_int_type == MCT_INT_PPI) { @@ -602,13 +581,24 @@ static int __init exynos4_timer_interrupts(struct device_node *np, static int __init mct_init_dt(struct device_node *np, unsigned int int_type) { + u32 nr_irqs, i; int ret; - ret = exynos4_timer_resources(np); - if (ret) - return ret; + mct_int_type = int_type; - ret = exynos4_timer_interrupts(np, int_type); + /* This driver uses only one global timer interrupt */ + mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); + + /* + * Find out the number of local irqs specified. The local + * timer irqs are specified after the four global timer + * irqs are specified. + */ + nr_irqs = of_irq_count(np); + for (i = MCT_L0_IRQ; i < nr_irqs; i++) + mct_irqs[i] = irq_of_parse_and_map(np, i); + + ret = exynos4_timer_resources(np, of_iomap(np, 0)); if (ret) return ret; diff --git a/drivers/clocksource/renesas-ostm.c b/drivers/clocksource/renesas-ostm.c index 21d1392637..3d06ba6600 100644 --- a/drivers/clocksource/renesas-ostm.c +++ b/drivers/clocksource/renesas-ostm.c @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include @@ -161,7 +159,6 @@ static int __init ostm_init_clkevt(struct timer_of *to) static int __init ostm_init(struct device_node *np) { - struct reset_control *rstc; struct timer_of *to; int ret; @@ -169,14 +166,6 @@ static int __init ostm_init(struct device_node *np) if (!to) return -ENOMEM; - rstc = of_reset_control_get_optional_exclusive(np, NULL); - if (IS_ERR(rstc)) { - ret = PTR_ERR(rstc); - goto err_free; - } - - reset_control_deassert(rstc); - to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK; if (system_clock) { /* @@ -189,7 +178,7 @@ static int __init ostm_init(struct device_node *np) ret = timer_of_init(np, to); if (ret) - goto err_reset; + goto err_free; /* * First probed device will be used as system clocksource. Any @@ -214,35 +203,9 @@ static int __init ostm_init(struct device_node *np) err_cleanup: timer_of_cleanup(to); -err_reset: - reset_control_assert(rstc); - reset_control_put(rstc); err_free: kfree(to); return ret; } TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init); - -#ifdef CONFIG_ARCH_R9A07G044 -static int __init ostm_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - return ostm_init(dev->of_node); -} - -static const struct of_device_id ostm_of_table[] = { - { .compatible = "renesas,ostm", }, - { /* sentinel */ } -}; - -static struct platform_driver ostm_device_driver = { - .driver = { - .name = "renesas_ostm", - .of_match_table = of_match_ptr(ostm_of_table), - .suppress_bind_attrs = true, - }, -}; -builtin_platform_driver_probe(ostm_device_driver, ostm_probe); -#endif diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index 55a8e198d2..18b90fc56b 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -20,8 +20,8 @@ #define SYS_CTR_CLK_DIV 0x3 -static void __iomem *sys_ctr_base __ro_after_init; -static u32 cmpcr __ro_after_init; +static void __iomem *sys_ctr_base; +static u32 cmpcr; static void sysctr_timer_enable(bool enable) { @@ -119,7 +119,7 @@ static struct timer_of to_sysctr = { static void __init sysctr_clockevent_init(void) { - to_sysctr.clkevt.cpumask = cpu_possible_mask; + to_sysctr.clkevt.cpumask = cpumask_of(0); clockevents_config_and_register(&to_sysctr.clkevt, timer_of_rate(&to_sysctr), diff --git a/drivers/clocksource/timer-pistachio.c b/drivers/clocksource/timer-pistachio.c index 69c069e6f0..6f37181a8c 100644 --- a/drivers/clocksource/timer-pistachio.c +++ b/drivers/clocksource/timer-pistachio.c @@ -71,8 +71,7 @@ static u64 notrace pistachio_clocksource_read_cycles(struct clocksource *cs) { struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); - __maybe_unused u32 overflow; - u32 counter; + u32 counter, overflow; unsigned long flags; /* diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index 1767f8bf20..c51c5ed15a 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -13,12 +13,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -81,13 +79,6 @@ static int riscv_timer_dying_cpu(unsigned int cpu) return 0; } -void riscv_cs_get_mult_shift(u32 *mult, u32 *shift) -{ - *mult = riscv_clocksource.mult; - *shift = riscv_clocksource.shift; -} -EXPORT_SYMBOL_GPL(riscv_cs_get_mult_shift); - /* called directly from the low-level interrupt handler */ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id) { diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c index 5c40ca1d47..1fccb457fc 100644 --- a/drivers/clocksource/timer-ti-dm-systimer.c +++ b/drivers/clocksource/timer-ti-dm-systimer.c @@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void) bool quirk_unreliable_oscillator = false; /* Quirk unreliable 32 KiHz oscillator with incomplete dts */ - if (of_machine_is_compatible("ti,omap3-beagle-ab4") || - of_machine_is_compatible("timll,omap3-devkit8000")) { + if (of_machine_is_compatible("ti,omap3-beagle-ab4")) { quirk_unreliable_oscillator = true; counter_32k = -ENODEV; } diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index ccac1c4530..646ad385e4 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -358,7 +358,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, * other namespaces. */ if ((current_user_ns() != &init_user_ns) || - !task_is_in_init_pid_ns(current)) + (task_active_pid_ns(current) != &init_pid_ns)) return; /* Can only change if privileged. */ diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c index a17e51d65a..0caa60537b 100644 --- a/drivers/counter/104-quad-8.c +++ b/drivers/counter/104-quad-8.c @@ -11,14 +11,11 @@ #include #include #include -#include #include #include -#include #include #include #include -#include #define QUAD8_EXTENT 32 @@ -27,10 +24,6 @@ static unsigned int num_quad8; module_param_hw_array(base, uint, ioport, &num_quad8, 0); MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses"); -static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)]; -module_param_hw_array(irq, uint, irq, NULL, 0); -MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers"); - #define QUAD8_NUM_COUNTERS 8 /** @@ -44,14 +37,14 @@ MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers"); * @quadrature_scale: array of quadrature mode scale configurations * @ab_enable: array of A and B inputs enable configurations * @preset_enable: array of set_to_preset_on_index attribute configurations - * @irq_trigger: array of current IRQ trigger function configurations * @synchronous_mode: array of index function synchronous mode configurations * @index_polarity: array of index function polarity configurations * @cable_fault_enable: differential encoder cable status enable configurations * @base: base port address of the device */ struct quad8 { - spinlock_t lock; + struct mutex lock; + struct counter_device counter; unsigned int fck_prescaler[QUAD8_NUM_COUNTERS]; unsigned int preset[QUAD8_NUM_COUNTERS]; unsigned int count_mode[QUAD8_NUM_COUNTERS]; @@ -59,16 +52,13 @@ struct quad8 { unsigned int quadrature_scale[QUAD8_NUM_COUNTERS]; unsigned int ab_enable[QUAD8_NUM_COUNTERS]; unsigned int preset_enable[QUAD8_NUM_COUNTERS]; - unsigned int irq_trigger[QUAD8_NUM_COUNTERS]; unsigned int synchronous_mode[QUAD8_NUM_COUNTERS]; unsigned int index_polarity[QUAD8_NUM_COUNTERS]; unsigned int cable_fault_enable; unsigned int base; }; -#define QUAD8_REG_INTERRUPT_STATUS 0x10 #define QUAD8_REG_CHAN_OP 0x11 -#define QUAD8_REG_INDEX_INTERRUPT 0x12 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17 /* Borrow Toggle flip-flop */ @@ -101,8 +91,8 @@ struct quad8 { #define QUAD8_RLD_CNTR_OUT 0x10 /* Transfer Preset Register LSB to FCK Prescaler */ #define QUAD8_RLD_PRESET_PSC 0x18 +#define QUAD8_CHAN_OP_ENABLE_COUNTERS 0x00 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01 -#define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04 #define QUAD8_CMR_QUADRATURE_X1 0x08 #define QUAD8_CMR_QUADRATURE_X2 0x10 #define QUAD8_CMR_QUADRATURE_X4 0x18 @@ -111,7 +101,7 @@ static int quad8_signal_read(struct counter_device *counter, struct counter_signal *signal, enum counter_signal_level *level) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; unsigned int state; /* Only Index signal levels can be read */ @@ -127,14 +117,13 @@ static int quad8_signal_read(struct counter_device *counter, } static int quad8_count_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, unsigned long *val) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; unsigned int flags; unsigned int borrow; unsigned int carry; - unsigned long irqflags; int i; flags = inb(base_offset + 1); @@ -144,7 +133,7 @@ static int quad8_count_read(struct counter_device *counter, /* Borrow XOR Carry effectively doubles count range */ *val = (unsigned long)(borrow ^ carry) << 24; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); /* Reset Byte Pointer; transfer Counter to Output Latch */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT, @@ -153,24 +142,23 @@ static int quad8_count_read(struct counter_device *counter, for (i = 0; i < 3; i++) *val |= (unsigned long)inb(base_offset) << (8 * i); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } static int quad8_count_write(struct counter_device *counter, - struct counter_count *count, u64 val) + struct counter_count *count, unsigned long val) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; - unsigned long irqflags; int i; /* Only 24-bit values are supported */ if (val > 0xFFFFFF) return -ERANGE; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); /* Reset Byte Pointer */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); @@ -195,68 +183,71 @@ static int quad8_count_write(struct counter_device *counter, /* Reset Error flag */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } -static const enum counter_function quad8_count_functions_list[] = { - COUNTER_FUNCTION_PULSE_DIRECTION, - COUNTER_FUNCTION_QUADRATURE_X1_A, - COUNTER_FUNCTION_QUADRATURE_X2_A, - COUNTER_FUNCTION_QUADRATURE_X4, +enum quad8_count_function { + QUAD8_COUNT_FUNCTION_PULSE_DIRECTION = 0, + QUAD8_COUNT_FUNCTION_QUADRATURE_X1, + QUAD8_COUNT_FUNCTION_QUADRATURE_X2, + QUAD8_COUNT_FUNCTION_QUADRATURE_X4 }; -static int quad8_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) -{ - struct quad8 *const priv = counter_priv(counter); - const int id = count->id; - unsigned long irqflags; +static const enum counter_function quad8_count_functions_list[] = { + [QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_FUNCTION_PULSE_DIRECTION, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_FUNCTION_QUADRATURE_X1_A, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_FUNCTION_QUADRATURE_X2_A, + [QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_FUNCTION_QUADRATURE_X4 +}; - spin_lock_irqsave(&priv->lock, irqflags); +static int quad8_function_get(struct counter_device *counter, + struct counter_count *count, size_t *function) +{ + struct quad8 *const priv = counter->priv; + const int id = count->id; + + mutex_lock(&priv->lock); if (priv->quadrature_mode[id]) switch (priv->quadrature_scale[id]) { case 0: - *function = COUNTER_FUNCTION_QUADRATURE_X1_A; + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1; break; case 1: - *function = COUNTER_FUNCTION_QUADRATURE_X2_A; + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X2; break; case 2: - *function = COUNTER_FUNCTION_QUADRATURE_X4; + *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X4; break; } else - *function = COUNTER_FUNCTION_PULSE_DIRECTION; + *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION; - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } -static int quad8_function_write(struct counter_device *counter, - struct counter_count *count, - enum counter_function function) +static int quad8_function_set(struct counter_device *counter, + struct counter_count *count, size_t function) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const int id = count->id; unsigned int *const quadrature_mode = priv->quadrature_mode + id; unsigned int *const scale = priv->quadrature_scale + id; unsigned int *const synchronous_mode = priv->synchronous_mode + id; const int base_offset = priv->base + 2 * id + 1; - unsigned long irqflags; unsigned int mode_cfg; unsigned int idr_cfg; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); mode_cfg = priv->count_mode[id] << 1; idr_cfg = priv->index_polarity[id] << 1; - if (function == COUNTER_FUNCTION_PULSE_DIRECTION) { + if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) { *quadrature_mode = 0; /* Quadrature scaling only available in quadrature mode */ @@ -272,21 +263,21 @@ static int quad8_function_write(struct counter_device *counter, *quadrature_mode = 1; switch (function) { - case COUNTER_FUNCTION_QUADRATURE_X1_A: + case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: *scale = 0; mode_cfg |= QUAD8_CMR_QUADRATURE_X1; break; - case COUNTER_FUNCTION_QUADRATURE_X2_A: + case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: *scale = 1; mode_cfg |= QUAD8_CMR_QUADRATURE_X2; break; - case COUNTER_FUNCTION_QUADRATURE_X4: + case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: *scale = 2; mode_cfg |= QUAD8_CMR_QUADRATURE_X4; break; default: /* should never reach this path */ - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return -EINVAL; } } @@ -294,16 +285,15 @@ static int quad8_function_write(struct counter_device *counter, /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } -static int quad8_direction_read(struct counter_device *counter, - struct counter_count *count, - enum counter_count_direction *direction) +static void quad8_direction_get(struct counter_device *counter, + struct counter_count *count, enum counter_count_direction *direction) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; unsigned int ud_flag; const unsigned int flag_addr = priv->base + 2 * count->id + 1; @@ -312,74 +302,76 @@ static int quad8_direction_read(struct counter_device *counter, *direction = (ud_flag) ? COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD; - - return 0; } +enum quad8_synapse_action { + QUAD8_SYNAPSE_ACTION_NONE = 0, + QUAD8_SYNAPSE_ACTION_RISING_EDGE, + QUAD8_SYNAPSE_ACTION_FALLING_EDGE, + QUAD8_SYNAPSE_ACTION_BOTH_EDGES +}; + static const enum counter_synapse_action quad8_index_actions_list[] = { - COUNTER_SYNAPSE_ACTION_NONE, - COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE }; static const enum counter_synapse_action quad8_synapse_actions_list[] = { - COUNTER_SYNAPSE_ACTION_NONE, - COUNTER_SYNAPSE_ACTION_RISING_EDGE, - COUNTER_SYNAPSE_ACTION_FALLING_EDGE, - COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + [QUAD8_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [QUAD8_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [QUAD8_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + [QUAD8_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES }; -static int quad8_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int quad8_action_get(struct counter_device *counter, + struct counter_count *count, struct counter_synapse *synapse, + size_t *action) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; int err; - enum counter_function function; + size_t function = 0; const size_t signal_a_id = count->synapses[0].signal->id; enum counter_count_direction direction; /* Handle Index signals */ if (synapse->signal->id >= 16) { if (priv->preset_enable[count->id]) - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; else - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = QUAD8_SYNAPSE_ACTION_NONE; return 0; } - err = quad8_function_read(counter, count, &function); + err = quad8_function_get(counter, count, &function); if (err) return err; /* Default action mode */ - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = QUAD8_SYNAPSE_ACTION_NONE; /* Determine action mode based on current count function mode */ switch (function) { - case COUNTER_FUNCTION_PULSE_DIRECTION: + case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION: if (synapse->signal->id == signal_a_id) - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; return 0; - case COUNTER_FUNCTION_QUADRATURE_X1_A: + case QUAD8_COUNT_FUNCTION_QUADRATURE_X1: if (synapse->signal->id == signal_a_id) { - err = quad8_direction_read(counter, count, &direction); - if (err) - return err; + quad8_direction_get(counter, count, &direction); if (direction == COUNTER_COUNT_DIRECTION_FORWARD) - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = QUAD8_SYNAPSE_ACTION_RISING_EDGE; else - *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; + *action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE; } return 0; - case COUNTER_FUNCTION_QUADRATURE_X2_A: + case QUAD8_COUNT_FUNCTION_QUADRATURE_X2: if (synapse->signal->id == signal_a_id) - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; return 0; - case COUNTER_FUNCTION_QUADRATURE_X4: - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + case QUAD8_COUNT_FUNCTION_QUADRATURE_X4: + *action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES; return 0; default: /* should never reach this path */ @@ -387,102 +379,13 @@ static int quad8_action_read(struct counter_device *counter, } } -enum { - QUAD8_EVENT_CARRY = 0, - QUAD8_EVENT_COMPARE = 1, - QUAD8_EVENT_CARRY_BORROW = 2, - QUAD8_EVENT_INDEX = 3, -}; - -static int quad8_events_configure(struct counter_device *counter) -{ - struct quad8 *const priv = counter_priv(counter); - unsigned long irq_enabled = 0; - unsigned long irqflags; - struct counter_event_node *event_node; - unsigned int next_irq_trigger; - unsigned long ior_cfg; - unsigned long base_offset; - - spin_lock_irqsave(&priv->lock, irqflags); - - list_for_each_entry(event_node, &counter->events_list, l) { - switch (event_node->event) { - case COUNTER_EVENT_OVERFLOW: - next_irq_trigger = QUAD8_EVENT_CARRY; - break; - case COUNTER_EVENT_THRESHOLD: - next_irq_trigger = QUAD8_EVENT_COMPARE; - break; - case COUNTER_EVENT_OVERFLOW_UNDERFLOW: - next_irq_trigger = QUAD8_EVENT_CARRY_BORROW; - break; - case COUNTER_EVENT_INDEX: - next_irq_trigger = QUAD8_EVENT_INDEX; - break; - default: - /* should never reach this path */ - spin_unlock_irqrestore(&priv->lock, irqflags); - return -EINVAL; - } - - /* Skip configuration if it is the same as previously set */ - if (priv->irq_trigger[event_node->channel] == next_irq_trigger) - continue; - - /* Save new IRQ function configuration */ - priv->irq_trigger[event_node->channel] = next_irq_trigger; - - /* Load configuration to I/O Control Register */ - ior_cfg = priv->ab_enable[event_node->channel] | - priv->preset_enable[event_node->channel] << 1 | - priv->irq_trigger[event_node->channel] << 3; - base_offset = priv->base + 2 * event_node->channel + 1; - outb(QUAD8_CTR_IOR | ior_cfg, base_offset); - - /* Enable IRQ line */ - irq_enabled |= BIT(event_node->channel); - } - - outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT); - - spin_unlock_irqrestore(&priv->lock, irqflags); - - return 0; -} - -static int quad8_watch_validate(struct counter_device *counter, - const struct counter_watch *watch) -{ - struct counter_event_node *event_node; - - if (watch->channel > QUAD8_NUM_COUNTERS - 1) - return -EINVAL; - - switch (watch->event) { - case COUNTER_EVENT_OVERFLOW: - case COUNTER_EVENT_THRESHOLD: - case COUNTER_EVENT_OVERFLOW_UNDERFLOW: - case COUNTER_EVENT_INDEX: - list_for_each_entry(event_node, &counter->next_events_list, l) - if (watch->channel == event_node->channel && - watch->event != event_node->event) - return -EINVAL; - return 0; - default: - return -EINVAL; - } -} - static const struct counter_ops quad8_ops = { .signal_read = quad8_signal_read, .count_read = quad8_count_read, .count_write = quad8_count_write, - .function_read = quad8_function_read, - .function_write = quad8_function_write, - .action_read = quad8_action_read, - .events_configure = quad8_events_configure, - .watch_validate = quad8_watch_validate, + .function_get = quad8_function_get, + .function_set = quad8_function_set, + .action_get = quad8_action_get }; static const char *const quad8_index_polarity_modes[] = { @@ -491,10 +394,9 @@ static const char *const quad8_index_polarity_modes[] = { }; static int quad8_index_polarity_get(struct counter_device *counter, - struct counter_signal *signal, - u32 *index_polarity) + struct counter_signal *signal, size_t *index_polarity) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id - 16; *index_polarity = priv->index_polarity[channel_id]; @@ -503,16 +405,14 @@ static int quad8_index_polarity_get(struct counter_device *counter, } static int quad8_index_polarity_set(struct counter_device *counter, - struct counter_signal *signal, - u32 index_polarity) + struct counter_signal *signal, size_t index_polarity) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id - 16; const int base_offset = priv->base + 2 * channel_id + 1; - unsigned long irqflags; unsigned int idr_cfg = index_polarity << 1; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); idr_cfg |= priv->synchronous_mode[channel_id]; @@ -521,21 +421,27 @@ static int quad8_index_polarity_set(struct counter_device *counter, /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } +static struct counter_signal_enum_ext quad8_index_pol_enum = { + .items = quad8_index_polarity_modes, + .num_items = ARRAY_SIZE(quad8_index_polarity_modes), + .get = quad8_index_polarity_get, + .set = quad8_index_polarity_set +}; + static const char *const quad8_synchronous_modes[] = { "non-synchronous", "synchronous" }; static int quad8_synchronous_mode_get(struct counter_device *counter, - struct counter_signal *signal, - u32 *synchronous_mode) + struct counter_signal *signal, size_t *synchronous_mode) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id - 16; *synchronous_mode = priv->synchronous_mode[channel_id]; @@ -544,22 +450,20 @@ static int quad8_synchronous_mode_get(struct counter_device *counter, } static int quad8_synchronous_mode_set(struct counter_device *counter, - struct counter_signal *signal, - u32 synchronous_mode) + struct counter_signal *signal, size_t synchronous_mode) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id - 16; const int base_offset = priv->base + 2 * channel_id + 1; - unsigned long irqflags; unsigned int idr_cfg = synchronous_mode; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); idr_cfg |= priv->index_polarity[channel_id] << 1; /* Index function must be non-synchronous in non-quadrature mode */ if (synchronous_mode && !priv->quadrature_mode[channel_id]) { - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return -EINVAL; } @@ -568,25 +472,29 @@ static int quad8_synchronous_mode_set(struct counter_device *counter, /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } -static int quad8_count_floor_read(struct counter_device *counter, - struct counter_count *count, u64 *floor) +static struct counter_signal_enum_ext quad8_syn_mode_enum = { + .items = quad8_synchronous_modes, + .num_items = ARRAY_SIZE(quad8_synchronous_modes), + .get = quad8_synchronous_mode_get, + .set = quad8_synchronous_mode_set +}; + +static ssize_t quad8_count_floor_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) { /* Only a floor of 0 is supported */ - *floor = 0; - - return 0; + return sprintf(buf, "0\n"); } -static int quad8_count_mode_read(struct counter_device *counter, - struct counter_count *count, - enum counter_count_mode *cnt_mode) +static int quad8_count_mode_get(struct counter_device *counter, + struct counter_count *count, size_t *cnt_mode) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; /* Map 104-QUAD-8 count mode to Generic Counter count mode */ switch (priv->count_mode[count->id]) { @@ -607,41 +515,38 @@ static int quad8_count_mode_read(struct counter_device *counter, return 0; } -static int quad8_count_mode_write(struct counter_device *counter, - struct counter_count *count, - enum counter_count_mode cnt_mode) +static int quad8_count_mode_set(struct counter_device *counter, + struct counter_count *count, size_t cnt_mode) { - struct quad8 *const priv = counter_priv(counter); - unsigned int count_mode; + struct quad8 *const priv = counter->priv; unsigned int mode_cfg; const int base_offset = priv->base + 2 * count->id + 1; - unsigned long irqflags; /* Map Generic Counter count mode to 104-QUAD-8 count mode */ switch (cnt_mode) { case COUNTER_COUNT_MODE_NORMAL: - count_mode = 0; + cnt_mode = 0; break; case COUNTER_COUNT_MODE_RANGE_LIMIT: - count_mode = 1; + cnt_mode = 1; break; case COUNTER_COUNT_MODE_NON_RECYCLE: - count_mode = 2; + cnt_mode = 2; break; case COUNTER_COUNT_MODE_MODULO_N: - count_mode = 3; + cnt_mode = 3; break; default: /* should never reach this path */ return -EINVAL; } - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); - priv->count_mode[count->id] = count_mode; + priv->count_mode[count->id] = cnt_mode; /* Set count mode configuration value */ - mode_cfg = count_mode << 1; + mode_cfg = cnt_mode << 1; /* Add quadrature mode configuration */ if (priv->quadrature_mode[count->id]) @@ -650,42 +555,61 @@ static int quad8_count_mode_write(struct counter_device *counter, /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return 0; } -static int quad8_count_enable_read(struct counter_device *counter, - struct counter_count *count, u8 *enable) +static struct counter_count_enum_ext quad8_cnt_mode_enum = { + .items = counter_count_mode_str, + .num_items = ARRAY_SIZE(counter_count_mode_str), + .get = quad8_count_mode_get, + .set = quad8_count_mode_set +}; + +static ssize_t quad8_count_direction_read(struct counter_device *counter, + struct counter_count *count, void *priv, char *buf) { - const struct quad8 *const priv = counter_priv(counter); + enum counter_count_direction dir; - *enable = priv->ab_enable[count->id]; + quad8_direction_get(counter, count, &dir); - return 0; + return sprintf(buf, "%s\n", counter_count_direction_str[dir]); } -static int quad8_count_enable_write(struct counter_device *counter, - struct counter_count *count, u8 enable) +static ssize_t quad8_count_enable_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) { - struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; + + return sprintf(buf, "%u\n", priv->ab_enable[count->id]); +} + +static ssize_t quad8_count_enable_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) +{ + struct quad8 *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; - unsigned long irqflags; + int err; + bool ab_enable; unsigned int ior_cfg; - spin_lock_irqsave(&priv->lock, irqflags); + err = kstrtobool(buf, &ab_enable); + if (err) + return err; - priv->ab_enable[count->id] = enable; + mutex_lock(&priv->lock); - ior_cfg = enable | priv->preset_enable[count->id] << 1 | - priv->irq_trigger[count->id] << 3; + priv->ab_enable[count->id] = ab_enable; + + ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; /* Load I/O control configuration */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + return len; } static const char *const quad8_noise_error_states[] = { @@ -694,9 +618,9 @@ static const char *const quad8_noise_error_states[] = { }; static int quad8_error_noise_get(struct counter_device *counter, - struct counter_count *count, u32 *noise_error) + struct counter_count *count, size_t *noise_error) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id + 1; *noise_error = !!(inb(base_offset) & QUAD8_FLAG_E); @@ -704,14 +628,18 @@ static int quad8_error_noise_get(struct counter_device *counter, return 0; } -static int quad8_count_preset_read(struct counter_device *counter, - struct counter_count *count, u64 *preset) +static struct counter_count_enum_ext quad8_error_noise_enum = { + .items = quad8_noise_error_states, + .num_items = ARRAY_SIZE(quad8_noise_error_states), + .get = quad8_error_noise_get +}; + +static ssize_t quad8_count_preset_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; - *preset = priv->preset[count->id]; - - return 0; + return sprintf(buf, "%u\n", priv->preset[count->id]); } static void quad8_preset_register_set(struct quad8 *const priv, const int id, @@ -730,166 +658,176 @@ static void quad8_preset_register_set(struct quad8 *const priv, const int id, outb(preset >> (8 * i), base_offset); } -static int quad8_count_preset_write(struct counter_device *counter, - struct counter_count *count, u64 preset) +static ssize_t quad8_count_preset_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) { - struct quad8 *const priv = counter_priv(counter); - unsigned long irqflags; + struct quad8 *const priv = counter->priv; + unsigned int preset; + int ret; + + ret = kstrtouint(buf, 0, &preset); + if (ret) + return ret; /* Only 24-bit values are supported */ if (preset > 0xFFFFFF) return -ERANGE; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); quad8_preset_register_set(priv, count->id, preset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + return len; } -static int quad8_count_ceiling_read(struct counter_device *counter, - struct counter_count *count, u64 *ceiling) +static ssize_t quad8_count_ceiling_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) { - struct quad8 *const priv = counter_priv(counter); - unsigned long irqflags; + struct quad8 *const priv = counter->priv; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); /* Range Limit and Modulo-N count modes use preset value as ceiling */ switch (priv->count_mode[count->id]) { case 1: case 3: - *ceiling = priv->preset[count->id]; - break; - default: - /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ - *ceiling = 0x1FFFFFF; - break; + mutex_unlock(&priv->lock); + return sprintf(buf, "%u\n", priv->preset[count->id]); } - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ + return sprintf(buf, "33554431\n"); } -static int quad8_count_ceiling_write(struct counter_device *counter, - struct counter_count *count, u64 ceiling) +static ssize_t quad8_count_ceiling_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) { - struct quad8 *const priv = counter_priv(counter); - unsigned long irqflags; + struct quad8 *const priv = counter->priv; + unsigned int ceiling; + int ret; + + ret = kstrtouint(buf, 0, &ceiling); + if (ret) + return ret; /* Only 24-bit values are supported */ if (ceiling > 0xFFFFFF) return -ERANGE; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); /* Range Limit and Modulo-N count modes use preset value as ceiling */ switch (priv->count_mode[count->id]) { case 1: case 3: quad8_preset_register_set(priv, count->id, ceiling); - spin_unlock_irqrestore(&priv->lock, irqflags); - return 0; + mutex_unlock(&priv->lock); + return len; } - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return -EINVAL; } -static int quad8_count_preset_enable_read(struct counter_device *counter, - struct counter_count *count, - u8 *preset_enable) +static ssize_t quad8_count_preset_enable_read(struct counter_device *counter, + struct counter_count *count, void *private, char *buf) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; - *preset_enable = !priv->preset_enable[count->id]; - - return 0; + return sprintf(buf, "%u\n", !priv->preset_enable[count->id]); } -static int quad8_count_preset_enable_write(struct counter_device *counter, - struct counter_count *count, - u8 preset_enable) +static ssize_t quad8_count_preset_enable_write(struct counter_device *counter, + struct counter_count *count, void *private, const char *buf, size_t len) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id + 1; - unsigned long irqflags; + bool preset_enable; + int ret; unsigned int ior_cfg; + ret = kstrtobool(buf, &preset_enable); + if (ret) + return ret; + /* Preset enable is active low in Input/Output Control register */ preset_enable = !preset_enable; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); priv->preset_enable[count->id] = preset_enable; - ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 | - priv->irq_trigger[count->id] << 3; + ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; /* Load I/O control configuration to Input / Output Control Register */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + return len; } -static int quad8_signal_cable_fault_read(struct counter_device *counter, - struct counter_signal *signal, - u8 *cable_fault) +static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter, + struct counter_signal *signal, + void *private, char *buf) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id / 2; - unsigned long irqflags; bool disabled; unsigned int status; + unsigned int fault; - spin_lock_irqsave(&priv->lock, irqflags); + mutex_lock(&priv->lock); disabled = !(priv->cable_fault_enable & BIT(channel_id)); if (disabled) { - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); return -EINVAL; } /* Logic 0 = cable fault */ status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); /* Mask respective channel and invert logic */ - *cable_fault = !(status & BIT(channel_id)); + fault = !(status & BIT(channel_id)); - return 0; + return sprintf(buf, "%u\n", fault); } -static int quad8_signal_cable_fault_enable_read(struct counter_device *counter, - struct counter_signal *signal, - u8 *enable) +static ssize_t quad8_signal_cable_fault_enable_read( + struct counter_device *counter, struct counter_signal *signal, + void *private, char *buf) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id / 2; + const unsigned int enb = !!(priv->cable_fault_enable & BIT(channel_id)); - *enable = !!(priv->cable_fault_enable & BIT(channel_id)); - - return 0; + return sprintf(buf, "%u\n", enb); } -static int quad8_signal_cable_fault_enable_write(struct counter_device *counter, - struct counter_signal *signal, - u8 enable) +static ssize_t quad8_signal_cable_fault_enable_write( + struct counter_device *counter, struct counter_signal *signal, + void *private, const char *buf, size_t len) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id / 2; - unsigned long irqflags; + bool enable; + int ret; unsigned int cable_fault_enable; - spin_lock_irqsave(&priv->lock, irqflags); + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + mutex_lock(&priv->lock); if (enable) priv->cable_fault_enable |= BIT(channel_id); @@ -901,32 +839,35 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter, outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + return len; } -static int quad8_signal_fck_prescaler_read(struct counter_device *counter, - struct counter_signal *signal, - u8 *prescaler) +static ssize_t quad8_signal_fck_prescaler_read(struct counter_device *counter, + struct counter_signal *signal, void *private, char *buf) { - const struct quad8 *const priv = counter_priv(counter); + const struct quad8 *const priv = counter->priv; + const size_t channel_id = signal->id / 2; - *prescaler = priv->fck_prescaler[signal->id / 2]; - - return 0; + return sprintf(buf, "%u\n", priv->fck_prescaler[channel_id]); } -static int quad8_signal_fck_prescaler_write(struct counter_device *counter, - struct counter_signal *signal, - u8 prescaler) +static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter, + struct counter_signal *signal, void *private, const char *buf, + size_t len) { - struct quad8 *const priv = counter_priv(counter); + struct quad8 *const priv = counter->priv; const size_t channel_id = signal->id / 2; const int base_offset = priv->base + 2 * channel_id; - unsigned long irqflags; + u8 prescaler; + int ret; - spin_lock_irqsave(&priv->lock, irqflags); + ret = kstrtou8(buf, 0, &prescaler); + if (ret) + return ret; + + mutex_lock(&priv->lock); priv->fck_prescaler[channel_id] = prescaler; @@ -938,32 +879,33 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter, outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC, base_offset + 1); - spin_unlock_irqrestore(&priv->lock, irqflags); + mutex_unlock(&priv->lock); - return 0; + return len; } -static struct counter_comp quad8_signal_ext[] = { - COUNTER_COMP_SIGNAL_BOOL("cable_fault", quad8_signal_cable_fault_read, - NULL), - COUNTER_COMP_SIGNAL_BOOL("cable_fault_enable", - quad8_signal_cable_fault_enable_read, - quad8_signal_cable_fault_enable_write), - COUNTER_COMP_SIGNAL_U8("filter_clock_prescaler", - quad8_signal_fck_prescaler_read, - quad8_signal_fck_prescaler_write) +static const struct counter_signal_ext quad8_signal_ext[] = { + { + .name = "cable_fault", + .read = quad8_signal_cable_fault_read + }, + { + .name = "cable_fault_enable", + .read = quad8_signal_cable_fault_enable_read, + .write = quad8_signal_cable_fault_enable_write + }, + { + .name = "filter_clock_prescaler", + .read = quad8_signal_fck_prescaler_read, + .write = quad8_signal_fck_prescaler_write + } }; -static DEFINE_COUNTER_ENUM(quad8_index_pol_enum, quad8_index_polarity_modes); -static DEFINE_COUNTER_ENUM(quad8_synch_mode_enum, quad8_synchronous_modes); - -static struct counter_comp quad8_index_ext[] = { - COUNTER_COMP_SIGNAL_ENUM("index_polarity", quad8_index_polarity_get, - quad8_index_polarity_set, - quad8_index_pol_enum), - COUNTER_COMP_SIGNAL_ENUM("synchronous_mode", quad8_synchronous_mode_get, - quad8_synchronous_mode_set, - quad8_synch_mode_enum), +static const struct counter_signal_ext quad8_index_ext[] = { + COUNTER_SIGNAL_ENUM("index_polarity", &quad8_index_pol_enum), + COUNTER_SIGNAL_ENUM_AVAILABLE("index_polarity", &quad8_index_pol_enum), + COUNTER_SIGNAL_ENUM("synchronous_mode", &quad8_syn_mode_enum), + COUNTER_SIGNAL_ENUM_AVAILABLE("synchronous_mode", &quad8_syn_mode_enum) }; #define QUAD8_QUAD_SIGNAL(_id, _name) { \ @@ -1032,30 +974,39 @@ static struct counter_synapse quad8_count_synapses[][3] = { QUAD8_COUNT_SYNAPSES(6), QUAD8_COUNT_SYNAPSES(7) }; -static const enum counter_count_mode quad8_cnt_modes[] = { - COUNTER_COUNT_MODE_NORMAL, - COUNTER_COUNT_MODE_RANGE_LIMIT, - COUNTER_COUNT_MODE_NON_RECYCLE, - COUNTER_COUNT_MODE_MODULO_N, -}; - -static DEFINE_COUNTER_AVAILABLE(quad8_count_mode_available, quad8_cnt_modes); - -static DEFINE_COUNTER_ENUM(quad8_error_noise_enum, quad8_noise_error_states); - -static struct counter_comp quad8_count_ext[] = { - COUNTER_COMP_CEILING(quad8_count_ceiling_read, - quad8_count_ceiling_write), - COUNTER_COMP_FLOOR(quad8_count_floor_read, NULL), - COUNTER_COMP_COUNT_MODE(quad8_count_mode_read, quad8_count_mode_write, - quad8_count_mode_available), - COUNTER_COMP_DIRECTION(quad8_direction_read), - COUNTER_COMP_ENABLE(quad8_count_enable_read, quad8_count_enable_write), - COUNTER_COMP_COUNT_ENUM("error_noise", quad8_error_noise_get, NULL, - quad8_error_noise_enum), - COUNTER_COMP_PRESET(quad8_count_preset_read, quad8_count_preset_write), - COUNTER_COMP_PRESET_ENABLE(quad8_count_preset_enable_read, - quad8_count_preset_enable_write), +static const struct counter_count_ext quad8_count_ext[] = { + { + .name = "ceiling", + .read = quad8_count_ceiling_read, + .write = quad8_count_ceiling_write + }, + { + .name = "floor", + .read = quad8_count_floor_read + }, + COUNTER_COUNT_ENUM("count_mode", &quad8_cnt_mode_enum), + COUNTER_COUNT_ENUM_AVAILABLE("count_mode", &quad8_cnt_mode_enum), + { + .name = "direction", + .read = quad8_count_direction_read + }, + { + .name = "enable", + .read = quad8_count_enable_read, + .write = quad8_count_enable_write + }, + COUNTER_COUNT_ENUM("error_noise", &quad8_error_noise_enum), + COUNTER_COUNT_ENUM_AVAILABLE("error_noise", &quad8_error_noise_enum), + { + .name = "preset", + .read = quad8_count_preset_read, + .write = quad8_count_preset_write + }, + { + .name = "preset_enable", + .read = quad8_count_preset_enable_read, + .write = quad8_count_preset_enable_write + } }; #define QUAD8_COUNT(_id, _cntname) { \ @@ -1080,56 +1031,11 @@ static struct counter_count quad8_counts[] = { QUAD8_COUNT(7, "Channel 8 Count") }; -static irqreturn_t quad8_irq_handler(int irq, void *private) -{ - struct counter_device *counter = private; - struct quad8 *const priv = counter_priv(counter); - const unsigned long base = priv->base; - unsigned long irq_status; - unsigned long channel; - u8 event; - - irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS); - if (!irq_status) - return IRQ_NONE; - - for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) { - switch (priv->irq_trigger[channel]) { - case QUAD8_EVENT_CARRY: - event = COUNTER_EVENT_OVERFLOW; - break; - case QUAD8_EVENT_COMPARE: - event = COUNTER_EVENT_THRESHOLD; - break; - case QUAD8_EVENT_CARRY_BORROW: - event = COUNTER_EVENT_OVERFLOW_UNDERFLOW; - break; - case QUAD8_EVENT_INDEX: - event = COUNTER_EVENT_INDEX; - break; - default: - /* should never reach this path */ - WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n", - priv->irq_trigger[channel], channel); - continue; - } - - counter_push_event(counter, event, channel); - } - - /* Clear pending interrupts on device */ - outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP); - - return IRQ_HANDLED; -} - static int quad8_probe(struct device *dev, unsigned int id) { - struct counter_device *counter; struct quad8 *priv; int i, j; unsigned int base_offset; - int err; if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", @@ -1137,25 +1043,24 @@ static int quad8_probe(struct device *dev, unsigned int id) return -EBUSY; } - counter = devm_counter_alloc(dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); /* Initialize Counter device and driver data */ - counter->name = dev_name(dev); - counter->parent = dev; - counter->ops = &quad8_ops; - counter->counts = quad8_counts; - counter->num_counts = ARRAY_SIZE(quad8_counts); - counter->signals = quad8_signals; - counter->num_signals = ARRAY_SIZE(quad8_signals); + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; + priv->counter.ops = &quad8_ops; + priv->counter.counts = quad8_counts; + priv->counter.num_counts = ARRAY_SIZE(quad8_counts); + priv->counter.signals = quad8_signals; + priv->counter.num_signals = ARRAY_SIZE(quad8_signals); + priv->counter.priv = priv; priv->base = base[id]; - spin_lock_init(&priv->lock); + /* Initialize mutex */ + mutex_init(&priv->lock); - /* Reset Index/Interrupt Register */ - outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT); /* Reset all counters and disable interrupt function */ outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); /* Set initial configuration for all counters */ @@ -1185,19 +1090,10 @@ static int quad8_probe(struct device *dev, unsigned int id) } /* Disable Differential Encoder Cable Status for all channels */ outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS); - /* Enable all counters and enable interrupt function */ - outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP); + /* Enable all counters */ + outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); - err = devm_request_irq(&counter->dev, irq[id], quad8_irq_handler, - IRQF_SHARED, counter->name, counter); - if (err) - return err; - - err = devm_counter_add(dev, counter); - if (err < 0) - return dev_err_probe(dev, err, "Failed to add counter\n"); - - return 0; + return devm_counter_register(dev, &priv->counter); } static struct isa_driver quad8_driver = { diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig index 3dcdb681c4..d5d2540b30 100644 --- a/drivers/counter/Kconfig +++ b/drivers/counter/Kconfig @@ -23,11 +23,11 @@ config 104_QUAD_8 A counter's respective error flag may be cleared by performing a write operation on the respective count value attribute. Although the 104-QUAD-8 counters have a 25-bit range, only the lower 24 bits may be - set, either directly or via the counter's preset attribute. + set, either directly or via the counter's preset attribute. Interrupts + are not supported by this driver. The base port addresses for the devices may be configured via the base - array module parameter. The interrupt line numbers for the devices may - be configured via the irq array module parameter. + array module parameter. config INTERRUPT_CNT tristate "Interrupt counter driver" diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile index 8fde6c100e..19742e6f5e 100644 --- a/drivers/counter/Makefile +++ b/drivers/counter/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_COUNTER) += counter.o -counter-y := counter-core.o counter-sysfs.o counter-chrdev.o obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o obj-$(CONFIG_INTERRUPT_CNT) += interrupt-cnt.o diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c index 2a58582a9d..53c15f8490 100644 --- a/drivers/counter/ftm-quaddec.c +++ b/drivers/counter/ftm-quaddec.c @@ -14,7 +14,6 @@ #include #include #include -#include #define FTM_FIELD_UPDATE(ftm, offset, mask, val) \ ({ \ @@ -26,6 +25,7 @@ }) struct ftm_quaddec { + struct counter_device counter; struct platform_device *pdev; void __iomem *ftm_base; bool big_endian; @@ -115,9 +115,10 @@ static void ftm_quaddec_disable(void *ftm) } static int ftm_quaddec_get_prescaler(struct counter_device *counter, - struct counter_count *count, u32 *cnt_mode) + struct counter_count *count, + size_t *cnt_mode) { - struct ftm_quaddec *ftm = counter_priv(counter); + struct ftm_quaddec *ftm = counter->priv; uint32_t scflags; ftm_read(ftm, FTM_SC, &scflags); @@ -128,9 +129,10 @@ static int ftm_quaddec_get_prescaler(struct counter_device *counter, } static int ftm_quaddec_set_prescaler(struct counter_device *counter, - struct counter_count *count, u32 cnt_mode) + struct counter_count *count, + size_t cnt_mode) { - struct ftm_quaddec *ftm = counter_priv(counter); + struct ftm_quaddec *ftm = counter->priv; mutex_lock(&ftm->ftm_quaddec_mutex); @@ -149,19 +151,35 @@ static const char * const ftm_quaddec_prescaler[] = { "1", "2", "4", "8", "16", "32", "64", "128" }; +static struct counter_count_enum_ext ftm_quaddec_prescaler_enum = { + .items = ftm_quaddec_prescaler, + .num_items = ARRAY_SIZE(ftm_quaddec_prescaler), + .get = ftm_quaddec_get_prescaler, + .set = ftm_quaddec_set_prescaler +}; + +enum ftm_quaddec_synapse_action { + FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES, +}; + static const enum counter_synapse_action ftm_quaddec_synapse_actions[] = { + [FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES }; +enum ftm_quaddec_count_function { + FTM_QUADDEC_COUNT_ENCODER_MODE_1, +}; + static const enum counter_function ftm_quaddec_count_functions[] = { - COUNTER_FUNCTION_QUADRATURE_X4 + [FTM_QUADDEC_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X4 }; static int ftm_quaddec_count_read(struct counter_device *counter, struct counter_count *count, - u64 *val) + unsigned long *val) { - struct ftm_quaddec *const ftm = counter_priv(counter); + struct ftm_quaddec *const ftm = counter->priv; uint32_t cntval; ftm_read(ftm, FTM_CNT, &cntval); @@ -173,9 +191,9 @@ static int ftm_quaddec_count_read(struct counter_device *counter, static int ftm_quaddec_count_write(struct counter_device *counter, struct counter_count *count, - const u64 val) + const unsigned long val) { - struct ftm_quaddec *const ftm = counter_priv(counter); + struct ftm_quaddec *const ftm = counter->priv; if (val != 0) { dev_warn(&ftm->pdev->dev, "Can only accept '0' as new counter value\n"); @@ -187,21 +205,21 @@ static int ftm_quaddec_count_write(struct counter_device *counter, return 0; } -static int ftm_quaddec_count_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int ftm_quaddec_count_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - *function = COUNTER_FUNCTION_QUADRATURE_X4; + *function = FTM_QUADDEC_COUNT_ENCODER_MODE_1; return 0; } -static int ftm_quaddec_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int ftm_quaddec_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = FTM_QUADDEC_SYNAPSE_ACTION_BOTH_EDGES; return 0; } @@ -209,8 +227,8 @@ static int ftm_quaddec_action_read(struct counter_device *counter, static const struct counter_ops ftm_quaddec_cnt_ops = { .count_read = ftm_quaddec_count_read, .count_write = ftm_quaddec_count_write, - .function_read = ftm_quaddec_count_function_read, - .action_read = ftm_quaddec_action_read, + .function_get = ftm_quaddec_count_function_get, + .action_get = ftm_quaddec_action_get, }; static struct counter_signal ftm_quaddec_signals[] = { @@ -237,12 +255,9 @@ static struct counter_synapse ftm_quaddec_count_synapses[] = { } }; -static DEFINE_COUNTER_ENUM(ftm_quaddec_prescaler_enum, ftm_quaddec_prescaler); - -static struct counter_comp ftm_quaddec_count_ext[] = { - COUNTER_COMP_COUNT_ENUM("prescaler", ftm_quaddec_get_prescaler, - ftm_quaddec_set_prescaler, - ftm_quaddec_prescaler_enum), +static const struct counter_count_ext ftm_quaddec_count_ext[] = { + COUNTER_COUNT_ENUM("prescaler", &ftm_quaddec_prescaler_enum), + COUNTER_COUNT_ENUM_AVAILABLE("prescaler", &ftm_quaddec_prescaler_enum), }; static struct counter_count ftm_quaddec_counts = { @@ -258,17 +273,17 @@ static struct counter_count ftm_quaddec_counts = { static int ftm_quaddec_probe(struct platform_device *pdev) { - struct counter_device *counter; struct ftm_quaddec *ftm; struct device_node *node = pdev->dev.of_node; struct resource *io; int ret; - counter = devm_counter_alloc(&pdev->dev, sizeof(*ftm)); - if (!counter) + ftm = devm_kzalloc(&pdev->dev, sizeof(*ftm), GFP_KERNEL); + if (!ftm) return -ENOMEM; - ftm = counter_priv(counter); + + platform_set_drvdata(pdev, ftm); io = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!io) { @@ -284,13 +299,14 @@ static int ftm_quaddec_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to map memory region\n"); return -EINVAL; } - counter->name = dev_name(&pdev->dev); - counter->parent = &pdev->dev; - counter->ops = &ftm_quaddec_cnt_ops; - counter->counts = &ftm_quaddec_counts; - counter->num_counts = 1; - counter->signals = ftm_quaddec_signals; - counter->num_signals = ARRAY_SIZE(ftm_quaddec_signals); + ftm->counter.name = dev_name(&pdev->dev); + ftm->counter.parent = &pdev->dev; + ftm->counter.ops = &ftm_quaddec_cnt_ops; + ftm->counter.counts = &ftm_quaddec_counts; + ftm->counter.num_counts = 1; + ftm->counter.signals = ftm_quaddec_signals; + ftm->counter.num_signals = ARRAY_SIZE(ftm_quaddec_signals); + ftm->counter.priv = ftm; mutex_init(&ftm->ftm_quaddec_mutex); @@ -300,9 +316,9 @@ static int ftm_quaddec_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_counter_add(&pdev->dev, counter); + ret = devm_counter_register(&pdev->dev, &ftm->counter); if (ret) - return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n"); + return ret; return 0; } diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c index 47a6a9dfc9..8a6847d5fb 100644 --- a/drivers/counter/intel-qep.c +++ b/drivers/counter/intel-qep.c @@ -62,7 +62,15 @@ #define INTEL_QEP_CLK_PERIOD_NS 10 +#define INTEL_QEP_COUNTER_EXT_RW(_name) \ +{ \ + .name = #_name, \ + .read = _name##_read, \ + .write = _name##_write, \ +} + struct intel_qep { + struct counter_device counter; struct mutex lock; struct device *dev; void __iomem *regs; @@ -106,9 +114,10 @@ static void intel_qep_init(struct intel_qep *qep) } static int intel_qep_count_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, + unsigned long *val) { - struct intel_qep *const qep = counter_priv(counter); + struct intel_qep *const qep = counter->priv; pm_runtime_get_sync(qep->dev); *val = intel_qep_readl(qep, INTEL_QEPCOUNT); @@ -121,11 +130,11 @@ static const enum counter_function intel_qep_count_functions[] = { COUNTER_FUNCTION_QUADRATURE_X4, }; -static int intel_qep_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int intel_qep_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - *function = COUNTER_FUNCTION_QUADRATURE_X4; + *function = 0; return 0; } @@ -134,19 +143,19 @@ static const enum counter_synapse_action intel_qep_synapse_actions[] = { COUNTER_SYNAPSE_ACTION_BOTH_EDGES, }; -static int intel_qep_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int intel_qep_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = 0; return 0; } static const struct counter_ops intel_qep_counter_ops = { .count_read = intel_qep_count_read, - .function_read = intel_qep_function_read, - .action_read = intel_qep_action_read, + .function_get = intel_qep_function_get, + .action_get = intel_qep_action_get, }; #define INTEL_QEP_SIGNAL(_id, _name) { \ @@ -172,27 +181,31 @@ static struct counter_synapse intel_qep_count_synapses[] = { INTEL_QEP_SYNAPSE(2), }; -static int intel_qep_ceiling_read(struct counter_device *counter, - struct counter_count *count, u64 *ceiling) +static ssize_t ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; + u32 reg; pm_runtime_get_sync(qep->dev); - *ceiling = intel_qep_readl(qep, INTEL_QEPMAX); + reg = intel_qep_readl(qep, INTEL_QEPMAX); pm_runtime_put(qep->dev); - return 0; + return sysfs_emit(buf, "%u\n", reg); } -static int intel_qep_ceiling_write(struct counter_device *counter, - struct counter_count *count, u64 max) +static ssize_t ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *priv, const char *buf, size_t len) { - struct intel_qep *qep = counter_priv(counter); - int ret = 0; + struct intel_qep *qep = counter->priv; + u32 max; + int ret; - /* Intel QEP ceiling configuration only supports 32-bit values */ - if (max != (u32)max) - return -ERANGE; + ret = kstrtou32(buf, 0, &max); + if (ret < 0) + return ret; mutex_lock(&qep->lock); if (qep->enabled) { @@ -203,28 +216,34 @@ static int intel_qep_ceiling_write(struct counter_device *counter, pm_runtime_get_sync(qep->dev); intel_qep_writel(qep, INTEL_QEPMAX, max); pm_runtime_put(qep->dev); + ret = len; out: mutex_unlock(&qep->lock); return ret; } -static int intel_qep_enable_read(struct counter_device *counter, - struct counter_count *count, u8 *enable) +static ssize_t enable_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; - *enable = qep->enabled; - - return 0; + return sysfs_emit(buf, "%u\n", qep->enabled); } -static int intel_qep_enable_write(struct counter_device *counter, - struct counter_count *count, u8 val) +static ssize_t enable_write(struct counter_device *counter, + struct counter_count *count, + void *priv, const char *buf, size_t len) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; u32 reg; - bool changed; + bool val, changed; + int ret; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; mutex_lock(&qep->lock); changed = val ^ qep->enabled; @@ -248,45 +267,47 @@ static int intel_qep_enable_write(struct counter_device *counter, out: mutex_unlock(&qep->lock); - return 0; + return len; } -static int intel_qep_spike_filter_ns_read(struct counter_device *counter, - struct counter_count *count, - u64 *length) +static ssize_t spike_filter_ns_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; u32 reg; pm_runtime_get_sync(qep->dev); reg = intel_qep_readl(qep, INTEL_QEPCON); if (!(reg & INTEL_QEPCON_FLT_EN)) { pm_runtime_put(qep->dev); - return 0; + return sysfs_emit(buf, "0\n"); } reg = INTEL_QEPFLT_MAX_COUNT(intel_qep_readl(qep, INTEL_QEPFLT)); pm_runtime_put(qep->dev); - *length = (reg + 2) * INTEL_QEP_CLK_PERIOD_NS; - - return 0; + return sysfs_emit(buf, "%u\n", (reg + 2) * INTEL_QEP_CLK_PERIOD_NS); } -static int intel_qep_spike_filter_ns_write(struct counter_device *counter, - struct counter_count *count, - u64 length) +static ssize_t spike_filter_ns_write(struct counter_device *counter, + struct counter_count *count, + void *priv, const char *buf, size_t len) { - struct intel_qep *qep = counter_priv(counter); - u32 reg; + struct intel_qep *qep = counter->priv; + u32 reg, length; bool enable; - int ret = 0; + int ret; + + ret = kstrtou32(buf, 0, &length); + if (ret < 0) + return ret; /* * Spike filter length is (MAX_COUNT + 2) clock periods. * Disable filter when userspace writes 0, enable for valid * nanoseconds values and error out otherwise. */ - do_div(length, INTEL_QEP_CLK_PERIOD_NS); + length /= INTEL_QEP_CLK_PERIOD_NS; if (length == 0) { enable = false; length = 0; @@ -315,34 +336,38 @@ static int intel_qep_spike_filter_ns_write(struct counter_device *counter, intel_qep_writel(qep, INTEL_QEPFLT, length); intel_qep_writel(qep, INTEL_QEPCON, reg); pm_runtime_put(qep->dev); + ret = len; out: mutex_unlock(&qep->lock); return ret; } -static int intel_qep_preset_enable_read(struct counter_device *counter, - struct counter_count *count, - u8 *preset_enable) +static ssize_t preset_enable_read(struct counter_device *counter, + struct counter_count *count, + void *priv, char *buf) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; u32 reg; pm_runtime_get_sync(qep->dev); reg = intel_qep_readl(qep, INTEL_QEPCON); pm_runtime_put(qep->dev); - - *preset_enable = !(reg & INTEL_QEPCON_COUNT_RST_MODE); - - return 0; + return sysfs_emit(buf, "%u\n", !(reg & INTEL_QEPCON_COUNT_RST_MODE)); } -static int intel_qep_preset_enable_write(struct counter_device *counter, - struct counter_count *count, u8 val) +static ssize_t preset_enable_write(struct counter_device *counter, + struct counter_count *count, + void *priv, const char *buf, size_t len) { - struct intel_qep *qep = counter_priv(counter); + struct intel_qep *qep = counter->priv; u32 reg; - int ret = 0; + bool val; + int ret; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; mutex_lock(&qep->lock); if (qep->enabled) { @@ -359,6 +384,7 @@ static int intel_qep_preset_enable_write(struct counter_device *counter, intel_qep_writel(qep, INTEL_QEPCON, reg); pm_runtime_put(qep->dev); + ret = len; out: mutex_unlock(&qep->lock); @@ -366,14 +392,11 @@ static int intel_qep_preset_enable_write(struct counter_device *counter, return ret; } -static struct counter_comp intel_qep_count_ext[] = { - COUNTER_COMP_ENABLE(intel_qep_enable_read, intel_qep_enable_write), - COUNTER_COMP_CEILING(intel_qep_ceiling_read, intel_qep_ceiling_write), - COUNTER_COMP_PRESET_ENABLE(intel_qep_preset_enable_read, - intel_qep_preset_enable_write), - COUNTER_COMP_COUNT_U64("spike_filter_ns", - intel_qep_spike_filter_ns_read, - intel_qep_spike_filter_ns_write), +static const struct counter_count_ext intel_qep_count_ext[] = { + INTEL_QEP_COUNTER_EXT_RW(ceiling), + INTEL_QEP_COUNTER_EXT_RW(enable), + INTEL_QEP_COUNTER_EXT_RW(spike_filter_ns), + INTEL_QEP_COUNTER_EXT_RW(preset_enable) }; static struct counter_count intel_qep_counter_count[] = { @@ -391,16 +414,14 @@ static struct counter_count intel_qep_counter_count[] = { static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id) { - struct counter_device *counter; struct intel_qep *qep; struct device *dev = &pci->dev; void __iomem *regs; int ret; - counter = devm_counter_alloc(dev, sizeof(*qep)); - if (!counter) + qep = devm_kzalloc(dev, sizeof(*qep), GFP_KERNEL); + if (!qep) return -ENOMEM; - qep = counter_priv(counter); ret = pcim_enable_device(pci); if (ret) @@ -423,23 +444,20 @@ static int intel_qep_probe(struct pci_dev *pci, const struct pci_device_id *id) intel_qep_init(qep); pci_set_drvdata(pci, qep); - counter->name = pci_name(pci); - counter->parent = dev; - counter->ops = &intel_qep_counter_ops; - counter->counts = intel_qep_counter_count; - counter->num_counts = ARRAY_SIZE(intel_qep_counter_count); - counter->signals = intel_qep_signals; - counter->num_signals = ARRAY_SIZE(intel_qep_signals); + qep->counter.name = pci_name(pci); + qep->counter.parent = dev; + qep->counter.ops = &intel_qep_counter_ops; + qep->counter.counts = intel_qep_counter_count; + qep->counter.num_counts = ARRAY_SIZE(intel_qep_counter_count); + qep->counter.signals = intel_qep_signals; + qep->counter.num_signals = ARRAY_SIZE(intel_qep_signals); + qep->counter.priv = qep; qep->enabled = false; pm_runtime_put(dev); pm_runtime_allow(dev); - ret = devm_counter_add(&pci->dev, counter); - if (ret < 0) - return dev_err_probe(&pci->dev, ret, "Failed to add counter\n"); - - return 0; + return devm_counter_register(&pci->dev, &qep->counter); } static void intel_qep_remove(struct pci_dev *pci) diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c index 9e99702470..1de4243db4 100644 --- a/drivers/counter/interrupt-cnt.c +++ b/drivers/counter/interrupt-cnt.c @@ -10,12 +10,12 @@ #include #include #include -#include #define INTERRUPT_CNT_NAME "interrupt-cnt" struct interrupt_cnt_priv { atomic_t count; + struct counter_device counter; struct gpio_desc *gpio; int irq; bool enabled; @@ -33,23 +33,30 @@ static irqreturn_t interrupt_cnt_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int interrupt_cnt_enable_read(struct counter_device *counter, - struct counter_count *count, u8 *enable) +static ssize_t interrupt_cnt_enable_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) { - struct interrupt_cnt_priv *priv = counter_priv(counter); + struct interrupt_cnt_priv *priv = counter->priv; - *enable = priv->enabled; - - return 0; + return sysfs_emit(buf, "%d\n", priv->enabled); } -static int interrupt_cnt_enable_write(struct counter_device *counter, - struct counter_count *count, u8 enable) +static ssize_t interrupt_cnt_enable_write(struct counter_device *counter, + struct counter_count *count, + void *private, const char *buf, + size_t len) { - struct interrupt_cnt_priv *priv = counter_priv(counter); + struct interrupt_cnt_priv *priv = counter->priv; + bool enable; + ssize_t ret; + + ret = kstrtobool(buf, &enable); + if (ret) + return ret; if (priv->enabled == enable) - return 0; + return len; if (enable) { priv->enabled = true; @@ -59,32 +66,35 @@ static int interrupt_cnt_enable_write(struct counter_device *counter, priv->enabled = false; } - return 0; + return len; } -static struct counter_comp interrupt_cnt_ext[] = { - COUNTER_COMP_ENABLE(interrupt_cnt_enable_read, - interrupt_cnt_enable_write), +static const struct counter_count_ext interrupt_cnt_ext[] = { + { + .name = "enable", + .read = interrupt_cnt_enable_read, + .write = interrupt_cnt_enable_write, + }, }; static const enum counter_synapse_action interrupt_cnt_synapse_actions[] = { COUNTER_SYNAPSE_ACTION_RISING_EDGE, }; -static int interrupt_cnt_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int interrupt_cnt_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = 0; return 0; } static int interrupt_cnt_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, unsigned long *val) { - struct interrupt_cnt_priv *priv = counter_priv(counter); + struct interrupt_cnt_priv *priv = counter->priv; *val = atomic_read(&priv->count); @@ -92,9 +102,10 @@ static int interrupt_cnt_read(struct counter_device *counter, } static int interrupt_cnt_write(struct counter_device *counter, - struct counter_count *count, const u64 val) + struct counter_count *count, + const unsigned long val) { - struct interrupt_cnt_priv *priv = counter_priv(counter); + struct interrupt_cnt_priv *priv = counter->priv; if (val != (typeof(priv->count.counter))val) return -ERANGE; @@ -108,11 +119,11 @@ static const enum counter_function interrupt_cnt_functions[] = { COUNTER_FUNCTION_INCREASE, }; -static int interrupt_cnt_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int interrupt_cnt_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - *function = COUNTER_FUNCTION_INCREASE; + *function = 0; return 0; } @@ -121,7 +132,7 @@ static int interrupt_cnt_signal_read(struct counter_device *counter, struct counter_signal *signal, enum counter_signal_level *level) { - struct interrupt_cnt_priv *priv = counter_priv(counter); + struct interrupt_cnt_priv *priv = counter->priv; int ret; if (!priv->gpio) @@ -137,24 +148,22 @@ static int interrupt_cnt_signal_read(struct counter_device *counter, } static const struct counter_ops interrupt_cnt_ops = { - .action_read = interrupt_cnt_action_read, + .action_get = interrupt_cnt_action_get, .count_read = interrupt_cnt_read, .count_write = interrupt_cnt_write, - .function_read = interrupt_cnt_function_read, + .function_get = interrupt_cnt_function_get, .signal_read = interrupt_cnt_signal_read, }; static int interrupt_cnt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct counter_device *counter; struct interrupt_cnt_priv *priv; int ret; - counter = devm_counter_alloc(dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); priv->irq = platform_get_irq_optional(pdev, 0); if (priv->irq == -ENXIO) @@ -185,8 +194,8 @@ static int interrupt_cnt_probe(struct platform_device *pdev) if (!priv->signals.name) return -ENOMEM; - counter->signals = &priv->signals; - counter->num_signals = 1; + priv->counter.signals = &priv->signals; + priv->counter.num_signals = 1; priv->synapses.actions_list = interrupt_cnt_synapse_actions; priv->synapses.num_actions = ARRAY_SIZE(interrupt_cnt_synapse_actions); @@ -200,11 +209,12 @@ static int interrupt_cnt_probe(struct platform_device *pdev) priv->cnts.ext = interrupt_cnt_ext; priv->cnts.num_ext = ARRAY_SIZE(interrupt_cnt_ext); - counter->name = dev_name(dev); - counter->parent = dev; - counter->ops = &interrupt_cnt_ops; - counter->counts = &priv->cnts; - counter->num_counts = 1; + priv->counter.priv = priv; + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; + priv->counter.ops = &interrupt_cnt_ops; + priv->counter.counts = &priv->cnts; + priv->counter.num_counts = 1; irq_set_status_flags(priv->irq, IRQ_NOAUTOEN); ret = devm_request_irq(dev, priv->irq, interrupt_cnt_isr, @@ -213,11 +223,7 @@ static int interrupt_cnt_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_counter_add(dev, counter); - if (ret < 0) - return dev_err_probe(dev, ret, "Failed to add counter\n"); - - return 0; + return devm_counter_register(dev, &priv->counter); } static const struct of_device_id interrupt_cnt_of_match[] = { diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c index 0084444514..1aa70b9c48 100644 --- a/drivers/counter/microchip-tcb-capture.c +++ b/drivers/counter/microchip-tcb-capture.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* +/** * Copyright (C) 2020 Microchip * * Author: Kamel Bouhara @@ -24,6 +24,7 @@ struct mchp_tc_data { const struct atmel_tcb_config *tc_cfg; + struct counter_device counter; struct regmap *regmap; int qdec_mode; int num_channels; @@ -31,16 +32,28 @@ struct mchp_tc_data { bool trig_inverted; }; +enum mchp_tc_count_function { + MCHP_TC_FUNCTION_INCREASE, + MCHP_TC_FUNCTION_QUADRATURE, +}; + static const enum counter_function mchp_tc_count_functions[] = { - COUNTER_FUNCTION_INCREASE, - COUNTER_FUNCTION_QUADRATURE_X4, + [MCHP_TC_FUNCTION_INCREASE] = COUNTER_FUNCTION_INCREASE, + [MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_FUNCTION_QUADRATURE_X4, +}; + +enum mchp_tc_synapse_action { + MCHP_TC_SYNAPSE_ACTION_NONE = 0, + MCHP_TC_SYNAPSE_ACTION_RISING_EDGE, + MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE, + MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE }; static const enum counter_synapse_action mchp_tc_synapse_actions[] = { - COUNTER_SYNAPSE_ACTION_NONE, - COUNTER_SYNAPSE_ACTION_RISING_EDGE, - COUNTER_SYNAPSE_ACTION_FALLING_EDGE, - COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + [MCHP_TC_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [MCHP_TC_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + [MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, }; static struct counter_signal mchp_tc_count_signals[] = { @@ -67,25 +80,25 @@ static struct counter_synapse mchp_tc_count_synapses[] = { } }; -static int mchp_tc_count_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int mchp_tc_count_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; if (priv->qdec_mode) - *function = COUNTER_FUNCTION_QUADRATURE_X4; + *function = MCHP_TC_FUNCTION_QUADRATURE; else - *function = COUNTER_FUNCTION_INCREASE; + *function = MCHP_TC_FUNCTION_INCREASE; return 0; } -static int mchp_tc_count_function_write(struct counter_device *counter, - struct counter_count *count, - enum counter_function function) +static int mchp_tc_count_function_set(struct counter_device *counter, + struct counter_count *count, + size_t function) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; u32 bmr, cmr; regmap_read(priv->regmap, ATMEL_TC_BMR, &bmr); @@ -95,7 +108,7 @@ static int mchp_tc_count_function_write(struct counter_device *counter, cmr &= ~ATMEL_TC_WAVE; switch (function) { - case COUNTER_FUNCTION_INCREASE: + case MCHP_TC_FUNCTION_INCREASE: priv->qdec_mode = 0; /* Set highest rate based on whether soc has gclk or not */ bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN); @@ -107,7 +120,7 @@ static int mchp_tc_count_function_write(struct counter_device *counter, cmr |= ATMEL_TC_CMR_MASK; cmr &= ~(ATMEL_TC_ABETRG | ATMEL_TC_XC0); break; - case COUNTER_FUNCTION_QUADRATURE_X4: + case MCHP_TC_FUNCTION_QUADRATURE: if (!priv->tc_cfg->has_qdec) return -EINVAL; /* In QDEC mode settings both channels 0 and 1 are required */ @@ -147,7 +160,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter, struct counter_signal *signal, enum counter_signal_level *lvl) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; bool sigstatus; u32 sr; @@ -163,40 +176,40 @@ static int mchp_tc_count_signal_read(struct counter_device *counter, return 0; } -static int mchp_tc_count_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int mchp_tc_count_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; u32 cmr; regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr); switch (cmr & ATMEL_TC_ETRGEDG) { default: - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = MCHP_TC_SYNAPSE_ACTION_NONE; break; case ATMEL_TC_ETRGEDG_RISING: - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = MCHP_TC_SYNAPSE_ACTION_RISING_EDGE; break; case ATMEL_TC_ETRGEDG_FALLING: - *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; + *action = MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE; break; case ATMEL_TC_ETRGEDG_BOTH: - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE; break; } return 0; } -static int mchp_tc_count_action_write(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action action) +static int mchp_tc_count_action_set(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t action) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; u32 edge = ATMEL_TC_ETRGEDG_NONE; /* QDEC mode is rising edge only */ @@ -204,16 +217,16 @@ static int mchp_tc_count_action_write(struct counter_device *counter, return -EINVAL; switch (action) { - case COUNTER_SYNAPSE_ACTION_NONE: + case MCHP_TC_SYNAPSE_ACTION_NONE: edge = ATMEL_TC_ETRGEDG_NONE; break; - case COUNTER_SYNAPSE_ACTION_RISING_EDGE: + case MCHP_TC_SYNAPSE_ACTION_RISING_EDGE: edge = ATMEL_TC_ETRGEDG_RISING; break; - case COUNTER_SYNAPSE_ACTION_FALLING_EDGE: + case MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE: edge = ATMEL_TC_ETRGEDG_FALLING; break; - case COUNTER_SYNAPSE_ACTION_BOTH_EDGES: + case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE: edge = ATMEL_TC_ETRGEDG_BOTH; break; default: @@ -227,9 +240,10 @@ static int mchp_tc_count_action_write(struct counter_device *counter, } static int mchp_tc_count_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, + unsigned long *val) { - struct mchp_tc_data *const priv = counter_priv(counter); + struct mchp_tc_data *const priv = counter->priv; u32 cnt; regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CV), &cnt); @@ -250,12 +264,12 @@ static struct counter_count mchp_tc_counts[] = { }; static const struct counter_ops mchp_tc_ops = { - .signal_read = mchp_tc_count_signal_read, - .count_read = mchp_tc_count_read, - .function_read = mchp_tc_count_function_read, - .function_write = mchp_tc_count_function_write, - .action_read = mchp_tc_count_action_read, - .action_write = mchp_tc_count_action_write + .signal_read = mchp_tc_count_signal_read, + .count_read = mchp_tc_count_read, + .function_get = mchp_tc_count_function_get, + .function_set = mchp_tc_count_function_set, + .action_get = mchp_tc_count_action_get, + .action_set = mchp_tc_count_action_set }; static const struct atmel_tcb_config tcb_rm9200_config = { @@ -295,7 +309,6 @@ static int mchp_tc_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; const struct atmel_tcb_config *tcb_config; const struct of_device_id *match; - struct counter_device *counter; struct mchp_tc_data *priv; char clk_name[7]; struct regmap *regmap; @@ -303,10 +316,11 @@ static int mchp_tc_probe(struct platform_device *pdev) int channel; int ret, i; - counter = devm_counter_alloc(&pdev->dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); + + platform_set_drvdata(pdev, priv); match = of_match_node(atmel_tc_of_match, np->parent); tcb_config = match->data; @@ -361,19 +375,16 @@ static int mchp_tc_probe(struct platform_device *pdev) priv->tc_cfg = tcb_config; priv->regmap = regmap; - counter->name = dev_name(&pdev->dev); - counter->parent = &pdev->dev; - counter->ops = &mchp_tc_ops; - counter->num_counts = ARRAY_SIZE(mchp_tc_counts); - counter->counts = mchp_tc_counts; - counter->num_signals = ARRAY_SIZE(mchp_tc_count_signals); - counter->signals = mchp_tc_count_signals; + priv->counter.name = dev_name(&pdev->dev); + priv->counter.parent = &pdev->dev; + priv->counter.ops = &mchp_tc_ops; + priv->counter.num_counts = ARRAY_SIZE(mchp_tc_counts); + priv->counter.counts = mchp_tc_counts; + priv->counter.num_signals = ARRAY_SIZE(mchp_tc_count_signals); + priv->counter.signals = mchp_tc_count_signals; + priv->counter.priv = priv; - ret = devm_counter_add(&pdev->dev, counter); - if (ret < 0) - return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n"); - - return 0; + return devm_counter_register(&pdev->dev, &priv->counter); } static const struct of_device_id mchp_tc_dt_ids[] = { diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c index 68031d93ce..13656957c4 100644 --- a/drivers/counter/stm32-lptimer-cnt.c +++ b/drivers/counter/stm32-lptimer-cnt.c @@ -17,9 +17,9 @@ #include #include #include -#include struct stm32_lptim_cnt { + struct counter_device counter; struct device *dev; struct regmap *regmap; struct clk *clk; @@ -107,7 +107,11 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable) return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val); } -/* +/** + * enum stm32_lptim_cnt_function - enumerates LPTimer counter & encoder modes + * @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges + * @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature) + * * In non-quadrature mode, device counts up on active edge. * In quadrature mode, encoder counting scenarios are as follows: * +---------+----------+--------------------+--------------------+ @@ -125,22 +129,35 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable) * | edges | Low -> | Up | Down | Down | Up | * +---------+----------+----------+---------+----------+---------+ */ +enum stm32_lptim_cnt_function { + STM32_LPTIM_COUNTER_INCREASE, + STM32_LPTIM_ENCODER_BOTH_EDGE, +}; + static const enum counter_function stm32_lptim_cnt_functions[] = { - COUNTER_FUNCTION_INCREASE, - COUNTER_FUNCTION_QUADRATURE_X4, + [STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE, + [STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4, +}; + +enum stm32_lptim_synapse_action { + STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE, + STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE, + STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES, + STM32_LPTIM_SYNAPSE_ACTION_NONE, }; static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = { - COUNTER_SYNAPSE_ACTION_RISING_EDGE, - COUNTER_SYNAPSE_ACTION_FALLING_EDGE, - COUNTER_SYNAPSE_ACTION_BOTH_EDGES, - COUNTER_SYNAPSE_ACTION_NONE, + /* Index must match with stm32_lptim_cnt_polarity[] (priv->polarity) */ + [STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE, + [STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + [STM32_LPTIM_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, }; static int stm32_lptim_cnt_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, unsigned long *val) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; u32 cnt; int ret; @@ -153,41 +170,41 @@ static int stm32_lptim_cnt_read(struct counter_device *counter, return 0; } -static int stm32_lptim_cnt_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int stm32_lptim_cnt_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; if (!priv->quadrature_mode) { - *function = COUNTER_FUNCTION_INCREASE; + *function = STM32_LPTIM_COUNTER_INCREASE; return 0; } - if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) { - *function = COUNTER_FUNCTION_QUADRATURE_X4; + if (priv->polarity == STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES) { + *function = STM32_LPTIM_ENCODER_BOTH_EDGE; return 0; } return -EINVAL; } -static int stm32_lptim_cnt_function_write(struct counter_device *counter, - struct counter_count *count, - enum counter_function function) +static int stm32_lptim_cnt_function_set(struct counter_device *counter, + struct counter_count *count, + size_t function) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; if (stm32_lptim_is_enabled(priv)) return -EBUSY; switch (function) { - case COUNTER_FUNCTION_INCREASE: + case STM32_LPTIM_COUNTER_INCREASE: priv->quadrature_mode = 0; return 0; - case COUNTER_FUNCTION_QUADRATURE_X4: + case STM32_LPTIM_ENCODER_BOTH_EDGE: priv->quadrature_mode = 1; - priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES; + priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES; return 0; default: /* should never reach this path */ @@ -195,29 +212,33 @@ static int stm32_lptim_cnt_function_write(struct counter_device *counter, } } -static int stm32_lptim_cnt_enable_read(struct counter_device *counter, - struct counter_count *count, - u8 *enable) +static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; int ret; ret = stm32_lptim_is_enabled(priv); if (ret < 0) return ret; - *enable = ret; - - return 0; + return scnprintf(buf, PAGE_SIZE, "%u\n", ret); } -static int stm32_lptim_cnt_enable_write(struct counter_device *counter, - struct counter_count *count, - u8 enable) +static ssize_t stm32_lptim_cnt_enable_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; + bool enable; int ret; + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + /* Check nobody uses the timer, or already disabled/enabled */ ret = stm32_lptim_is_enabled(priv); if ((ret < 0) || (!ret && !enable)) @@ -233,81 +254,78 @@ static int stm32_lptim_cnt_enable_write(struct counter_device *counter, if (ret) return ret; - return 0; + return len; } -static int stm32_lptim_cnt_ceiling_read(struct counter_device *counter, - struct counter_count *count, - u64 *ceiling) +static ssize_t stm32_lptim_cnt_ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; - *ceiling = priv->ceiling; - - return 0; + return snprintf(buf, PAGE_SIZE, "%u\n", priv->ceiling); } -static int stm32_lptim_cnt_ceiling_write(struct counter_device *counter, - struct counter_count *count, - u64 ceiling) +static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); + struct stm32_lptim_cnt *const priv = counter->priv; + unsigned int ceiling; + int ret; if (stm32_lptim_is_enabled(priv)) return -EBUSY; + ret = kstrtouint(buf, 0, &ceiling); + if (ret) + return ret; + if (ceiling > STM32_LPTIM_MAX_ARR) return -ERANGE; priv->ceiling = ceiling; - return 0; + return len; } -static struct counter_comp stm32_lptim_cnt_ext[] = { - COUNTER_COMP_ENABLE(stm32_lptim_cnt_enable_read, - stm32_lptim_cnt_enable_write), - COUNTER_COMP_CEILING(stm32_lptim_cnt_ceiling_read, - stm32_lptim_cnt_ceiling_write), +static const struct counter_count_ext stm32_lptim_cnt_ext[] = { + { + .name = "enable", + .read = stm32_lptim_cnt_enable_read, + .write = stm32_lptim_cnt_enable_write + }, + { + .name = "ceiling", + .read = stm32_lptim_cnt_ceiling_read, + .write = stm32_lptim_cnt_ceiling_write + }, }; -static int stm32_lptim_cnt_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int stm32_lptim_cnt_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); - enum counter_function function; + struct stm32_lptim_cnt *const priv = counter->priv; + size_t function; int err; - err = stm32_lptim_cnt_function_read(counter, count, &function); + err = stm32_lptim_cnt_function_get(counter, count, &function); if (err) return err; switch (function) { - case COUNTER_FUNCTION_INCREASE: + case STM32_LPTIM_COUNTER_INCREASE: /* LP Timer acts as up-counter on input 1 */ - if (synapse->signal->id != count->synapses[0].signal->id) { - *action = COUNTER_SYNAPSE_ACTION_NONE; - return 0; - } - - switch (priv->polarity) { - case STM32_LPTIM_CKPOL_RISING_EDGE: - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; - return 0; - case STM32_LPTIM_CKPOL_FALLING_EDGE: - *action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE; - return 0; - case STM32_LPTIM_CKPOL_BOTH_EDGES: - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; - return 0; - default: - /* should never reach this path */ - return -EINVAL; - } - case COUNTER_FUNCTION_QUADRATURE_X4: - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + if (synapse->signal->id == count->synapses[0].signal->id) + *action = priv->polarity; + else + *action = STM32_LPTIM_SYNAPSE_ACTION_NONE; + return 0; + case STM32_LPTIM_ENCODER_BOTH_EDGE: + *action = priv->polarity; return 0; default: /* should never reach this path */ @@ -315,48 +333,43 @@ static int stm32_lptim_cnt_action_read(struct counter_device *counter, } } -static int stm32_lptim_cnt_action_write(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action action) +static int stm32_lptim_cnt_action_set(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t action) { - struct stm32_lptim_cnt *const priv = counter_priv(counter); - enum counter_function function; + struct stm32_lptim_cnt *const priv = counter->priv; + size_t function; int err; if (stm32_lptim_is_enabled(priv)) return -EBUSY; - err = stm32_lptim_cnt_function_read(counter, count, &function); + err = stm32_lptim_cnt_function_get(counter, count, &function); if (err) return err; /* only set polarity when in counter mode (on input 1) */ - if (function != COUNTER_FUNCTION_INCREASE - || synapse->signal->id != count->synapses[0].signal->id) - return -EINVAL; - - switch (action) { - case COUNTER_SYNAPSE_ACTION_RISING_EDGE: - priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE; - return 0; - case COUNTER_SYNAPSE_ACTION_FALLING_EDGE: - priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE; - return 0; - case COUNTER_SYNAPSE_ACTION_BOTH_EDGES: - priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES; - return 0; - default: - return -EINVAL; + if (function == STM32_LPTIM_COUNTER_INCREASE + && synapse->signal->id == count->synapses[0].signal->id) { + switch (action) { + case STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE: + case STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE: + case STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES: + priv->polarity = action; + return 0; + } } + + return -EINVAL; } static const struct counter_ops stm32_lptim_cnt_ops = { .count_read = stm32_lptim_cnt_read, - .function_read = stm32_lptim_cnt_function_read, - .function_write = stm32_lptim_cnt_function_write, - .action_read = stm32_lptim_cnt_action_read, - .action_write = stm32_lptim_cnt_action_write, + .function_get = stm32_lptim_cnt_function_get, + .function_set = stm32_lptim_cnt_function_set, + .action_get = stm32_lptim_cnt_action_get, + .action_set = stm32_lptim_cnt_action_set, }; static struct counter_signal stm32_lptim_cnt_signals[] = { @@ -410,17 +423,14 @@ static struct counter_count stm32_lptim_in1_counts = { static int stm32_lptim_cnt_probe(struct platform_device *pdev) { struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); - struct counter_device *counter; struct stm32_lptim_cnt *priv; - int ret; if (IS_ERR_OR_NULL(ddata)) return -EINVAL; - counter = devm_counter_alloc(&pdev->dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); priv->dev = &pdev->dev; priv->regmap = ddata->regmap; @@ -428,26 +438,23 @@ static int stm32_lptim_cnt_probe(struct platform_device *pdev) priv->ceiling = STM32_LPTIM_MAX_ARR; /* Initialize Counter device */ - counter->name = dev_name(&pdev->dev); - counter->parent = &pdev->dev; - counter->ops = &stm32_lptim_cnt_ops; + priv->counter.name = dev_name(&pdev->dev); + priv->counter.parent = &pdev->dev; + priv->counter.ops = &stm32_lptim_cnt_ops; if (ddata->has_encoder) { - counter->counts = &stm32_lptim_enc_counts; - counter->num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals); + priv->counter.counts = &stm32_lptim_enc_counts; + priv->counter.num_signals = ARRAY_SIZE(stm32_lptim_cnt_signals); } else { - counter->counts = &stm32_lptim_in1_counts; - counter->num_signals = 1; + priv->counter.counts = &stm32_lptim_in1_counts; + priv->counter.num_signals = 1; } - counter->num_counts = 1; - counter->signals = stm32_lptim_cnt_signals; + priv->counter.num_counts = 1; + priv->counter.signals = stm32_lptim_cnt_signals; + priv->counter.priv = priv; platform_set_drvdata(pdev, priv); - ret = devm_counter_add(&pdev->dev, counter); - if (ret < 0) - return dev_err_probe(&pdev->dev, ret, "Failed to add counter\n"); - - return 0; + return devm_counter_register(&pdev->dev, &priv->counter); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c index 5779ae7c73..3fb0debd74 100644 --- a/drivers/counter/stm32-timer-cnt.c +++ b/drivers/counter/stm32-timer-cnt.c @@ -13,7 +13,6 @@ #include #include #include -#include #define TIM_CCMR_CCXS (BIT(8) | BIT(0)) #define TIM_CCMR_MASK (TIM_CCMR_CC1S | TIM_CCMR_CC2S | \ @@ -29,6 +28,7 @@ struct stm32_timer_regs { }; struct stm32_timer_cnt { + struct counter_device counter; struct regmap *regmap; struct clk *clk; u32 max_arr; @@ -36,17 +36,31 @@ struct stm32_timer_cnt { struct stm32_timer_regs bak; }; +/** + * enum stm32_count_function - enumerates stm32 timer counter encoder modes + * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1 + * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level + * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level + * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges + */ +enum stm32_count_function { + STM32_COUNT_SLAVE_MODE_DISABLED, + STM32_COUNT_ENCODER_MODE_1, + STM32_COUNT_ENCODER_MODE_2, + STM32_COUNT_ENCODER_MODE_3, +}; + static const enum counter_function stm32_count_functions[] = { - COUNTER_FUNCTION_INCREASE, - COUNTER_FUNCTION_QUADRATURE_X2_A, - COUNTER_FUNCTION_QUADRATURE_X2_B, - COUNTER_FUNCTION_QUADRATURE_X4, + [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE, + [STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A, + [STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B, + [STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4, }; static int stm32_count_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, unsigned long *val) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 cnt; regmap_read(priv->regmap, TIM_CNT, &cnt); @@ -56,9 +70,10 @@ static int stm32_count_read(struct counter_device *counter, } static int stm32_count_write(struct counter_device *counter, - struct counter_count *count, const u64 val) + struct counter_count *count, + const unsigned long val) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 ceiling; regmap_read(priv->regmap, TIM_ARR, &ceiling); @@ -68,52 +83,52 @@ static int stm32_count_write(struct counter_device *counter, return regmap_write(priv->regmap, TIM_CNT, val); } -static int stm32_count_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int stm32_count_function_get(struct counter_device *counter, + struct counter_count *count, + size_t *function) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 smcr; regmap_read(priv->regmap, TIM_SMCR, &smcr); switch (smcr & TIM_SMCR_SMS) { - case TIM_SMCR_SMS_SLAVE_MODE_DISABLED: - *function = COUNTER_FUNCTION_INCREASE; + case 0: + *function = STM32_COUNT_SLAVE_MODE_DISABLED; return 0; - case TIM_SMCR_SMS_ENCODER_MODE_1: - *function = COUNTER_FUNCTION_QUADRATURE_X2_A; + case 1: + *function = STM32_COUNT_ENCODER_MODE_1; return 0; - case TIM_SMCR_SMS_ENCODER_MODE_2: - *function = COUNTER_FUNCTION_QUADRATURE_X2_B; + case 2: + *function = STM32_COUNT_ENCODER_MODE_2; return 0; - case TIM_SMCR_SMS_ENCODER_MODE_3: - *function = COUNTER_FUNCTION_QUADRATURE_X4; + case 3: + *function = STM32_COUNT_ENCODER_MODE_3; return 0; default: return -EINVAL; } } -static int stm32_count_function_write(struct counter_device *counter, - struct counter_count *count, - enum counter_function function) +static int stm32_count_function_set(struct counter_device *counter, + struct counter_count *count, + size_t function) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 cr1, sms; switch (function) { - case COUNTER_FUNCTION_INCREASE: - sms = TIM_SMCR_SMS_SLAVE_MODE_DISABLED; + case STM32_COUNT_SLAVE_MODE_DISABLED: + sms = 0; break; - case COUNTER_FUNCTION_QUADRATURE_X2_A: - sms = TIM_SMCR_SMS_ENCODER_MODE_1; + case STM32_COUNT_ENCODER_MODE_1: + sms = 1; break; - case COUNTER_FUNCTION_QUADRATURE_X2_B: - sms = TIM_SMCR_SMS_ENCODER_MODE_2; + case STM32_COUNT_ENCODER_MODE_2: + sms = 2; break; - case COUNTER_FUNCTION_QUADRATURE_X4: - sms = TIM_SMCR_SMS_ENCODER_MODE_3; + case STM32_COUNT_ENCODER_MODE_3: + sms = 3; break; default: return -EINVAL; @@ -135,37 +150,44 @@ static int stm32_count_function_write(struct counter_device *counter, return 0; } -static int stm32_count_direction_read(struct counter_device *counter, +static ssize_t stm32_count_direction_read(struct counter_device *counter, struct counter_count *count, - enum counter_count_direction *direction) + void *private, char *buf) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; + const char *direction; u32 cr1; regmap_read(priv->regmap, TIM_CR1, &cr1); - *direction = (cr1 & TIM_CR1_DIR) ? COUNTER_COUNT_DIRECTION_BACKWARD : - COUNTER_COUNT_DIRECTION_FORWARD; + direction = (cr1 & TIM_CR1_DIR) ? "backward" : "forward"; - return 0; + return scnprintf(buf, PAGE_SIZE, "%s\n", direction); } -static int stm32_count_ceiling_read(struct counter_device *counter, - struct counter_count *count, u64 *ceiling) +static ssize_t stm32_count_ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 arr; regmap_read(priv->regmap, TIM_ARR, &arr); - *ceiling = arr; - - return 0; + return snprintf(buf, PAGE_SIZE, "%u\n", arr); } -static int stm32_count_ceiling_write(struct counter_device *counter, - struct counter_count *count, u64 ceiling) +static ssize_t stm32_count_ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; + unsigned int ceiling; + int ret; + + ret = kstrtouint(buf, 0, &ceiling); + if (ret) + return ret; if (ceiling > priv->max_arr) return -ERANGE; @@ -174,27 +196,34 @@ static int stm32_count_ceiling_write(struct counter_device *counter, regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); regmap_write(priv->regmap, TIM_ARR, ceiling); - return 0; + return len; } -static int stm32_count_enable_read(struct counter_device *counter, - struct counter_count *count, u8 *enable) +static ssize_t stm32_count_enable_read(struct counter_device *counter, + struct counter_count *count, + void *private, char *buf) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; u32 cr1; regmap_read(priv->regmap, TIM_CR1, &cr1); - *enable = cr1 & TIM_CR1_CEN; - - return 0; + return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)(cr1 & TIM_CR1_CEN)); } -static int stm32_count_enable_write(struct counter_device *counter, - struct counter_count *count, u8 enable) +static ssize_t stm32_count_enable_write(struct counter_device *counter, + struct counter_count *count, + void *private, + const char *buf, size_t len) { - struct stm32_timer_cnt *const priv = counter_priv(counter); + struct stm32_timer_cnt *const priv = counter->priv; + int err; u32 cr1; + bool enable; + + err = kstrtobool(buf, &enable); + if (err) + return err; if (enable) { regmap_read(priv->regmap, TIM_CR1, &cr1); @@ -213,55 +242,70 @@ static int stm32_count_enable_write(struct counter_device *counter, /* Keep enabled state to properly handle low power states */ priv->enabled = enable; - return 0; + return len; } -static struct counter_comp stm32_count_ext[] = { - COUNTER_COMP_DIRECTION(stm32_count_direction_read), - COUNTER_COMP_ENABLE(stm32_count_enable_read, stm32_count_enable_write), - COUNTER_COMP_CEILING(stm32_count_ceiling_read, - stm32_count_ceiling_write), +static const struct counter_count_ext stm32_count_ext[] = { + { + .name = "direction", + .read = stm32_count_direction_read, + }, + { + .name = "enable", + .read = stm32_count_enable_read, + .write = stm32_count_enable_write + }, + { + .name = "ceiling", + .read = stm32_count_ceiling_read, + .write = stm32_count_ceiling_write + }, +}; + +enum stm32_synapse_action { + STM32_SYNAPSE_ACTION_NONE, + STM32_SYNAPSE_ACTION_BOTH_EDGES }; static const enum counter_synapse_action stm32_synapse_actions[] = { - COUNTER_SYNAPSE_ACTION_NONE, - COUNTER_SYNAPSE_ACTION_BOTH_EDGES + [STM32_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, + [STM32_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES }; -static int stm32_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int stm32_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, + size_t *action) { - enum counter_function function; + size_t function; int err; - err = stm32_count_function_read(counter, count, &function); + err = stm32_count_function_get(counter, count, &function); if (err) return err; switch (function) { - case COUNTER_FUNCTION_INCREASE: + case STM32_COUNT_SLAVE_MODE_DISABLED: /* counts on internal clock when CEN=1 */ - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = STM32_SYNAPSE_ACTION_NONE; return 0; - case COUNTER_FUNCTION_QUADRATURE_X2_A: + case STM32_COUNT_ENCODER_MODE_1: /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ if (synapse->signal->id == count->synapses[0].signal->id) - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; else - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = STM32_SYNAPSE_ACTION_NONE; return 0; - case COUNTER_FUNCTION_QUADRATURE_X2_B: + case STM32_COUNT_ENCODER_MODE_2: /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ if (synapse->signal->id == count->synapses[1].signal->id) - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; else - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = STM32_SYNAPSE_ACTION_NONE; return 0; - case COUNTER_FUNCTION_QUADRATURE_X4: + case STM32_COUNT_ENCODER_MODE_3: /* counts up/down on both TI1FP1 and TI2FP2 edges */ - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; return 0; default: return -EINVAL; @@ -271,9 +315,9 @@ static int stm32_action_read(struct counter_device *counter, static const struct counter_ops stm32_timer_cnt_ops = { .count_read = stm32_count_read, .count_write = stm32_count_write, - .function_read = stm32_count_function_read, - .function_write = stm32_count_function_write, - .action_read = stm32_action_read, + .function_get = stm32_count_function_get, + .function_set = stm32_count_function_set, + .action_get = stm32_action_get, }; static struct counter_signal stm32_signals[] = { @@ -316,38 +360,31 @@ static int stm32_timer_cnt_probe(struct platform_device *pdev) struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev; struct stm32_timer_cnt *priv; - struct counter_device *counter; - int ret; if (IS_ERR_OR_NULL(ddata)) return -EINVAL; - counter = devm_counter_alloc(dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); - priv->regmap = ddata->regmap; priv->clk = ddata->clk; priv->max_arr = ddata->max_arr; - counter->name = dev_name(dev); - counter->parent = dev; - counter->ops = &stm32_timer_cnt_ops; - counter->counts = &stm32_counts; - counter->num_counts = 1; - counter->signals = stm32_signals; - counter->num_signals = ARRAY_SIZE(stm32_signals); + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; + priv->counter.ops = &stm32_timer_cnt_ops; + priv->counter.counts = &stm32_counts; + priv->counter.num_counts = 1; + priv->counter.signals = stm32_signals; + priv->counter.num_signals = ARRAY_SIZE(stm32_signals); + priv->counter.priv = priv; platform_set_drvdata(pdev, priv); /* Register Counter device */ - ret = devm_counter_add(dev, counter); - if (ret < 0) - dev_err_probe(dev, ret, "Failed to add counter\n"); - - return ret; + return devm_counter_register(dev, &priv->counter); } static int __maybe_unused stm32_timer_cnt_suspend(struct device *dev) diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c index 0489d26eb4..94fe58bb3e 100644 --- a/drivers/counter/ti-eqep.c +++ b/drivers/counter/ti-eqep.c @@ -13,7 +13,6 @@ #include #include #include -#include /* 32-bit registers */ #define QPOSCNT 0x0 @@ -74,28 +73,29 @@ enum { }; /* Position Counter Input Modes */ -enum ti_eqep_count_func { +enum { TI_EQEP_COUNT_FUNC_QUAD_COUNT, TI_EQEP_COUNT_FUNC_DIR_COUNT, TI_EQEP_COUNT_FUNC_UP_COUNT, TI_EQEP_COUNT_FUNC_DOWN_COUNT, }; +enum { + TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES, + TI_EQEP_SYNAPSE_ACTION_RISING_EDGE, + TI_EQEP_SYNAPSE_ACTION_NONE, +}; + struct ti_eqep_cnt { struct counter_device counter; struct regmap *regmap32; struct regmap *regmap16; }; -static struct ti_eqep_cnt *ti_eqep_count_from_counter(struct counter_device *counter) -{ - return counter_priv(counter); -} - static int ti_eqep_count_read(struct counter_device *counter, - struct counter_count *count, u64 *val) + struct counter_count *count, unsigned long *val) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; u32 cnt; regmap_read(priv->regmap32, QPOSCNT, &cnt); @@ -105,9 +105,9 @@ static int ti_eqep_count_read(struct counter_device *counter, } static int ti_eqep_count_write(struct counter_device *counter, - struct counter_count *count, u64 val) + struct counter_count *count, unsigned long val) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; u32 max; regmap_read(priv->regmap32, QPOSMAX, &max); @@ -117,100 +117,64 @@ static int ti_eqep_count_write(struct counter_device *counter, return regmap_write(priv->regmap32, QPOSCNT, val); } -static int ti_eqep_function_read(struct counter_device *counter, - struct counter_count *count, - enum counter_function *function) +static int ti_eqep_function_get(struct counter_device *counter, + struct counter_count *count, size_t *function) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; u32 qdecctl; regmap_read(priv->regmap16, QDECCTL, &qdecctl); - - switch ((qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT) { - case TI_EQEP_COUNT_FUNC_QUAD_COUNT: - *function = COUNTER_FUNCTION_QUADRATURE_X4; - break; - case TI_EQEP_COUNT_FUNC_DIR_COUNT: - *function = COUNTER_FUNCTION_PULSE_DIRECTION; - break; - case TI_EQEP_COUNT_FUNC_UP_COUNT: - *function = COUNTER_FUNCTION_INCREASE; - break; - case TI_EQEP_COUNT_FUNC_DOWN_COUNT: - *function = COUNTER_FUNCTION_DECREASE; - break; - } + *function = (qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT; return 0; } -static int ti_eqep_function_write(struct counter_device *counter, - struct counter_count *count, - enum counter_function function) +static int ti_eqep_function_set(struct counter_device *counter, + struct counter_count *count, size_t function) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); - enum ti_eqep_count_func qsrc; - - switch (function) { - case COUNTER_FUNCTION_QUADRATURE_X4: - qsrc = TI_EQEP_COUNT_FUNC_QUAD_COUNT; - break; - case COUNTER_FUNCTION_PULSE_DIRECTION: - qsrc = TI_EQEP_COUNT_FUNC_DIR_COUNT; - break; - case COUNTER_FUNCTION_INCREASE: - qsrc = TI_EQEP_COUNT_FUNC_UP_COUNT; - break; - case COUNTER_FUNCTION_DECREASE: - qsrc = TI_EQEP_COUNT_FUNC_DOWN_COUNT; - break; - default: - /* should never reach this path */ - return -EINVAL; - } + struct ti_eqep_cnt *priv = counter->priv; return regmap_write_bits(priv->regmap16, QDECCTL, QDECCTL_QSRC, - qsrc << QDECCTL_QSRC_SHIFT); + function << QDECCTL_QSRC_SHIFT); } -static int ti_eqep_action_read(struct counter_device *counter, - struct counter_count *count, - struct counter_synapse *synapse, - enum counter_synapse_action *action) +static int ti_eqep_action_get(struct counter_device *counter, + struct counter_count *count, + struct counter_synapse *synapse, size_t *action) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); - enum counter_function function; + struct ti_eqep_cnt *priv = counter->priv; + size_t function; u32 qdecctl; int err; - err = ti_eqep_function_read(counter, count, &function); + err = ti_eqep_function_get(counter, count, &function); if (err) return err; switch (function) { - case COUNTER_FUNCTION_QUADRATURE_X4: + case TI_EQEP_COUNT_FUNC_QUAD_COUNT: /* In quadrature mode, the rising and falling edge of both * QEPA and QEPB trigger QCLK. */ - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; return 0; - case COUNTER_FUNCTION_PULSE_DIRECTION: + case TI_EQEP_COUNT_FUNC_DIR_COUNT: /* In direction-count mode only rising edge of QEPA is counted * and QEPB gives direction. */ switch (synapse->signal->id) { case TI_EQEP_SIGNAL_QEPA: - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; return 0; case TI_EQEP_SIGNAL_QEPB: - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = TI_EQEP_SYNAPSE_ACTION_NONE; return 0; default: /* should never reach this path */ return -EINVAL; } - case COUNTER_FUNCTION_INCREASE: - case COUNTER_FUNCTION_DECREASE: + case TI_EQEP_COUNT_FUNC_UP_COUNT: + case TI_EQEP_COUNT_FUNC_DOWN_COUNT: /* In up/down-count modes only QEPA is counted and QEPB is not * used. */ @@ -221,12 +185,12 @@ static int ti_eqep_action_read(struct counter_device *counter, return err; if (qdecctl & QDECCTL_XCR) - *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES; + *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES; else - *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE; + *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE; return 0; case TI_EQEP_SIGNAL_QEPB: - *action = COUNTER_SYNAPSE_ACTION_NONE; + *action = TI_EQEP_SYNAPSE_ACTION_NONE; return 0; default: /* should never reach this path */ @@ -241,67 +205,82 @@ static int ti_eqep_action_read(struct counter_device *counter, static const struct counter_ops ti_eqep_counter_ops = { .count_read = ti_eqep_count_read, .count_write = ti_eqep_count_write, - .function_read = ti_eqep_function_read, - .function_write = ti_eqep_function_write, - .action_read = ti_eqep_action_read, + .function_get = ti_eqep_function_get, + .function_set = ti_eqep_function_set, + .action_get = ti_eqep_action_get, }; -static int ti_eqep_position_ceiling_read(struct counter_device *counter, - struct counter_count *count, - u64 *ceiling) +static ssize_t ti_eqep_position_ceiling_read(struct counter_device *counter, + struct counter_count *count, + void *ext_priv, char *buf) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; u32 qposmax; regmap_read(priv->regmap32, QPOSMAX, &qposmax); - *ceiling = qposmax; - - return 0; + return sprintf(buf, "%u\n", qposmax); } -static int ti_eqep_position_ceiling_write(struct counter_device *counter, - struct counter_count *count, - u64 ceiling) +static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter, + struct counter_count *count, + void *ext_priv, const char *buf, + size_t len) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; + int err; + u32 res; - if (ceiling != (u32)ceiling) - return -ERANGE; + err = kstrtouint(buf, 0, &res); + if (err < 0) + return err; - regmap_write(priv->regmap32, QPOSMAX, ceiling); + regmap_write(priv->regmap32, QPOSMAX, res); - return 0; + return len; } -static int ti_eqep_position_enable_read(struct counter_device *counter, - struct counter_count *count, u8 *enable) +static ssize_t ti_eqep_position_enable_read(struct counter_device *counter, + struct counter_count *count, + void *ext_priv, char *buf) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; u32 qepctl; regmap_read(priv->regmap16, QEPCTL, &qepctl); - *enable = !!(qepctl & QEPCTL_PHEN); - - return 0; + return sprintf(buf, "%u\n", !!(qepctl & QEPCTL_PHEN)); } -static int ti_eqep_position_enable_write(struct counter_device *counter, - struct counter_count *count, u8 enable) +static ssize_t ti_eqep_position_enable_write(struct counter_device *counter, + struct counter_count *count, + void *ext_priv, const char *buf, + size_t len) { - struct ti_eqep_cnt *priv = ti_eqep_count_from_counter(counter); + struct ti_eqep_cnt *priv = counter->priv; + int err; + bool res; - regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, enable ? -1 : 0); + err = kstrtobool(buf, &res); + if (err < 0) + return err; - return 0; + regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, res ? -1 : 0); + + return len; } -static struct counter_comp ti_eqep_position_ext[] = { - COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read, - ti_eqep_position_ceiling_write), - COUNTER_COMP_ENABLE(ti_eqep_position_enable_read, - ti_eqep_position_enable_write), +static struct counter_count_ext ti_eqep_position_ext[] = { + { + .name = "ceiling", + .read = ti_eqep_position_ceiling_read, + .write = ti_eqep_position_ceiling_write, + }, + { + .name = "enable", + .read = ti_eqep_position_enable_read, + .write = ti_eqep_position_enable_write, + }, }; static struct counter_signal ti_eqep_signals[] = { @@ -316,16 +295,16 @@ static struct counter_signal ti_eqep_signals[] = { }; static const enum counter_function ti_eqep_position_functions[] = { - COUNTER_FUNCTION_QUADRATURE_X4, - COUNTER_FUNCTION_PULSE_DIRECTION, - COUNTER_FUNCTION_INCREASE, - COUNTER_FUNCTION_DECREASE, + [TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_FUNCTION_QUADRATURE_X4, + [TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_FUNCTION_PULSE_DIRECTION, + [TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_FUNCTION_INCREASE, + [TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_FUNCTION_DECREASE, }; static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = { - COUNTER_SYNAPSE_ACTION_BOTH_EDGES, - COUNTER_SYNAPSE_ACTION_RISING_EDGE, - COUNTER_SYNAPSE_ACTION_NONE, + [TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES, + [TI_EQEP_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE, + [TI_EQEP_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE, }; static struct counter_synapse ti_eqep_position_synapses[] = { @@ -373,15 +352,13 @@ static const struct regmap_config ti_eqep_regmap16_config = { static int ti_eqep_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct counter_device *counter; struct ti_eqep_cnt *priv; void __iomem *base; int err; - counter = devm_counter_alloc(dev, sizeof(*priv)); - if (!counter) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = counter_priv(counter); base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) @@ -397,15 +374,16 @@ static int ti_eqep_probe(struct platform_device *pdev) if (IS_ERR(priv->regmap16)) return PTR_ERR(priv->regmap16); - counter->name = dev_name(dev); - counter->parent = dev; - counter->ops = &ti_eqep_counter_ops; - counter->counts = ti_eqep_counts; - counter->num_counts = ARRAY_SIZE(ti_eqep_counts); - counter->signals = ti_eqep_signals; - counter->num_signals = ARRAY_SIZE(ti_eqep_signals); + priv->counter.name = dev_name(dev); + priv->counter.parent = dev; + priv->counter.ops = &ti_eqep_counter_ops; + priv->counter.counts = ti_eqep_counts; + priv->counter.num_counts = ARRAY_SIZE(ti_eqep_counts); + priv->counter.signals = ti_eqep_signals; + priv->counter.num_signals = ARRAY_SIZE(ti_eqep_signals); + priv->counter.priv = priv; - platform_set_drvdata(pdev, counter); + platform_set_drvdata(pdev, priv); /* * Need to make sure power is turned on. On AM33xx, this comes from the @@ -415,7 +393,7 @@ static int ti_eqep_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_runtime_get_sync(dev); - err = counter_add(counter); + err = counter_register(&priv->counter); if (err < 0) { pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -427,10 +405,10 @@ static int ti_eqep_probe(struct platform_device *pdev) static int ti_eqep_remove(struct platform_device *pdev) { - struct counter_device *counter = platform_get_drvdata(pdev); + struct ti_eqep_cnt *priv = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; - counter_unregister(counter); + counter_unregister(&priv->counter); pm_runtime_put_sync(dev); pm_runtime_disable(dev); diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 15d6c46c0a..334f83e561 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm @@ -99,7 +99,7 @@ config ARM_MVEBU_V7_CPUIDLE config ARM_TEGRA_CPUIDLE bool "CPU Idle Driver for NVIDIA Tegra SoCs" - depends on (ARCH_TEGRA || COMPILE_TEST) && !ARM64 && MMU + depends on ARCH_TEGRA && !ARM64 select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP select ARM_CPU_SUSPEND help @@ -112,7 +112,6 @@ config ARM_QCOM_SPM_CPUIDLE select CPU_IDLE_MULTIPLE_DRIVERS select DT_IDLE_STATES select QCOM_SCM - select QCOM_SPM help Select this to enable cpuidle for Qualcomm processors. The Subsystem Power Manager (SPM) controls low power modes for the diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c index 01e77913a4..c0e7971da2 100644 --- a/drivers/cpuidle/cpuidle-qcom-spm.c +++ b/drivers/cpuidle/cpuidle-qcom-spm.c @@ -18,18 +18,158 @@ #include #include #include -#include #include #include #include "dt_idle_states.h" -struct cpuidle_qcom_spm_data { - struct cpuidle_driver cpuidle_driver; - struct spm_driver_data *spm; +#define MAX_PMIC_DATA 2 +#define MAX_SEQ_DATA 64 +#define SPM_CTL_INDEX 0x7f +#define SPM_CTL_INDEX_SHIFT 4 +#define SPM_CTL_EN BIT(0) + +enum pm_sleep_mode { + PM_SLEEP_MODE_STBY, + PM_SLEEP_MODE_RET, + PM_SLEEP_MODE_SPC, + PM_SLEEP_MODE_PC, + PM_SLEEP_MODE_NR, }; +enum spm_reg { + SPM_REG_CFG, + SPM_REG_SPM_CTL, + SPM_REG_DLY, + SPM_REG_PMIC_DLY, + SPM_REG_PMIC_DATA_0, + SPM_REG_PMIC_DATA_1, + SPM_REG_VCTL, + SPM_REG_SEQ_ENTRY, + SPM_REG_SPM_STS, + SPM_REG_PMIC_STS, + SPM_REG_NR, +}; + +struct spm_reg_data { + const u8 *reg_offset; + u32 spm_cfg; + u32 spm_dly; + u32 pmic_dly; + u32 pmic_data[MAX_PMIC_DATA]; + u8 seq[MAX_SEQ_DATA]; + u8 start_index[PM_SLEEP_MODE_NR]; +}; + +struct spm_driver_data { + struct cpuidle_driver cpuidle_driver; + void __iomem *reg_base; + const struct spm_reg_data *reg_data; +}; + +static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = { + [SPM_REG_CFG] = 0x08, + [SPM_REG_SPM_CTL] = 0x30, + [SPM_REG_DLY] = 0x34, + [SPM_REG_SEQ_ENTRY] = 0x80, +}; + +/* SPM register data for 8974, 8084 */ +static const struct spm_reg_data spm_reg_8974_8084_cpu = { + .reg_offset = spm_reg_offset_v2_1, + .spm_cfg = 0x1, + .spm_dly = 0x3C102800, + .seq = { 0x03, 0x0B, 0x0F, 0x00, 0x20, 0x80, 0x10, 0xE8, 0x5B, 0x03, + 0x3B, 0xE8, 0x5B, 0x82, 0x10, 0x0B, 0x30, 0x06, 0x26, 0x30, + 0x0F }, + .start_index[PM_SLEEP_MODE_STBY] = 0, + .start_index[PM_SLEEP_MODE_SPC] = 3, +}; + +/* SPM register data for 8226 */ +static const struct spm_reg_data spm_reg_8226_cpu = { + .reg_offset = spm_reg_offset_v2_1, + .spm_cfg = 0x0, + .spm_dly = 0x3C102800, + .seq = { 0x60, 0x03, 0x60, 0x0B, 0x0F, 0x20, 0x10, 0x80, 0x30, 0x90, + 0x5B, 0x60, 0x03, 0x60, 0x3B, 0x76, 0x76, 0x0B, 0x94, 0x5B, + 0x80, 0x10, 0x26, 0x30, 0x0F }, + .start_index[PM_SLEEP_MODE_STBY] = 0, + .start_index[PM_SLEEP_MODE_SPC] = 5, +}; + +static const u8 spm_reg_offset_v1_1[SPM_REG_NR] = { + [SPM_REG_CFG] = 0x08, + [SPM_REG_SPM_CTL] = 0x20, + [SPM_REG_PMIC_DLY] = 0x24, + [SPM_REG_PMIC_DATA_0] = 0x28, + [SPM_REG_PMIC_DATA_1] = 0x2C, + [SPM_REG_SEQ_ENTRY] = 0x80, +}; + +/* SPM register data for 8064 */ +static const struct spm_reg_data spm_reg_8064_cpu = { + .reg_offset = spm_reg_offset_v1_1, + .spm_cfg = 0x1F, + .pmic_dly = 0x02020004, + .pmic_data[0] = 0x0084009C, + .pmic_data[1] = 0x00A4001C, + .seq = { 0x03, 0x0F, 0x00, 0x24, 0x54, 0x10, 0x09, 0x03, 0x01, + 0x10, 0x54, 0x30, 0x0C, 0x24, 0x30, 0x0F }, + .start_index[PM_SLEEP_MODE_STBY] = 0, + .start_index[PM_SLEEP_MODE_SPC] = 2, +}; + +static inline void spm_register_write(struct spm_driver_data *drv, + enum spm_reg reg, u32 val) +{ + if (drv->reg_data->reg_offset[reg]) + writel_relaxed(val, drv->reg_base + + drv->reg_data->reg_offset[reg]); +} + +/* Ensure a guaranteed write, before return */ +static inline void spm_register_write_sync(struct spm_driver_data *drv, + enum spm_reg reg, u32 val) +{ + u32 ret; + + if (!drv->reg_data->reg_offset[reg]) + return; + + do { + writel_relaxed(val, drv->reg_base + + drv->reg_data->reg_offset[reg]); + ret = readl_relaxed(drv->reg_base + + drv->reg_data->reg_offset[reg]); + if (ret == val) + break; + cpu_relax(); + } while (1); +} + +static inline u32 spm_register_read(struct spm_driver_data *drv, + enum spm_reg reg) +{ + return readl_relaxed(drv->reg_base + drv->reg_data->reg_offset[reg]); +} + +static void spm_set_low_power_mode(struct spm_driver_data *drv, + enum pm_sleep_mode mode) +{ + u32 start_index; + u32 ctl_val; + + start_index = drv->reg_data->start_index[mode]; + + ctl_val = spm_register_read(drv, SPM_REG_SPM_CTL); + ctl_val &= ~(SPM_CTL_INDEX << SPM_CTL_INDEX_SHIFT); + ctl_val |= start_index << SPM_CTL_INDEX_SHIFT; + ctl_val |= SPM_CTL_EN; + spm_register_write_sync(drv, SPM_REG_SPM_CTL, ctl_val); +} + static int qcom_pm_collapse(unsigned long int unused) { qcom_scm_cpu_power_down(QCOM_SCM_CPU_PWR_DOWN_L2_ON); @@ -61,10 +201,10 @@ static int qcom_cpu_spc(struct spm_driver_data *drv) static int spm_enter_idle_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) { - struct cpuidle_qcom_spm_data *data = container_of(drv, struct cpuidle_qcom_spm_data, - cpuidle_driver); + struct spm_driver_data *data = container_of(drv, struct spm_driver_data, + cpuidle_driver); - return CPU_PM_CPU_IDLE_ENTER_PARAM(qcom_cpu_spc, idx, data->spm); + return CPU_PM_CPU_IDLE_ENTER_PARAM(qcom_cpu_spc, idx, data); } static struct cpuidle_driver qcom_spm_idle_driver = { @@ -85,92 +225,134 @@ static const struct of_device_id qcom_idle_state_match[] = { { }, }; -static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu) +static int spm_cpuidle_init(struct cpuidle_driver *drv, int cpu) { - struct platform_device *pdev = NULL; - struct device_node *cpu_node, *saw_node; - struct cpuidle_qcom_spm_data *data = NULL; int ret; - cpu_node = of_cpu_device_node_get(cpu); - if (!cpu_node) - return -ENODEV; + memcpy(drv, &qcom_spm_idle_driver, sizeof(*drv)); + drv->cpumask = (struct cpumask *)cpumask_of(cpu); - saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); - if (!saw_node) - return -ENODEV; - - pdev = of_find_device_by_node(saw_node); - of_node_put(saw_node); - of_node_put(cpu_node); - if (!pdev) - return -ENODEV; - - data = devm_kzalloc(cpuidle_dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->spm = dev_get_drvdata(&pdev->dev); - if (!data->spm) - return -EINVAL; - - data->cpuidle_driver = qcom_spm_idle_driver; - data->cpuidle_driver.cpumask = (struct cpumask *)cpumask_of(cpu); - - ret = dt_init_idle_driver(&data->cpuidle_driver, - qcom_idle_state_match, 1); + /* Parse idle states from device tree */ + ret = dt_init_idle_driver(drv, qcom_idle_state_match, 1); if (ret <= 0) return ret ? : -ENODEV; - ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu)); - if (ret) - return ret; - - return cpuidle_register(&data->cpuidle_driver, NULL); + /* We have atleast one power down mode */ + return qcom_scm_set_warm_boot_addr(cpu_resume_arm, drv->cpumask); } -static int spm_cpuidle_drv_probe(struct platform_device *pdev) +static struct spm_driver_data *spm_get_drv(struct platform_device *pdev, + int *spm_cpu) { + struct spm_driver_data *drv = NULL; + struct device_node *cpu_node, *saw_node; + int cpu; + bool found = 0; + + for_each_possible_cpu(cpu) { + cpu_node = of_cpu_device_node_get(cpu); + if (!cpu_node) + continue; + saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); + found = (saw_node == pdev->dev.of_node); + of_node_put(saw_node); + of_node_put(cpu_node); + if (found) + break; + } + + if (found) { + drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); + if (drv) + *spm_cpu = cpu; + } + + return drv; +} + +static const struct of_device_id spm_match_table[] = { + { .compatible = "qcom,msm8226-saw2-v2.1-cpu", + .data = &spm_reg_8226_cpu }, + { .compatible = "qcom,msm8974-saw2-v2.1-cpu", + .data = &spm_reg_8974_8084_cpu }, + { .compatible = "qcom,apq8084-saw2-v2.1-cpu", + .data = &spm_reg_8974_8084_cpu }, + { .compatible = "qcom,apq8064-saw2-v1.1-cpu", + .data = &spm_reg_8064_cpu }, + { }, +}; + +static int spm_dev_probe(struct platform_device *pdev) +{ + struct spm_driver_data *drv; + struct resource *res; + const struct of_device_id *match_id; + void __iomem *addr; int cpu, ret; if (!qcom_scm_is_available()) return -EPROBE_DEFER; - for_each_possible_cpu(cpu) { - ret = spm_cpuidle_register(&pdev->dev, cpu); - if (ret && ret != -ENODEV) { - dev_err(&pdev->dev, - "Cannot register for CPU%d: %d\n", cpu, ret); - } - } + drv = spm_get_drv(pdev, &cpu); + if (!drv) + return -EINVAL; + platform_set_drvdata(pdev, drv); - return 0; -} + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + drv->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(drv->reg_base)) + return PTR_ERR(drv->reg_base); -static struct platform_driver spm_cpuidle_driver = { - .probe = spm_cpuidle_drv_probe, - .driver = { - .name = "qcom-spm-cpuidle", - .suppress_bind_attrs = true, - }, -}; + match_id = of_match_node(spm_match_table, pdev->dev.of_node); + if (!match_id) + return -ENODEV; -static int __init qcom_spm_cpuidle_init(void) -{ - struct platform_device *pdev; - int ret; + drv->reg_data = match_id->data; - ret = platform_driver_register(&spm_cpuidle_driver); + ret = spm_cpuidle_init(&drv->cpuidle_driver, cpu); if (ret) return ret; - pdev = platform_device_register_simple("qcom-spm-cpuidle", - -1, NULL, 0); - if (IS_ERR(pdev)) { - platform_driver_unregister(&spm_cpuidle_driver); - return PTR_ERR(pdev); - } + /* Write the SPM sequences first.. */ + addr = drv->reg_base + drv->reg_data->reg_offset[SPM_REG_SEQ_ENTRY]; + __iowrite32_copy(addr, drv->reg_data->seq, + ARRAY_SIZE(drv->reg_data->seq) / 4); + /* + * ..and then the control registers. + * On some SoC if the control registers are written first and if the + * CPU was held in reset, the reset signal could trigger the SPM state + * machine, before the sequences are completely written. + */ + spm_register_write(drv, SPM_REG_CFG, drv->reg_data->spm_cfg); + spm_register_write(drv, SPM_REG_DLY, drv->reg_data->spm_dly); + spm_register_write(drv, SPM_REG_PMIC_DLY, drv->reg_data->pmic_dly); + spm_register_write(drv, SPM_REG_PMIC_DATA_0, + drv->reg_data->pmic_data[0]); + spm_register_write(drv, SPM_REG_PMIC_DATA_1, + drv->reg_data->pmic_data[1]); + + /* Set up Standby as the default low power mode */ + spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY); + + return cpuidle_register(&drv->cpuidle_driver, NULL); +} + +static int spm_dev_remove(struct platform_device *pdev) +{ + struct spm_driver_data *drv = platform_get_drvdata(pdev); + + cpuidle_unregister(&drv->cpuidle_driver); return 0; } -device_initcall(qcom_spm_cpuidle_init); + +static struct platform_driver spm_driver = { + .probe = spm_dev_probe, + .remove = spm_dev_remove, + .driver = { + .name = "saw", + .of_match_table = spm_match_table, + }, +}; + +builtin_platform_driver(spm_driver); diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c index 9845629aeb..508bd9f237 100644 --- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -337,9 +337,6 @@ static void tegra_cpuidle_setup_tegra114_c7_state(void) static int tegra_cpuidle_probe(struct platform_device *pdev) { - if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NOT_READY) - return -EPROBE_DEFER; - /* LP2 could be disabled in device-tree */ if (tegra_pmc_get_suspend_mode() < TEGRA_SUSPEND_LP2) tegra_cpuidle_disable_state(TEGRA_CC6); diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c4922684f3..2e56704469 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -34,7 +34,7 @@ * 1) Energy break even point * 2) Performance impact * 3) Latency tolerance (from pmqos infrastructure) - * These three factors are treated independently. + * These these three factors are treated independently. * * Energy break even point * ----------------------- diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 2b496a53cb..469e18547d 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -335,7 +335,6 @@ static struct attribute *cpuidle_state_default_attrs[] = { &attr_default_status.attr, NULL }; -ATTRIBUTE_GROUPS(cpuidle_state_default); struct cpuidle_state_kobj { struct cpuidle_state *state; @@ -449,7 +448,7 @@ static void cpuidle_state_sysfs_release(struct kobject *kobj) static struct kobj_type ktype_state_cpuidle = { .sysfs_ops = &cpuidle_state_sysfs_ops, - .default_groups = cpuidle_state_default_groups, + .default_attrs = cpuidle_state_default_attrs, .release = cpuidle_state_sysfs_release, }; @@ -506,7 +505,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) } /** - * cpuidle_remove_state_sysfs - removes the cpuidle states sysfs attributes + * cpuidle_remove_driver_sysfs - removes the cpuidle states sysfs attributes * @device: the target device */ static void cpuidle_remove_state_sysfs(struct cpuidle_device *device) @@ -592,11 +591,10 @@ static struct attribute *cpuidle_driver_default_attrs[] = { &attr_driver_name.attr, NULL }; -ATTRIBUTE_GROUPS(cpuidle_driver_default); static struct kobj_type ktype_driver_cpuidle = { .sysfs_ops = &cpuidle_driver_sysfs_ops, - .default_groups = cpuidle_driver_default_groups, + .default_attrs = cpuidle_driver_default_attrs, .release = cpuidle_driver_sysfs_release, }; diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 4f705674f9..51690e7315 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -213,18 +213,6 @@ config CRYPTO_AES_S390 key sizes and XTS mode is hardware accelerated for 256 and 512 bit keys. -config CRYPTO_CHACHA_S390 - tristate "ChaCha20 stream cipher" - depends on S390 - select CRYPTO_ALGAPI - select CRYPTO_SKCIPHER - select CRYPTO_CHACHA20 - help - This is the s390 SIMD implementation of the ChaCha20 stream - cipher (RFC 7539). - - It is available as of z13. - config S390_PRNG tristate "Pseudo random number generator device driver" depends on S390 diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index d8623c7e0d..00194d1d9a 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -106,24 +106,6 @@ static const struct ce_variant ce_a64_variant = { .trng = CE_ID_NOTSUPP, }; -static const struct ce_variant ce_d1_variant = { - .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, - }, - .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, - CE_ALG_SHA384, CE_ALG_SHA512 - }, - .op_mode = { CE_OP_ECB, CE_OP_CBC - }, - .ce_clks = { - { "bus", 0, 200000000 }, - { "mod", 300000000, 0 }, - { "ram", 0, 400000000 }, - }, - .esr = ESR_D1, - .prng = CE_ALG_PRNG, - .trng = CE_ALG_TRNG, -}; - static const struct ce_variant ce_r40_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, @@ -210,7 +192,6 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) dev_err(ce->dev, "CE ERROR: keysram access error for AES\n"); break; case ESR_A64: - case ESR_D1: case ESR_H5: case ESR_R40: v >>= (flow * 4); @@ -1009,8 +990,6 @@ static const struct of_device_id sun8i_ce_crypto_of_match_table[] = { .data = &ce_h3_variant }, { .compatible = "allwinner,sun8i-r40-crypto", .data = &ce_r40_variant }, - { .compatible = "allwinner,sun20i-d1-crypto", - .data = &ce_d1_variant }, { .compatible = "allwinner,sun50i-a64-crypto", .data = &ce_a64_variant }, { .compatible = "allwinner,sun50i-h5-crypto", diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h index 624a5926f2..cec781d506 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h @@ -94,7 +94,6 @@ #define ESR_R40 2 #define ESR_H5 3 #define ESR_H6 4 -#define ESR_D1 5 #define PRNG_DATA_SIZE (160 / 8) #define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8) diff --git a/drivers/crypto/cavium/cpt/cptvf_main.c b/drivers/crypto/cavium/cpt/cptvf_main.c index c246920e6f..112b12a325 100644 --- a/drivers/crypto/cavium/cpt/cptvf_main.c +++ b/drivers/crypto/cavium/cpt/cptvf_main.c @@ -104,14 +104,17 @@ static int alloc_pending_queues(struct pending_qinfo *pqinfo, u32 qlen, u32 nr_queues) { u32 i; + size_t size; int ret; struct pending_queue *queue = NULL; pqinfo->nr_queues = nr_queues; pqinfo->qlen = qlen; + size = (qlen * sizeof(struct pending_entry)); + for_each_pending_queue(pqinfo, queue, i) { - queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL); + queue->head = kzalloc((size), GFP_KERNEL); if (!queue->head) { ret = -ENOMEM; goto pending_qfail; diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index fe69053b23..0d5576f6ad 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -467,8 +467,8 @@ static int ccp_init(struct ccp_device *ccp) cmd_q = &ccp->cmd_q[i]; - kthread = kthread_run(ccp_cmd_queue_thread, cmd_q, - "%s-q%u", ccp->name, cmd_q->id); + kthread = kthread_create(ccp_cmd_queue_thread, cmd_q, + "%s-q%u", ccp->name, cmd_q->id); if (IS_ERR(kthread)) { dev_err(dev, "error creating queue thread (%ld)\n", PTR_ERR(kthread)); @@ -477,6 +477,7 @@ static int ccp_init(struct ccp_device *ccp) } cmd_q->kthread = kthread; + wake_up_process(kthread); } dev_dbg(dev, "Enabling interrupts...\n"); diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 7b73332d6a..7838f63bab 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -950,8 +950,8 @@ static int ccp5_init(struct ccp_device *ccp) cmd_q = &ccp->cmd_q[i]; - kthread = kthread_run(ccp_cmd_queue_thread, cmd_q, - "%s-q%u", ccp->name, cmd_q->id); + kthread = kthread_create(ccp_cmd_queue_thread, cmd_q, + "%s-q%u", ccp->name, cmd_q->id); if (IS_ERR(kthread)) { dev_err(dev, "error creating queue thread (%ld)\n", PTR_ERR(kthread)); @@ -960,6 +960,7 @@ static int ccp5_init(struct ccp_device *ccp) } cmd_q->kthread = kthread; + wake_up_process(kthread); } dev_dbg(dev, "Enabling interrupts...\n"); diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index c531d13d97..9ce4b68e9c 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -31,7 +31,7 @@ #define MAX_CCPS 32 /* Limit CCP use to a specifed number of queues per device */ -static unsigned int nqueues; +static unsigned int nqueues = 0; module_param(nqueues, uint, 0444); MODULE_PARM_DESC(nqueues, "Number of queues per CCP (minimum 1; default: all available)"); diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 8fd774a10e..e2806ca330 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -44,14 +43,6 @@ static int psp_probe_timeout = 5; module_param(psp_probe_timeout, int, 0644); MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe"); -static char *init_ex_path; -module_param(init_ex_path, charp, 0444); -MODULE_PARM_DESC(init_ex_path, " Path for INIT_EX data; if set try INIT_EX"); - -static bool psp_init_on_probe = true; -module_param(psp_init_on_probe, bool, 0444); -MODULE_PARM_DESC(psp_init_on_probe, " if true, the PSP will be initialized on module init. Else the PSP will be initialized on the first command requiring it"); - MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ @@ -67,14 +58,6 @@ static int psp_timeout; #define SEV_ES_TMR_SIZE (1024 * 1024) static void *sev_es_tmr; -/* INIT_EX NV Storage: - * The NV Storage is a 32Kb area and must be 4Kb page aligned. Use the page - * allocator to allocate the memory, which will return aligned memory for the - * specified allocation order. - */ -#define NV_LENGTH (32 * 1024) -static void *sev_init_ex_buffer; - static inline bool sev_version_greater_or_equal(u8 maj, u8 min) { struct sev_device *sev = psp_master->sev_data; @@ -124,7 +107,6 @@ static int sev_cmd_buffer_len(int cmd) { switch (cmd) { case SEV_CMD_INIT: return sizeof(struct sev_data_init); - case SEV_CMD_INIT_EX: return sizeof(struct sev_data_init_ex); case SEV_CMD_PLATFORM_STATUS: return sizeof(struct sev_user_data_status); case SEV_CMD_PEK_CSR: return sizeof(struct sev_data_pek_csr); case SEV_CMD_PEK_CERT_IMPORT: return sizeof(struct sev_data_pek_cert_import); @@ -152,119 +134,13 @@ static int sev_cmd_buffer_len(int cmd) case SEV_CMD_DOWNLOAD_FIRMWARE: return sizeof(struct sev_data_download_firmware); case SEV_CMD_GET_ID: return sizeof(struct sev_data_get_id); case SEV_CMD_ATTESTATION_REPORT: return sizeof(struct sev_data_attestation_report); - case SEV_CMD_SEND_CANCEL: return sizeof(struct sev_data_send_cancel); + case SEV_CMD_SEND_CANCEL: return sizeof(struct sev_data_send_cancel); default: return 0; } return 0; } -static void *sev_fw_alloc(unsigned long len) -{ - struct page *page; - - page = alloc_pages(GFP_KERNEL, get_order(len)); - if (!page) - return NULL; - - return page_address(page); -} - -static int sev_read_init_ex_file(void) -{ - struct sev_device *sev = psp_master->sev_data; - struct file *fp; - ssize_t nread; - - lockdep_assert_held(&sev_cmd_mutex); - - if (!sev_init_ex_buffer) - return -EOPNOTSUPP; - - fp = filp_open(init_ex_path, O_RDONLY, 0); - if (IS_ERR(fp)) { - int ret = PTR_ERR(fp); - - dev_err(sev->dev, - "SEV: could not open %s for read, error %d\n", - init_ex_path, ret); - return ret; - } - - nread = kernel_read(fp, sev_init_ex_buffer, NV_LENGTH, NULL); - if (nread != NV_LENGTH) { - dev_err(sev->dev, - "SEV: failed to read %u bytes to non volatile memory area, ret %ld\n", - NV_LENGTH, nread); - return -EIO; - } - - dev_dbg(sev->dev, "SEV: read %ld bytes from NV file\n", nread); - filp_close(fp, NULL); - - return 0; -} - -static void sev_write_init_ex_file(void) -{ - struct sev_device *sev = psp_master->sev_data; - struct file *fp; - loff_t offset = 0; - ssize_t nwrite; - - lockdep_assert_held(&sev_cmd_mutex); - - if (!sev_init_ex_buffer) - return; - - fp = filp_open(init_ex_path, O_CREAT | O_WRONLY, 0600); - if (IS_ERR(fp)) { - dev_err(sev->dev, - "SEV: could not open file for write, error %ld\n", - PTR_ERR(fp)); - return; - } - - nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset); - vfs_fsync(fp, 0); - filp_close(fp, NULL); - - if (nwrite != NV_LENGTH) { - dev_err(sev->dev, - "SEV: failed to write %u bytes to non volatile memory area, ret %ld\n", - NV_LENGTH, nwrite); - return; - } - - dev_dbg(sev->dev, "SEV: write successful to NV file\n"); -} - -static void sev_write_init_ex_file_if_required(int cmd_id) -{ - lockdep_assert_held(&sev_cmd_mutex); - - if (!sev_init_ex_buffer) - return; - - /* - * Only a few platform commands modify the SPI/NV area, but none of the - * non-platform commands do. Only INIT(_EX), PLATFORM_RESET, PEK_GEN, - * PEK_CERT_IMPORT, and PDH_GEN do. - */ - switch (cmd_id) { - case SEV_CMD_FACTORY_RESET: - case SEV_CMD_INIT_EX: - case SEV_CMD_PDH_GEN: - case SEV_CMD_PEK_CERT_IMPORT: - case SEV_CMD_PEK_GEN: - break; - default: - return; - } - - sev_write_init_ex_file(); -} - static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) { struct psp_device *psp = psp_master; @@ -334,8 +210,6 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret) dev_dbg(sev->dev, "sev command %#x failed (%#010x)\n", cmd, reg & PSP_CMDRESP_ERR_MASK); ret = -EIO; - } else { - sev_write_init_ex_file_if_required(cmd); } print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, @@ -362,59 +236,12 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret) return rc; } -static int __sev_init_locked(int *error) -{ - struct sev_data_init data; - - memset(&data, 0, sizeof(data)); - if (sev_es_tmr) { - /* - * Do not include the encryption mask on the physical - * address of the TMR (firmware should clear it anyway). - */ - data.tmr_address = __pa(sev_es_tmr); - - data.flags |= SEV_INIT_FLAGS_SEV_ES; - data.tmr_len = SEV_ES_TMR_SIZE; - } - - return __sev_do_cmd_locked(SEV_CMD_INIT, &data, error); -} - -static int __sev_init_ex_locked(int *error) -{ - struct sev_data_init_ex data; - int ret; - - memset(&data, 0, sizeof(data)); - data.length = sizeof(data); - data.nv_address = __psp_pa(sev_init_ex_buffer); - data.nv_len = NV_LENGTH; - - ret = sev_read_init_ex_file(); - if (ret) - return ret; - - if (sev_es_tmr) { - /* - * Do not include the encryption mask on the physical - * address of the TMR (firmware should clear it anyway). - */ - data.tmr_address = __pa(sev_es_tmr); - - data.flags |= SEV_INIT_FLAGS_SEV_ES; - data.tmr_len = SEV_ES_TMR_SIZE; - } - - return __sev_do_cmd_locked(SEV_CMD_INIT_EX, &data, error); -} - static int __sev_platform_init_locked(int *error) { struct psp_device *psp = psp_master; + struct sev_data_init data; struct sev_device *sev; - int rc, psp_ret; - int (*init_function)(int *error); + int psp_ret, rc = 0; if (!psp || !psp->sev_data) return -ENODEV; @@ -424,9 +251,22 @@ static int __sev_platform_init_locked(int *error) if (sev->state == SEV_STATE_INIT) return 0; - init_function = sev_init_ex_buffer ? __sev_init_ex_locked : - __sev_init_locked; - rc = init_function(&psp_ret); + memset(&data, 0, sizeof(data)); + if (sev_es_tmr) { + u64 tmr_pa; + + /* + * Do not include the encryption mask on the physical + * address of the TMR (firmware should clear it anyway). + */ + tmr_pa = __pa(sev_es_tmr); + + data.flags |= SEV_INIT_FLAGS_SEV_ES; + data.tmr_address = tmr_pa; + data.tmr_len = SEV_ES_TMR_SIZE; + } + + rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { /* * Initialization command returned an integrity check failure @@ -436,7 +276,7 @@ static int __sev_platform_init_locked(int *error) * with a reset state. */ dev_dbg(sev->dev, "SEV: retrying INIT command"); - rc = init_function(&psp_ret); + rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); } if (error) *error = psp_ret; @@ -454,10 +294,7 @@ static int __sev_platform_init_locked(int *error) dev_dbg(sev->dev, "SEV firmware initialized\n"); - dev_info(sev->dev, "SEV API:%d.%d build:%d\n", sev->api_major, - sev->api_minor, sev->build); - - return 0; + return rc; } int sev_platform_init(int *error) @@ -1211,12 +1048,6 @@ static void sev_firmware_shutdown(struct sev_device *sev) get_order(SEV_ES_TMR_SIZE)); sev_es_tmr = NULL; } - - if (sev_init_ex_buffer) { - free_pages((unsigned long)sev_init_ex_buffer, - get_order(NV_LENGTH)); - sev_init_ex_buffer = NULL; - } } void sev_dev_destroy(struct psp_device *psp) @@ -1247,6 +1078,7 @@ EXPORT_SYMBOL_GPL(sev_issue_cmd_external_user); void sev_pci_init(void) { struct sev_device *sev = psp_master->sev_data; + struct page *tmr_page; int error, rc; if (!sev) @@ -1261,32 +1093,25 @@ void sev_pci_init(void) sev_update_firmware(sev->dev) == 0) sev_get_api_version(); - /* If an init_ex_path is provided rely on INIT_EX for PSP initialization - * instead of INIT. - */ - if (init_ex_path) { - sev_init_ex_buffer = sev_fw_alloc(NV_LENGTH); - if (!sev_init_ex_buffer) { - dev_err(sev->dev, - "SEV: INIT_EX NV memory allocation failed\n"); - goto err; - } - } - /* Obtain the TMR memory area for SEV-ES use */ - sev_es_tmr = sev_fw_alloc(SEV_ES_TMR_SIZE); - if (!sev_es_tmr) + tmr_page = alloc_pages(GFP_KERNEL, get_order(SEV_ES_TMR_SIZE)); + if (tmr_page) { + sev_es_tmr = page_address(tmr_page); + } else { + sev_es_tmr = NULL; dev_warn(sev->dev, "SEV: TMR allocation failed, SEV-ES support unavailable\n"); - - if (!psp_init_on_probe) - return; + } /* Initialize the platform */ rc = sev_platform_init(&error); - if (rc) - dev_err(sev->dev, "SEV: failed to INIT error %#x, rc %d\n", - error, rc); + if (rc) { + dev_err(sev->dev, "SEV: failed to INIT error %#x\n", error); + return; + } + + dev_info(sev->dev, "SEV API:%d.%d build:%d\n", sev->api_major, + sev->api_minor, sev->build); return; diff --git a/drivers/crypto/ccree/cc_request_mgr.c b/drivers/crypto/ccree/cc_request_mgr.c index 887162df50..33fb27745d 100644 --- a/drivers/crypto/ccree/cc_request_mgr.c +++ b/drivers/crypto/ccree/cc_request_mgr.c @@ -101,6 +101,7 @@ void cc_req_mgr_fini(struct cc_drvdata *drvdata) dev_dbg(dev, "max_used_sw_slots=%d\n", req_mgr_h->max_used_sw_slots); #ifdef COMP_IN_WQ + flush_workqueue(req_mgr_h->workq); destroy_workqueue(req_mgr_h->workq); #else /* Kill tasklet */ diff --git a/drivers/crypto/chelsio/chcr_crypto.h b/drivers/crypto/chelsio/chcr_crypto.h index c7816c83e3..e89f9e0094 100644 --- a/drivers/crypto/chelsio/chcr_crypto.h +++ b/drivers/crypto/chelsio/chcr_crypto.h @@ -222,10 +222,8 @@ struct chcr_authenc_ctx { }; struct __aead_ctx { - union { - DECLARE_FLEX_ARRAY(struct chcr_gcm_ctx, gcm); - DECLARE_FLEX_ARRAY(struct chcr_authenc_ctx, authenc); - }; + struct chcr_gcm_ctx gcm[0]; + struct chcr_authenc_ctx authenc[]; }; struct chcr_aead_ctx { @@ -247,11 +245,9 @@ struct hmac_ctx { }; struct __crypto_ctx { - union { - DECLARE_FLEX_ARRAY(struct hmac_ctx, hmacctx); - DECLARE_FLEX_ARRAY(struct ablk_ctx, ablkctx); - DECLARE_FLEX_ARRAY(struct chcr_aead_ctx, aeadctx); - }; + struct hmac_ctx hmacctx[0]; + struct ablk_ctx ablkctx[0]; + struct chcr_aead_ctx aeadctx[]; }; struct chcr_context { diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c index 97d54c1465..7ba7641723 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -1177,10 +1177,13 @@ static void hpre_rsa_exit_tfm(struct crypto_akcipher *tfm) static void hpre_key_to_big_end(u8 *data, int len) { int i, j; + u8 tmp; for (i = 0; i < len / 2; i++) { j = len - i - 1; - swap(data[j], data[i]); + tmp = data[j]; + data[j] = data[i]; + data[i] = tmp; } } diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index c5b84a5ea3..ff1122153f 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -89,10 +89,6 @@ #define QM_AEQE_PHASE(aeqe) ((le32_to_cpu((aeqe)->dw0) >> 16) & 0x1) #define QM_AEQE_TYPE_SHIFT 17 -#define QM_AEQE_CQN_MASK GENMASK(15, 0) -#define QM_CQ_OVERFLOW 0 -#define QM_EQ_OVERFLOW 1 -#define QM_CQE_ERROR 2 #define QM_DOORBELL_CMD_SQ 0 #define QM_DOORBELL_CMD_CQ 1 @@ -126,8 +122,6 @@ #define QM_CQC_VFT 0x1 #define QM_VFT_CFG 0x100060 #define QM_VFT_CFG_OP_ENABLE 0x100054 -#define QM_PM_CTRL 0x100148 -#define QM_IDLE_DISABLE BIT(9) #define QM_VFT_CFG_DATA_L 0x100064 #define QM_VFT_CFG_DATA_H 0x100068 @@ -239,8 +233,6 @@ #define QM_DBG_WRITE_LEN 1024 #define QM_DBG_TMP_BUF_LEN 22 #define QM_PCI_COMMAND_INVALID ~0 -#define QM_RESET_STOP_TX_OFFSET 1 -#define QM_RESET_STOP_RX_OFFSET 2 #define WAIT_PERIOD 20 #define REMOVE_WAIT_DELAY 10 @@ -507,30 +499,10 @@ static const char * const qp_s[] = { "none", "init", "start", "stop", "close", }; -struct qm_typical_qos_table { - u32 start; - u32 end; - u32 val; -}; - -/* the qos step is 100 */ -static struct qm_typical_qos_table shaper_cir_s[] = { - {100, 100, 4}, - {200, 200, 3}, - {300, 500, 2}, - {600, 1000, 1}, - {1100, 100000, 0}, -}; - -static struct qm_typical_qos_table shaper_cbs_s[] = { - {100, 200, 9}, - {300, 500, 11}, - {600, 1000, 12}, - {1100, 10000, 16}, - {10100, 25000, 17}, - {25100, 50000, 18}, - {50100, 100000, 19} -}; +static const u32 typical_qos_val[QM_QOS_TYPICAL_NUM] = {100, 250, 500, 1000, + 10000, 25000, 50000, 100000}; +static const u32 typical_qos_cbs_s[QM_QOS_TYPICAL_NUM] = {9, 10, 11, 12, 16, + 17, 18, 19}; static bool qm_avail_state(struct hisi_qm *qm, enum qm_state new) { @@ -611,75 +583,6 @@ static bool qm_qp_avail_state(struct hisi_qm *qm, struct hisi_qp *qp, return avail; } -static u32 qm_get_hw_error_status(struct hisi_qm *qm) -{ - return readl(qm->io_base + QM_ABNORMAL_INT_STATUS); -} - -static u32 qm_get_dev_err_status(struct hisi_qm *qm) -{ - return qm->err_ini->get_dev_hw_err_status(qm); -} - -/* Check if the error causes the master ooo block */ -static int qm_check_dev_error(struct hisi_qm *qm) -{ - u32 val, dev_val; - - if (qm->fun_type == QM_HW_VF) - return 0; - - val = qm_get_hw_error_status(qm); - dev_val = qm_get_dev_err_status(qm); - - if (qm->ver < QM_HW_V3) - return (val & QM_ECC_MBIT) || - (dev_val & qm->err_info.ecc_2bits_mask); - - return (val & readl(qm->io_base + QM_OOO_SHUTDOWN_SEL)) || - (dev_val & (~qm->err_info.dev_ce_mask)); -} - -static int qm_wait_reset_finish(struct hisi_qm *qm) -{ - int delay = 0; - - /* All reset requests need to be queued for processing */ - while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) { - msleep(++delay); - if (delay > QM_RESET_WAIT_TIMEOUT) - return -EBUSY; - } - - return 0; -} - -static int qm_reset_prepare_ready(struct hisi_qm *qm) -{ - struct pci_dev *pdev = qm->pdev; - struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev)); - - /* - * PF and VF on host doesnot support resetting at the - * same time on Kunpeng920. - */ - if (qm->ver < QM_HW_V3) - return qm_wait_reset_finish(pf_qm); - - return qm_wait_reset_finish(qm); -} - -static void qm_reset_bit_clear(struct hisi_qm *qm) -{ - struct pci_dev *pdev = qm->pdev; - struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev)); - - if (qm->ver < QM_HW_V3) - clear_bit(QM_RESETTING, &pf_qm->misc_ctl); - - clear_bit(QM_RESETTING, &qm->misc_ctl); -} - static void qm_mb_pre_init(struct qm_mailbox *mailbox, u8 cmd, u64 base, u16 queue, bool op) { @@ -802,19 +705,6 @@ static void qm_db(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority) qm->ops->qm_db(qm, qn, cmd, index, priority); } -static void qm_disable_clock_gate(struct hisi_qm *qm) -{ - u32 val; - - /* if qm enables clock gating in Kunpeng930, qos will be inaccurate. */ - if (qm->ver < QM_HW_V3) - return; - - val = readl(qm->io_base + QM_PM_CTRL); - val |= QM_IDLE_DISABLE; - writel(val, qm->io_base + QM_PM_CTRL); -} - static int qm_dev_mem_reset(struct hisi_qm *qm) { u32 val; @@ -993,85 +883,24 @@ static irqreturn_t qm_mb_cmd_irq(int irq, void *data) return IRQ_HANDLED; } -static void qm_set_qp_disable(struct hisi_qp *qp, int offset) -{ - u32 *addr; - - if (qp->is_in_kernel) - return; - - addr = (u32 *)(qp->qdma.va + qp->qdma.size) - offset; - *addr = 1; - - /* make sure setup is completed */ - mb(); -} - -static void qm_disable_qp(struct hisi_qm *qm, u32 qp_id) -{ - struct hisi_qp *qp = &qm->qp_array[qp_id]; - - qm_set_qp_disable(qp, QM_RESET_STOP_TX_OFFSET); - hisi_qm_stop_qp(qp); - qm_set_qp_disable(qp, QM_RESET_STOP_RX_OFFSET); -} - -static void qm_reset_function(struct hisi_qm *qm) -{ - struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(qm->pdev)); - struct device *dev = &qm->pdev->dev; - int ret; - - if (qm_check_dev_error(pf_qm)) - return; - - ret = qm_reset_prepare_ready(qm); - if (ret) { - dev_err(dev, "reset function not ready\n"); - return; - } - - ret = hisi_qm_stop(qm, QM_FLR); - if (ret) { - dev_err(dev, "failed to stop qm when reset function\n"); - goto clear_bit; - } - - ret = hisi_qm_start(qm); - if (ret) - dev_err(dev, "failed to start qm when reset function\n"); - -clear_bit: - qm_reset_bit_clear(qm); -} - -static irqreturn_t qm_aeq_thread(int irq, void *data) +static irqreturn_t qm_aeq_irq(int irq, void *data) { struct hisi_qm *qm = data; struct qm_aeqe *aeqe = qm->aeqe + qm->status.aeq_head; - u32 type, qp_id; + u32 type; + + atomic64_inc(&qm->debug.dfx.aeq_irq_cnt); + if (!readl(qm->io_base + QM_VF_AEQ_INT_SOURCE)) + return IRQ_NONE; while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) { type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT; - qp_id = le32_to_cpu(aeqe->dw0) & QM_AEQE_CQN_MASK; - - switch (type) { - case QM_EQ_OVERFLOW: - dev_err(&qm->pdev->dev, "eq overflow, reset function\n"); - qm_reset_function(qm); - return IRQ_HANDLED; - case QM_CQ_OVERFLOW: - dev_err(&qm->pdev->dev, "cq overflow, stop qp(%u)\n", - qp_id); - fallthrough; - case QM_CQE_ERROR: - qm_disable_qp(qm, qp_id); - break; - default: + if (type < ARRAY_SIZE(qm_fifo_overflow)) + dev_err(&qm->pdev->dev, "%s overflow\n", + qm_fifo_overflow[type]); + else dev_err(&qm->pdev->dev, "unknown error type %u\n", type); - break; - } if (qm->status.aeq_head == QM_Q_DEPTH - 1) { qm->status.aeqc_phase = !qm->status.aeqc_phase; @@ -1081,24 +910,13 @@ static irqreturn_t qm_aeq_thread(int irq, void *data) aeqe++; qm->status.aeq_head++; } + + qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0); } - qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0); - return IRQ_HANDLED; } -static irqreturn_t qm_aeq_irq(int irq, void *data) -{ - struct hisi_qm *qm = data; - - atomic64_inc(&qm->debug.dfx.aeq_irq_cnt); - if (!readl(qm->io_base + QM_VF_AEQ_INT_SOURCE)) - return IRQ_NONE; - - return IRQ_WAKE_THREAD; -} - static void qm_irq_unregister(struct hisi_qm *qm) { struct pci_dev *pdev = qm->pdev; @@ -1154,14 +972,12 @@ static void qm_init_prefetch(struct hisi_qm *qm) } /* - * acc_shaper_para_calc() Get the IR value by the qos formula, the return value - * is the expected qos calculated. * the formula: * IR = X Mbps if ir = 1 means IR = 100 Mbps, if ir = 10000 means = 10Gbps * - * IR_b * (2 ^ IR_u) * 8000 - * IR(Mbps) = ------------------------- - * Tick * (2 ^ IR_s) + * IR_b * (2 ^ IR_u) * 8 + * IR(Mbps) * 10 ^ -3 = ------------------------- + * Tick * (2 ^ IR_s) */ static u32 acc_shaper_para_calc(u64 cir_b, u64 cir_u, u64 cir_s) { @@ -1171,28 +987,17 @@ static u32 acc_shaper_para_calc(u64 cir_b, u64 cir_u, u64 cir_s) static u32 acc_shaper_calc_cbs_s(u32 ir) { - int table_size = ARRAY_SIZE(shaper_cbs_s); int i; - for (i = 0; i < table_size; i++) { - if (ir >= shaper_cbs_s[i].start && ir <= shaper_cbs_s[i].end) - return shaper_cbs_s[i].val; + if (ir < typical_qos_val[0]) + return QM_SHAPER_MIN_CBS_S; + + for (i = 1; i < QM_QOS_TYPICAL_NUM; i++) { + if (ir >= typical_qos_val[i - 1] && ir < typical_qos_val[i]) + return typical_qos_cbs_s[i - 1]; } - return QM_SHAPER_MIN_CBS_S; -} - -static u32 acc_shaper_calc_cir_s(u32 ir) -{ - int table_size = ARRAY_SIZE(shaper_cir_s); - int i; - - for (i = 0; i < table_size; i++) { - if (ir >= shaper_cir_s[i].start && ir <= shaper_cir_s[i].end) - return shaper_cir_s[i].val; - } - - return 0; + return typical_qos_cbs_s[QM_QOS_TYPICAL_NUM - 1]; } static int qm_get_shaper_para(u32 ir, struct qm_shaper_factor *factor) @@ -1201,18 +1006,25 @@ static int qm_get_shaper_para(u32 ir, struct qm_shaper_factor *factor) u32 error_rate; factor->cbs_s = acc_shaper_calc_cbs_s(ir); - cir_s = acc_shaper_calc_cir_s(ir); for (cir_b = QM_QOS_MIN_CIR_B; cir_b <= QM_QOS_MAX_CIR_B; cir_b++) { for (cir_u = 0; cir_u <= QM_QOS_MAX_CIR_U; cir_u++) { - ir_calc = acc_shaper_para_calc(cir_b, cir_u, cir_s); + for (cir_s = 0; cir_s <= QM_QOS_MAX_CIR_S; cir_s++) { + /** the formula is changed to: + * IR_b * (2 ^ IR_u) * DIVISOR_CLK + * IR(Mbps) = ------------------------- + * 768 * (2 ^ IR_s) + */ + ir_calc = acc_shaper_para_calc(cir_b, cir_u, + cir_s); + error_rate = QM_QOS_EXPAND_RATE * (u32)abs(ir_calc - ir) / ir; + if (error_rate <= QM_QOS_MIN_ERROR_RATE) { + factor->cir_b = cir_b; + factor->cir_u = cir_u; + factor->cir_s = cir_s; - error_rate = QM_QOS_EXPAND_RATE * (u32)abs(ir_calc - ir) / ir; - if (error_rate <= QM_QOS_MIN_ERROR_RATE) { - factor->cir_b = cir_b; - factor->cir_u = cir_u; - factor->cir_s = cir_s; - return 0; + return 0; + } } } } @@ -1298,10 +1110,10 @@ static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type, static int qm_shaper_init_vft(struct hisi_qm *qm, u32 fun_num) { - u32 qos = qm->factor[fun_num].func_qos; int ret, i; - ret = qm_get_shaper_para(qos * QM_QOS_RATE, &qm->factor[fun_num]); + qm->factor[fun_num].func_qos = QM_QOS_MAX_VAL; + ret = qm_get_shaper_para(QM_QOS_MAX_VAL * QM_QOS_RATE, &qm->factor[fun_num]); if (ret) { dev_err(&qm->pdev->dev, "failed to calculate shaper parameter!\n"); return ret; @@ -2254,6 +2066,35 @@ static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm) return ACC_ERR_RECOVERED; } +static u32 qm_get_hw_error_status(struct hisi_qm *qm) +{ + return readl(qm->io_base + QM_ABNORMAL_INT_STATUS); +} + +static u32 qm_get_dev_err_status(struct hisi_qm *qm) +{ + return qm->err_ini->get_dev_hw_err_status(qm); +} + +/* Check if the error causes the master ooo block */ +static int qm_check_dev_error(struct hisi_qm *qm) +{ + u32 val, dev_val; + + if (qm->fun_type == QM_HW_VF) + return 0; + + val = qm_get_hw_error_status(qm); + dev_val = qm_get_dev_err_status(qm); + + if (qm->ver < QM_HW_V3) + return (val & QM_ECC_MBIT) || + (dev_val & qm->err_info.ecc_2bits_mask); + + return (val & readl(qm->io_base + QM_OOO_SHUTDOWN_SEL)) || + (dev_val & (~qm->err_info.dev_ce_mask)); +} + static int qm_get_mb_cmd(struct hisi_qm *qm, u64 *msg, u16 fun_num) { struct qm_mailbox mailbox; @@ -2626,15 +2467,6 @@ static void *qm_get_avail_sqe(struct hisi_qp *qp) return qp->sqe + sq_tail * qp->qm->sqe_size; } -static void hisi_qm_unset_hw_reset(struct hisi_qp *qp) -{ - u64 *addr; - - /* Use last 64 bits of DUS to reset status. */ - addr = (u64 *)(qp->qdma.va + qp->qdma.size) - QM_RESET_STOP_TX_OFFSET; - *addr = 0; -} - static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type) { struct device *dev = &qm->pdev->dev; @@ -2660,7 +2492,7 @@ static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type) } qp = &qm->qp_array[qp_id]; - hisi_qm_unset_hw_reset(qp); + memset(qp->cqe, 0, sizeof(struct qm_cqe) * QM_Q_DEPTH); qp->event_cb = NULL; @@ -3080,14 +2912,6 @@ static int hisi_qm_get_available_instances(struct uacce_device *uacce) return hisi_qm_get_free_qp_num(uacce->priv); } -static void hisi_qm_set_hw_reset(struct hisi_qm *qm, int offset) -{ - int i; - - for (i = 0; i < qm->qp_num; i++) - qm_set_qp_disable(&qm->qp_array[i], offset); -} - static int hisi_qm_uacce_get_queue(struct uacce_device *uacce, unsigned long arg, struct uacce_queue *q) @@ -3261,7 +3085,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm) }; int ret; - ret = strscpy(interface.name, dev_driver_string(&pdev->dev), + ret = strscpy(interface.name, pdev->driver->name, sizeof(interface.name)); if (ret < 0) return -ENAMETOOLONG; @@ -3270,7 +3094,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm) if (IS_ERR(uacce)) return PTR_ERR(uacce); - if (uacce->flags & UACCE_DEV_SVA) { + if (uacce->flags & UACCE_DEV_SVA && qm->mode == UACCE_MODE_SVA) { qm->use_sva = true; } else { /* only consider sva case */ @@ -3298,10 +3122,8 @@ static int qm_alloc_uacce(struct hisi_qm *qm) else mmio_page_nr = qm->db_interval / PAGE_SIZE; - /* Add one more page for device or qp status */ dus_page_nr = (PAGE_SIZE - 1 + qm->sqe_size * QM_Q_DEPTH + - sizeof(struct qm_cqe) * QM_Q_DEPTH + PAGE_SIZE) >> - PAGE_SHIFT; + sizeof(struct qm_cqe) * QM_Q_DEPTH) >> PAGE_SHIFT; uacce->qf_pg_num[UACCE_QFRT_MMIO] = mmio_page_nr; uacce->qf_pg_num[UACCE_QFRT_DUS] = dus_page_nr; @@ -3542,14 +3364,13 @@ void hisi_qm_uninit(struct hisi_qm *qm) dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma); } - up_write(&qm->qps_lock); qm_irq_unregister(qm); hisi_qm_pci_uninit(qm); - if (qm->use_sva) { - uacce_remove(qm->uacce); - qm->uacce = NULL; - } + uacce_remove(qm->uacce); + qm->uacce = NULL; + + up_write(&qm->qps_lock); } EXPORT_SYMBOL_GPL(hisi_qm_uninit); @@ -3615,22 +3436,6 @@ static void qm_init_eq_aeq_status(struct hisi_qm *qm) status->aeqc_phase = true; } -static void qm_enable_eq_aeq_interrupts(struct hisi_qm *qm) -{ - /* Clear eq/aeq interrupt source */ - qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0); - qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); - - writel(0x0, qm->io_base + QM_VF_EQ_INT_MASK); - writel(0x0, qm->io_base + QM_VF_AEQ_INT_MASK); -} - -static void qm_disable_eq_aeq_interrupts(struct hisi_qm *qm) -{ - writel(0x1, qm->io_base + QM_VF_EQ_INT_MASK); - writel(0x1, qm->io_base + QM_VF_AEQ_INT_MASK); -} - static int qm_eq_ctx_cfg(struct hisi_qm *qm) { struct device *dev = &qm->pdev->dev; @@ -3714,6 +3519,10 @@ static int __hisi_qm_start(struct hisi_qm *qm) WARN_ON(!qm->qdma.va); if (qm->fun_type == QM_HW_PF) { + ret = qm_dev_mem_reset(qm); + if (ret) + return ret; + ret = hisi_qm_set_vft(qm, 0, qm->qp_base, qm->qp_num); if (ret) return ret; @@ -3732,7 +3541,9 @@ static int __hisi_qm_start(struct hisi_qm *qm) return ret; qm_init_prefetch(qm); - qm_enable_eq_aeq_interrupts(qm); + + writel(0x0, qm->io_base + QM_VF_EQ_INT_MASK); + writel(0x0, qm->io_base + QM_VF_AEQ_INT_MASK); return 0; } @@ -3871,16 +3682,17 @@ int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r) if (qm->status.stop_reason == QM_SOFT_RESET || qm->status.stop_reason == QM_FLR) { - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET); ret = qm_stop_started_qp(qm); if (ret < 0) { dev_err(dev, "Failed to stop started qp!\n"); goto err_unlock; } - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); } - qm_disable_eq_aeq_interrupts(qm); + /* Mask eq and aeq irq */ + writel(0x1, qm->io_base + QM_VF_EQ_INT_MASK); + writel(0x1, qm->io_base + QM_VF_AEQ_INT_MASK); + if (qm->fun_type == QM_HW_PF) { ret = hisi_qm_set_vft(qm, 0, 0, 0); if (ret < 0) { @@ -4373,76 +4185,73 @@ static ssize_t qm_qos_value_init(const char *buf, unsigned long *val) return -EINVAL; } - ret = sscanf(buf, "%lu", val); + ret = sscanf(buf, "%ld", val); if (ret != QM_QOS_VAL_NUM) return -EINVAL; return 0; } -static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf, - unsigned long *val, - unsigned int *fun_index) -{ - char tbuf_bdf[QM_DBG_READ_LEN] = {0}; - char val_buf[QM_QOS_VAL_MAX_LEN] = {0}; - u32 tmp1, device, function; - int ret, bus; - - ret = sscanf(buf, "%s %s", tbuf_bdf, val_buf); - if (ret != QM_QOS_PARAM_NUM) - return -EINVAL; - - ret = qm_qos_value_init(val_buf, val); - if (ret || *val == 0 || *val > QM_QOS_MAX_VAL) { - pci_err(qm->pdev, "input qos value is error, please set 1~1000!\n"); - return -EINVAL; - } - - ret = sscanf(tbuf_bdf, "%u:%x:%u.%u", &tmp1, &bus, &device, &function); - if (ret != QM_QOS_BDF_PARAM_NUM) { - pci_err(qm->pdev, "input pci bdf value is error!\n"); - return -EINVAL; - } - - *fun_index = PCI_DEVFN(device, function); - - return 0; -} - static ssize_t qm_algqos_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { struct hisi_qm *qm = filp->private_data; char tbuf[QM_DBG_READ_LEN]; + int tmp1, bus, device, function; + char tbuf_bdf[QM_DBG_READ_LEN] = {0}; + char val_buf[QM_QOS_VAL_MAX_LEN] = {0}; unsigned int fun_index; - unsigned long val; + unsigned long val = 0; int len, ret; if (qm->fun_type == QM_HW_VF) return -EINVAL; - if (*pos != 0) - return 0; - - if (count >= QM_DBG_READ_LEN) - return -ENOSPC; - - len = simple_write_to_buffer(tbuf, QM_DBG_READ_LEN - 1, pos, buf, count); - if (len < 0) - return len; - - tbuf[len] = '\0'; - ret = qm_get_qos_value(qm, tbuf, &val, &fun_index); - if (ret) - return ret; - /* Mailbox and reset cannot be operated at the same time */ if (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) { pci_err(qm->pdev, "dev resetting, write alg qos failed!\n"); return -EAGAIN; } + if (*pos != 0) { + ret = 0; + goto err_get_status; + } + + if (count >= QM_DBG_READ_LEN) { + ret = -ENOSPC; + goto err_get_status; + } + + len = simple_write_to_buffer(tbuf, QM_DBG_READ_LEN - 1, pos, buf, count); + if (len < 0) { + ret = len; + goto err_get_status; + } + + tbuf[len] = '\0'; + ret = sscanf(tbuf, "%s %s", tbuf_bdf, val_buf); + if (ret != QM_QOS_PARAM_NUM) { + ret = -EINVAL; + goto err_get_status; + } + + ret = qm_qos_value_init(val_buf, &val); + if (val == 0 || val > QM_QOS_MAX_VAL || ret) { + pci_err(qm->pdev, "input qos value is error, please set 1~1000!\n"); + ret = -EINVAL; + goto err_get_status; + } + + ret = sscanf(tbuf_bdf, "%d:%x:%d.%d", &tmp1, &bus, &device, &function); + if (ret != QM_QOS_BDF_PARAM_NUM) { + pci_err(qm->pdev, "input pci bdf value is error!\n"); + ret = -EINVAL; + goto err_get_status; + } + + fun_index = device * 8 + function; + ret = qm_pm_get_sync(qm); if (ret) { ret = -EINVAL; @@ -4456,8 +4265,6 @@ static ssize_t qm_algqos_write(struct file *filp, const char __user *buf, goto err_put_sync; } - pci_info(qm->pdev, "the qos value of function%u is set to %lu.\n", - fun_index, val); ret = count; err_put_sync: @@ -4882,6 +4689,46 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, u64 cmd, return ret; } +static int qm_wait_reset_finish(struct hisi_qm *qm) +{ + int delay = 0; + + /* All reset requests need to be queued for processing */ + while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) { + msleep(++delay); + if (delay > QM_RESET_WAIT_TIMEOUT) + return -EBUSY; + } + + return 0; +} + +static int qm_reset_prepare_ready(struct hisi_qm *qm) +{ + struct pci_dev *pdev = qm->pdev; + struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev)); + + /* + * PF and VF on host doesnot support resetting at the + * same time on Kunpeng920. + */ + if (qm->ver < QM_HW_V3) + return qm_wait_reset_finish(pf_qm); + + return qm_wait_reset_finish(qm); +} + +static void qm_reset_bit_clear(struct hisi_qm *qm) +{ + struct pci_dev *pdev = qm->pdev; + struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev)); + + if (qm->ver < QM_HW_V3) + clear_bit(QM_RESETTING, &pf_qm->misc_ctl); + + clear_bit(QM_RESETTING, &qm->misc_ctl); +} + static int qm_controller_reset_prepare(struct hisi_qm *qm) { struct pci_dev *pdev = qm->pdev; @@ -5167,12 +5014,6 @@ static int qm_controller_reset_done(struct hisi_qm *qm) if (qm->err_ini->open_axi_master_ooo) qm->err_ini->open_axi_master_ooo(qm); - ret = qm_dev_mem_reset(qm); - if (ret) { - pci_err(pdev, "failed to reset device memory\n"); - return ret; - } - ret = qm_restart(qm); if (ret) { pci_err(pdev, "Failed to start QM!\n"); @@ -5204,8 +5045,6 @@ static int qm_controller_reset(struct hisi_qm *qm) ret = qm_controller_reset_prepare(qm); if (ret) { - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET); - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); clear_bit(QM_RST_SCHED, &qm->misc_ctl); return ret; } @@ -5292,8 +5131,6 @@ void hisi_qm_reset_prepare(struct pci_dev *pdev) ret = hisi_qm_stop(qm, QM_FLR); if (ret) { pci_err(pdev, "Failed to stop QM, ret = %d.\n", ret); - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET); - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); return; } @@ -5387,10 +5224,8 @@ static int qm_irq_register(struct hisi_qm *qm) return ret; if (qm->ver > QM_HW_V1) { - ret = request_threaded_irq(pci_irq_vector(pdev, - QM_AEQ_EVENT_IRQ_VECTOR), - qm_aeq_irq, qm_aeq_thread, - 0, qm->dev_name, qm); + ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), + qm_aeq_irq, 0, qm->dev_name, qm); if (ret) goto err_aeq_irq; @@ -5479,14 +5314,9 @@ static void qm_pf_reset_vf_prepare(struct hisi_qm *qm, atomic_set(&qm->status.flags, QM_STOP); cmd = QM_VF_PREPARE_FAIL; goto err_prepare; - } else { - goto out; } err_prepare: - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET); - hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); -out: pci_save_state(pdev); ret = qm->ops->ping_pf(qm, cmd); if (ret) @@ -5872,15 +5702,13 @@ static int hisi_qp_alloc_memory(struct hisi_qm *qm) static int hisi_qm_memory_init(struct hisi_qm *qm) { struct device *dev = &qm->pdev->dev; - int ret, total_func, i; + int ret, total_vfs; size_t off = 0; - total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; - qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); + total_vfs = pci_sriov_get_totalvfs(qm->pdev); + qm->factor = kcalloc(total_vfs + 1, sizeof(struct qm_shaper_factor), GFP_KERNEL); if (!qm->factor) return -ENOMEM; - for (i = 0; i < total_func; i++) - qm->factor[i].func_qos = QM_QOS_MAX_VAL; #define QM_INIT_BUF(qm, type, num) do { \ (qm)->type = ((qm)->qdma.va + (off)); \ @@ -5949,20 +5777,9 @@ int hisi_qm_init(struct hisi_qm *qm) goto err_irq_register; } - if (qm->fun_type == QM_HW_PF) { - qm_disable_clock_gate(qm); - ret = qm_dev_mem_reset(qm); - if (ret) { - dev_err(dev, "failed to reset device memory\n"); - goto err_irq_register; - } - } - - if (qm->mode == UACCE_MODE_SVA) { - ret = qm_alloc_uacce(qm); - if (ret < 0) - dev_warn(dev, "fail to alloc uacce (%d)\n", ret); - } + ret = qm_alloc_uacce(qm); + if (ret < 0) + dev_warn(dev, "fail to alloc uacce (%d)\n", ret); ret = hisi_qm_memory_init(qm); if (ret) @@ -5975,10 +5792,8 @@ int hisi_qm_init(struct hisi_qm *qm) return 0; err_alloc_uacce: - if (qm->use_sva) { - uacce_remove(qm->uacce); - qm->uacce = NULL; - } + uacce_remove(qm->uacce); + qm->uacce = NULL; err_irq_register: qm_irq_unregister(qm); err_pci_init: @@ -6115,12 +5930,8 @@ static int qm_rebuild_for_resume(struct hisi_qm *qm) qm_cmd_init(qm); hisi_qm_dev_err_init(qm); - qm_disable_clock_gate(qm); - ret = qm_dev_mem_reset(qm); - if (ret) - pci_err(pdev, "failed to reset device memory\n"); - return ret; + return 0; } /** diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 678f8b58ec..7148201ce7 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -103,8 +103,8 @@ #define HZIP_PREFETCH_ENABLE (~(BIT(26) | BIT(17) | BIT(0))) #define HZIP_SVA_PREFETCH_DISABLE BIT(26) #define HZIP_SVA_DISABLE_READY (BIT(26) | BIT(30)) -#define HZIP_SHAPER_RATE_COMPRESS 750 -#define HZIP_SHAPER_RATE_DECOMPRESS 140 +#define HZIP_SHAPER_RATE_COMPRESS 252 +#define HZIP_SHAPER_RATE_DECOMPRESS 229 #define HZIP_DELAY_1_US 1 #define HZIP_POLL_TIMEOUT_US 1000 @@ -218,7 +218,7 @@ static const struct debugfs_reg32 hzip_dfx_regs[] = { {"HZIP_AVG_DELAY ", 0x28ull}, {"HZIP_MEM_VISIBLE_DATA ", 0x30ull}, {"HZIP_MEM_VISIBLE_ADDR ", 0x34ull}, - {"HZIP_CONSUMED_BYTE ", 0x38ull}, + {"HZIP_COMSUMED_BYTE ", 0x38ull}, {"HZIP_PRODUCED_BYTE ", 0x40ull}, {"HZIP_COMP_INF ", 0x70ull}, {"HZIP_PRE_OUT ", 0x78ull}, @@ -364,16 +364,15 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm) /* user domain configurations */ writel(AXUSER_BASE, base + HZIP_BD_RUSER_32_63); + writel(AXUSER_BASE, base + HZIP_SGL_RUSER_32_63); writel(AXUSER_BASE, base + HZIP_BD_WUSER_32_63); if (qm->use_sva && qm->ver == QM_HW_V2) { writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_RUSER_32_63); writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_WUSER_32_63); - writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_SGL_RUSER_32_63); } else { writel(AXUSER_BASE, base + HZIP_DATA_RUSER_32_63); writel(AXUSER_BASE, base + HZIP_DATA_WUSER_32_63); - writel(AXUSER_BASE, base + HZIP_SGL_RUSER_32_63); } /* let's open all compression/decompression cores */ @@ -830,10 +829,7 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) qm->pdev = pdev; qm->ver = pdev->revision; - if (pdev->revision >= QM_HW_V3) - qm->algs = "zlib\ngzip\ndeflate\nlz77_zstd"; - else - qm->algs = "zlib\ngzip"; + qm->algs = "zlib\ngzip"; qm->mode = uacce_mode; qm->sqe_size = HZIP_SQE_SIZE; qm->dev_name = hisi_zip_name; diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c index d8e82d6974..aa4c7b2af3 100644 --- a/drivers/crypto/img-hash.c +++ b/drivers/crypto/img-hash.c @@ -674,12 +674,14 @@ static int img_hash_digest(struct ahash_request *req) static int img_hash_cra_init(struct crypto_tfm *tfm, const char *alg_name) { struct img_hash_ctx *ctx = crypto_tfm_ctx(tfm); + int err = -ENOMEM; ctx->fallback = crypto_alloc_ahash(alg_name, 0, CRYPTO_ALG_NEED_FALLBACK); if (IS_ERR(ctx->fallback)) { pr_err("img_hash: Could not load fallback driver.\n"); - return PTR_ERR(ctx->fallback); + err = PTR_ERR(ctx->fallback); + goto err; } crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct img_hash_request_ctx) + @@ -687,6 +689,9 @@ static int img_hash_cra_init(struct crypto_tfm *tfm, const char *alg_name) IMG_HASH_DMA_THRESHOLD); return 0; + +err: + return err; } static int img_hash_cra_md5_init(struct crypto_tfm *tfm) diff --git a/drivers/crypto/keembay/Kconfig b/drivers/crypto/keembay/Kconfig index 7942b48dd5..00cf8f028c 100644 --- a/drivers/crypto/keembay/Kconfig +++ b/drivers/crypto/keembay/Kconfig @@ -39,25 +39,6 @@ config CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS Intel does not recommend use of CTS mode with AES/SM4. -config CRYPTO_DEV_KEEMBAY_OCS_ECC - tristate "Support for Intel Keem Bay OCS ECC HW acceleration" - depends on ARCH_KEEMBAY || COMPILE_TEST - depends on OF || COMPILE_TEST - depends on HAS_IOMEM - select CRYPTO_ECDH - select CRYPTO_ENGINE - help - Support for Intel Keem Bay Offload and Crypto Subsystem (OCS) - Elliptic Curve Cryptography (ECC) hardware acceleration for use with - Crypto API. - - Provides OCS acceleration for ECDH-256 and ECDH-384. - - Say Y or M if you are compiling for the Intel Keem Bay SoC. The - module will be called keembay-ocs-ecc. - - If unsure, say N. - config CRYPTO_DEV_KEEMBAY_OCS_HCU tristate "Support for Intel Keem Bay OCS HCU HW acceleration" select CRYPTO_HASH diff --git a/drivers/crypto/keembay/Makefile b/drivers/crypto/keembay/Makefile index 7c12c3c138..aea03d4432 100644 --- a/drivers/crypto/keembay/Makefile +++ b/drivers/crypto/keembay/Makefile @@ -4,7 +4,5 @@ obj-$(CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4) += keembay-ocs-aes.o keembay-ocs-aes-objs := keembay-ocs-aes-core.o ocs-aes.o -obj-$(CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC) += keembay-ocs-ecc.o - obj-$(CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU) += keembay-ocs-hcu.o keembay-ocs-hcu-objs := keembay-ocs-hcu-core.o ocs-hcu.o diff --git a/drivers/crypto/marvell/cesa/cesa.c b/drivers/crypto/marvell/cesa/cesa.c index 5cd3328806..f14aac532f 100644 --- a/drivers/crypto/marvell/cesa/cesa.c +++ b/drivers/crypto/marvell/cesa/cesa.c @@ -615,6 +615,7 @@ static struct platform_driver marvell_cesa = { }; module_platform_driver(marvell_cesa); +MODULE_ALIAS("platform:mv_crypto"); MODULE_AUTHOR("Boris Brezillon "); MODULE_AUTHOR("Arnaud Ebalard "); MODULE_DESCRIPTION("Support for Marvell's cryptographic engine"); diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c index b681bd2dc6..c076d0b3ad 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c @@ -94,13 +94,15 @@ static int alloc_pending_queues(struct otx_cpt_pending_qinfo *pqinfo, u32 qlen, u32 num_queues) { struct otx_cpt_pending_queue *queue = NULL; + size_t size; int ret; u32 i; pqinfo->num_queues = num_queues; + size = (qlen * sizeof(struct otx_cpt_pending_entry)); for_each_pending_queue(pqinfo, queue, i) { - queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL); + queue->head = kzalloc((size), GFP_KERNEL); if (!queue->head) { ret = -ENOMEM; goto pending_qfail; diff --git a/drivers/crypto/marvell/octeontx2/Makefile b/drivers/crypto/marvell/octeontx2/Makefile index 965297e969..c242d22008 100644 --- a/drivers/crypto/marvell/octeontx2/Makefile +++ b/drivers/crypto/marvell/octeontx2/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_OCTEONTX2_CPT) += rvu_cptpf.o rvu_cptvf.o rvu_cptpf-objs := otx2_cptpf_main.o otx2_cptpf_mbox.o \ otx2_cpt_mbox_common.o otx2_cptpf_ucode.o otx2_cptlf.o \ - cn10k_cpt.o otx2_cpt_devlink.o + cn10k_cpt.o rvu_cptvf-objs := otx2_cptvf_main.o otx2_cptvf_mbox.o otx2_cptlf.o \ otx2_cpt_mbox_common.o otx2_cptvf_reqmgr.o \ otx2_cptvf_algs.o cn10k_cpt.o diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h index fb56824cb0..c5445b05f5 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h +++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h @@ -10,7 +10,6 @@ #include #include #include -#include #include "otx2_cpt_hw_types.h" #include "rvu.h" #include "mbox.h" diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf.h b/drivers/crypto/marvell/octeontx2/otx2_cptpf.h index 05b2d9c650..5ebba86c65 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf.h +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf.h @@ -53,9 +53,6 @@ struct otx2_cptpf_dev { u8 enabled_vfs; /* Number of enabled VFs */ u8 kvf_limits; /* Kernel crypto limits */ bool has_cpt1; - - /* Devlink */ - struct devlink *dl; }; irqreturn_t otx2_cptpf_afpf_mbox_intr(int irq, void *arg); diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c index 1720a5bb70..be1ad55a20 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c @@ -4,7 +4,6 @@ #include #include "otx2_cpt_hw_types.h" #include "otx2_cpt_common.h" -#include "otx2_cpt_devlink.h" #include "otx2_cptpf_ucode.h" #include "otx2_cptpf.h" #include "cn10k_cpt.h" @@ -767,15 +766,8 @@ static int otx2_cptpf_probe(struct pci_dev *pdev, err = sysfs_create_group(&dev->kobj, &cptpf_sysfs_group); if (err) goto cleanup_eng_grps; - - err = otx2_cpt_register_dl(cptpf); - if (err) - goto sysfs_grp_del; - return 0; -sysfs_grp_del: - sysfs_remove_group(&dev->kobj, &cptpf_sysfs_group); cleanup_eng_grps: otx2_cpt_cleanup_eng_grps(pdev, &cptpf->eng_grps); unregister_intr: @@ -795,7 +787,6 @@ static void otx2_cptpf_remove(struct pci_dev *pdev) return; cptpf_sriov_disable(pdev); - otx2_cpt_unregister_dl(cptpf); /* Delete sysfs entry created for kernel VF limits */ sysfs_remove_group(&pdev->dev.kobj, &cptpf_sysfs_group); /* Cleanup engine groups */ diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c index 1b4d425bbf..7c1b92aaab 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c @@ -1111,19 +1111,18 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf, struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { {0} }; struct pci_dev *pdev = cptpf->pdev; struct fw_info_t fw_info; - int ret = 0; + int ret; - mutex_lock(&eng_grps->lock); /* * We don't create engine groups if it was already * made (when user enabled VFs for the first time) */ if (eng_grps->is_grps_created) - goto unlock; + return 0; ret = cpt_ucode_load_fw(pdev, &fw_info); if (ret) - goto unlock; + return ret; /* * Create engine group with SE engines for kernel @@ -1188,7 +1187,7 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf, cpt_ucode_release_fw(&fw_info); if (is_dev_otx2(pdev)) - goto unlock; + return 0; /* * Configure engine group mask to allow context prefetching * for the groups. @@ -1203,15 +1202,12 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf, */ otx2_cpt_write_af_reg(&cptpf->afpf_mbox, pdev, CPT_AF_CTX_FLUSH_TIMER, CTX_FLUSH_TIMER_CNT, BLKADDR_CPT0); - mutex_unlock(&eng_grps->lock); return 0; delete_eng_grp: delete_engine_grps(pdev, eng_grps); release_fw: cpt_ucode_release_fw(&fw_info); -unlock: - mutex_unlock(&eng_grps->lock); return ret; } @@ -1291,7 +1287,6 @@ void otx2_cpt_cleanup_eng_grps(struct pci_dev *pdev, struct otx2_cpt_eng_grp_info *grp; int i, j; - mutex_lock(&eng_grps->lock); delete_engine_grps(pdev, eng_grps); /* Release memory */ for (i = 0; i < OTX2_CPT_MAX_ENGINE_GROUPS; i++) { @@ -1301,7 +1296,6 @@ void otx2_cpt_cleanup_eng_grps(struct pci_dev *pdev, grp->engs[j].bmap = NULL; } } - mutex_unlock(&eng_grps->lock); } int otx2_cpt_init_eng_grps(struct pci_dev *pdev, @@ -1310,7 +1304,6 @@ int otx2_cpt_init_eng_grps(struct pci_dev *pdev, struct otx2_cpt_eng_grp_info *grp; int i, j, ret; - mutex_init(&eng_grps->lock); eng_grps->obj = pci_get_drvdata(pdev); eng_grps->avail.se_cnt = eng_grps->avail.max_se_cnt; eng_grps->avail.ie_cnt = eng_grps->avail.max_ie_cnt; @@ -1357,14 +1350,11 @@ static int create_eng_caps_discovery_grps(struct pci_dev *pdev, struct fw_info_t fw_info; int ret; - mutex_lock(&eng_grps->lock); ret = cpt_ucode_load_fw(pdev, &fw_info); - if (ret) { - mutex_unlock(&eng_grps->lock); + if (ret) return ret; - } - uc_info[0] = get_ucode(&fw_info, OTX2_CPT_AE_TYPES); + uc_info[0] = get_ucode(&fw_info, OTX2_CPT_SE_TYPES); if (uc_info[0] == NULL) { dev_err(&pdev->dev, "Unable to find firmware for AE\n"); ret = -EINVAL; @@ -1407,14 +1397,12 @@ static int create_eng_caps_discovery_grps(struct pci_dev *pdev, goto delete_eng_grp; cpt_ucode_release_fw(&fw_info); - mutex_unlock(&eng_grps->lock); return 0; delete_eng_grp: delete_engine_grps(pdev, eng_grps); release_fw: cpt_ucode_release_fw(&fw_info); - mutex_unlock(&eng_grps->lock); return ret; } @@ -1514,292 +1502,3 @@ int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf) return ret; } - -int otx2_cpt_dl_custom_egrp_create(struct otx2_cptpf_dev *cptpf, - struct devlink_param_gset_ctx *ctx) -{ - struct otx2_cpt_engines engs[OTX2_CPT_MAX_ETYPES_PER_GRP] = { { 0 } }; - struct otx2_cpt_uc_info_t *uc_info[OTX2_CPT_MAX_ETYPES_PER_GRP] = {}; - struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; - char *ucode_filename[OTX2_CPT_MAX_ETYPES_PER_GRP]; - char tmp_buf[OTX2_CPT_NAME_LENGTH] = { 0 }; - struct device *dev = &cptpf->pdev->dev; - char *start, *val, *err_msg, *tmp; - int grp_idx = 0, ret = -EINVAL; - bool has_se, has_ie, has_ae; - struct fw_info_t fw_info; - int ucode_idx = 0; - - if (!eng_grps->is_grps_created) { - dev_err(dev, "Not allowed before creating the default groups\n"); - return -EINVAL; - } - err_msg = "Invalid engine group format"; - strscpy(tmp_buf, ctx->val.vstr, strlen(ctx->val.vstr) + 1); - start = tmp_buf; - - has_se = has_ie = has_ae = false; - - for (;;) { - val = strsep(&start, ";"); - if (!val) - break; - val = strim(val); - if (!*val) - continue; - - if (!strncasecmp(val, "se", 2) && strchr(val, ':')) { - if (has_se || ucode_idx) - goto err_print; - tmp = strim(strsep(&val, ":")); - if (!val) - goto err_print; - if (strlen(tmp) != 2) - goto err_print; - if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) - goto err_print; - engs[grp_idx++].type = OTX2_CPT_SE_TYPES; - has_se = true; - } else if (!strncasecmp(val, "ae", 2) && strchr(val, ':')) { - if (has_ae || ucode_idx) - goto err_print; - tmp = strim(strsep(&val, ":")); - if (!val) - goto err_print; - if (strlen(tmp) != 2) - goto err_print; - if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) - goto err_print; - engs[grp_idx++].type = OTX2_CPT_AE_TYPES; - has_ae = true; - } else if (!strncasecmp(val, "ie", 2) && strchr(val, ':')) { - if (has_ie || ucode_idx) - goto err_print; - tmp = strim(strsep(&val, ":")); - if (!val) - goto err_print; - if (strlen(tmp) != 2) - goto err_print; - if (kstrtoint(strim(val), 10, &engs[grp_idx].count)) - goto err_print; - engs[grp_idx++].type = OTX2_CPT_IE_TYPES; - has_ie = true; - } else { - if (ucode_idx > 1) - goto err_print; - if (!strlen(val)) - goto err_print; - if (strnstr(val, " ", strlen(val))) - goto err_print; - ucode_filename[ucode_idx++] = val; - } - } - - /* Validate input parameters */ - if (!(grp_idx && ucode_idx)) - goto err_print; - - if (ucode_idx > 1 && grp_idx < 2) - goto err_print; - - if (grp_idx > OTX2_CPT_MAX_ETYPES_PER_GRP) { - err_msg = "Error max 2 engine types can be attached"; - goto err_print; - } - - if (grp_idx > 1) { - if ((engs[0].type + engs[1].type) != - (OTX2_CPT_SE_TYPES + OTX2_CPT_IE_TYPES)) { - err_msg = "Only combination of SE+IE engines is allowed"; - goto err_print; - } - /* Keep SE engines at zero index */ - if (engs[1].type == OTX2_CPT_SE_TYPES) - swap(engs[0], engs[1]); - } - mutex_lock(&eng_grps->lock); - - if (cptpf->enabled_vfs) { - dev_err(dev, "Disable VFs before modifying engine groups\n"); - ret = -EACCES; - goto err_unlock; - } - INIT_LIST_HEAD(&fw_info.ucodes); - ret = load_fw(dev, &fw_info, ucode_filename[0]); - if (ret) { - dev_err(dev, "Unable to load firmware %s\n", ucode_filename[0]); - goto err_unlock; - } - if (ucode_idx > 1) { - ret = load_fw(dev, &fw_info, ucode_filename[1]); - if (ret) { - dev_err(dev, "Unable to load firmware %s\n", - ucode_filename[1]); - goto release_fw; - } - } - uc_info[0] = get_ucode(&fw_info, engs[0].type); - if (uc_info[0] == NULL) { - dev_err(dev, "Unable to find firmware for %s\n", - get_eng_type_str(engs[0].type)); - ret = -EINVAL; - goto release_fw; - } - if (ucode_idx > 1) { - uc_info[1] = get_ucode(&fw_info, engs[1].type); - if (uc_info[1] == NULL) { - dev_err(dev, "Unable to find firmware for %s\n", - get_eng_type_str(engs[1].type)); - ret = -EINVAL; - goto release_fw; - } - } - ret = create_engine_group(dev, eng_grps, engs, grp_idx, - (void **)uc_info, 1); - -release_fw: - cpt_ucode_release_fw(&fw_info); -err_unlock: - mutex_unlock(&eng_grps->lock); - return ret; -err_print: - dev_err(dev, "%s\n", err_msg); - return ret; -} - -int otx2_cpt_dl_custom_egrp_delete(struct otx2_cptpf_dev *cptpf, - struct devlink_param_gset_ctx *ctx) -{ - struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; - struct device *dev = &cptpf->pdev->dev; - char *tmp, *err_msg; - int egrp; - int ret; - - err_msg = "Invalid input string format(ex: egrp:0)"; - if (strncasecmp(ctx->val.vstr, "egrp", 4)) - goto err_print; - tmp = ctx->val.vstr; - strsep(&tmp, ":"); - if (!tmp) - goto err_print; - if (kstrtoint(tmp, 10, &egrp)) - goto err_print; - - if (egrp < 0 || egrp >= OTX2_CPT_MAX_ENGINE_GROUPS) { - dev_err(dev, "Invalid engine group %d", egrp); - return -EINVAL; - } - if (!eng_grps->grp[egrp].is_enabled) { - dev_err(dev, "Error engine_group%d is not configured", egrp); - return -EINVAL; - } - mutex_lock(&eng_grps->lock); - ret = delete_engine_group(dev, &eng_grps->grp[egrp]); - mutex_unlock(&eng_grps->lock); - - return ret; - -err_print: - dev_err(dev, "%s\n", err_msg); - return -EINVAL; -} - -static void get_engs_info(struct otx2_cpt_eng_grp_info *eng_grp, char *buf, - int size, int idx) -{ - struct otx2_cpt_engs_rsvd *mirrored_engs = NULL; - struct otx2_cpt_engs_rsvd *engs; - int len, i; - - buf[0] = '\0'; - for (i = 0; i < OTX2_CPT_MAX_ETYPES_PER_GRP; i++) { - engs = &eng_grp->engs[i]; - if (!engs->type) - continue; - if (idx != -1 && idx != i) - continue; - - if (eng_grp->mirror.is_ena) - mirrored_engs = find_engines_by_type( - &eng_grp->g->grp[eng_grp->mirror.idx], - engs->type); - if (i > 0 && idx == -1) { - len = strlen(buf); - scnprintf(buf + len, size - len, ", "); - } - - len = strlen(buf); - scnprintf(buf + len, size - len, "%d %s ", - mirrored_engs ? engs->count + mirrored_engs->count : - engs->count, - get_eng_type_str(engs->type)); - if (mirrored_engs) { - len = strlen(buf); - scnprintf(buf + len, size - len, - "(%d shared with engine_group%d) ", - engs->count <= 0 ? - engs->count + mirrored_engs->count : - mirrored_engs->count, - eng_grp->mirror.idx); - } - } -} - -void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf) -{ - struct otx2_cpt_eng_grps *eng_grps = &cptpf->eng_grps; - struct otx2_cpt_eng_grp_info *mirrored_grp; - char engs_info[2 * OTX2_CPT_NAME_LENGTH]; - struct otx2_cpt_eng_grp_info *grp; - struct otx2_cpt_engs_rsvd *engs; - int i, j; - - pr_debug("Engine groups global info"); - pr_debug("max SE %d, max IE %d, max AE %d", eng_grps->avail.max_se_cnt, - eng_grps->avail.max_ie_cnt, eng_grps->avail.max_ae_cnt); - pr_debug("free SE %d", eng_grps->avail.se_cnt); - pr_debug("free IE %d", eng_grps->avail.ie_cnt); - pr_debug("free AE %d", eng_grps->avail.ae_cnt); - - for (i = 0; i < OTX2_CPT_MAX_ENGINE_GROUPS; i++) { - grp = &eng_grps->grp[i]; - pr_debug("engine_group%d, state %s", i, - grp->is_enabled ? "enabled" : "disabled"); - if (grp->is_enabled) { - mirrored_grp = &eng_grps->grp[grp->mirror.idx]; - pr_debug("Ucode0 filename %s, version %s", - grp->mirror.is_ena ? - mirrored_grp->ucode[0].filename : - grp->ucode[0].filename, - grp->mirror.is_ena ? - mirrored_grp->ucode[0].ver_str : - grp->ucode[0].ver_str); - if (is_2nd_ucode_used(grp)) - pr_debug("Ucode1 filename %s, version %s", - grp->ucode[1].filename, - grp->ucode[1].ver_str); - } - - for (j = 0; j < OTX2_CPT_MAX_ETYPES_PER_GRP; j++) { - engs = &grp->engs[j]; - if (engs->type) { - u32 mask[5] = { }; - - get_engs_info(grp, engs_info, - 2 * OTX2_CPT_NAME_LENGTH, j); - pr_debug("Slot%d: %s", j, engs_info); - bitmap_to_arr32(mask, engs->bmap, - eng_grps->engs_num); - if (is_dev_otx2(cptpf->pdev)) - pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x", - mask[3], mask[2], mask[1], - mask[0]); - else - pr_debug("Mask: %8.8x %8.8x %8.8x %8.8x %8.8x", - mask[4], mask[3], mask[2], mask[1], - mask[0]); - } - } - } -} diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h index 8f4d4e5f53..fe019ab730 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.h @@ -143,7 +143,6 @@ struct otx2_cpt_eng_grp_info { }; struct otx2_cpt_eng_grps { - struct mutex lock; struct otx2_cpt_eng_grp_info grp[OTX2_CPT_MAX_ENGINE_GROUPS]; struct otx2_cpt_engs_available avail; void *obj; /* device specific data */ @@ -161,9 +160,5 @@ int otx2_cpt_create_eng_grps(struct otx2_cptpf_dev *cptpf, int otx2_cpt_disable_all_cores(struct otx2_cptpf_dev *cptpf); int otx2_cpt_get_eng_grp(struct otx2_cpt_eng_grps *eng_grps, int eng_type); int otx2_cpt_discover_eng_capabilities(struct otx2_cptpf_dev *cptpf); -int otx2_cpt_dl_custom_egrp_create(struct otx2_cptpf_dev *cptpf, - struct devlink_param_gset_ctx *ctx); -int otx2_cpt_dl_custom_egrp_delete(struct otx2_cptpf_dev *cptpf, - struct devlink_param_gset_ctx *ctx); -void otx2_cpt_print_uc_dbg_info(struct otx2_cptpf_dev *cptpf); + #endif /* __OTX2_CPTPF_UCODE_H */ diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c index 2748a3327e..877a948469 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c @@ -1682,8 +1682,11 @@ static void swap_func(void *lptr, void *rptr, int size) { struct cpt_device_desc *ldesc = lptr; struct cpt_device_desc *rdesc = rptr; + struct cpt_device_desc desc; - swap(*ldesc, *rdesc); + desc = *ldesc; + *ldesc = *rdesc; + *rdesc = desc; } int otx2_cpt_crypto_init(struct pci_dev *pdev, struct module *mod, diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig index 4b90c0f22b..77783feb62 100644 --- a/drivers/crypto/qat/Kconfig +++ b/drivers/crypto/qat/Kconfig @@ -13,7 +13,6 @@ config CRYPTO_DEV_QAT select CRYPTO_SHA512 select CRYPTO_LIB_AES select FW_LOADER - select CRC8 config CRYPTO_DEV_QAT_DH895xCC tristate "Support for Intel(R) DH895xCC" diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c index 6d10edc40a..88c0ded411 100644 --- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c +++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c @@ -1,11 +1,10 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2020 - 2021 Intel Corporation */ +/* Copyright(c) 2020 Intel Corporation */ #include #include -#include #include +#include #include -#include #include "adf_4xxx_hw_data.h" #include "icp_qat_hw.h" @@ -14,18 +13,12 @@ struct adf_fw_config { char *obj_name; }; -static struct adf_fw_config adf_4xxx_fw_cy_config[] = { +static struct adf_fw_config adf_4xxx_fw_config[] = { {0xF0, ADF_4XXX_SYM_OBJ}, {0xF, ADF_4XXX_ASYM_OBJ}, {0x100, ADF_4XXX_ADMIN_OBJ}, }; -static struct adf_fw_config adf_4xxx_fw_dc_config[] = { - {0xF0, ADF_4XXX_DC_OBJ}, - {0xF, ADF_4XXX_DC_OBJ}, - {0x100, ADF_4XXX_ADMIN_OBJ}, -}; - /* Worker thread to service arbiter mappings */ static const u32 thrd_to_arb_map[ADF_4XXX_MAX_ACCELENGINES] = { 0x5555555, 0x5555555, 0x5555555, 0x5555555, @@ -39,39 +32,6 @@ static struct adf_hw_device_class adf_4xxx_class = { .instances = 0, }; -enum dev_services { - SVC_CY = 0, - SVC_DC, -}; - -static const char *const dev_cfg_services[] = { - [SVC_CY] = ADF_CFG_CY, - [SVC_DC] = ADF_CFG_DC, -}; - -static int get_service_enabled(struct adf_accel_dev *accel_dev) -{ - char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; - u32 ret; - - ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, - ADF_SERVICES_ENABLED, services); - if (ret) { - dev_err(&GET_DEV(accel_dev), - ADF_SERVICES_ENABLED " param not found\n"); - return ret; - } - - ret = match_string(dev_cfg_services, ARRAY_SIZE(dev_cfg_services), - services); - if (ret < 0) - dev_err(&GET_DEV(accel_dev), - "Invalid value of " ADF_SERVICES_ENABLED " param: %s\n", - services); - - return ret; -} - static u32 get_accel_mask(struct adf_hw_device_data *self) { return ADF_4XXX_ACCELERATORS_MASK; @@ -136,67 +96,23 @@ static void set_msix_default_rttable(struct adf_accel_dev *accel_dev) static u32 get_accel_cap(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_dev->accel_pci_dev.pci_dev; - u32 capabilities_cy, capabilities_dc; u32 fusectl1; + u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | + ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | + ICP_ACCEL_CAPABILITIES_AUTHENTICATION | + ICP_ACCEL_CAPABILITIES_AES_V2; /* Read accelerator capabilities mask */ pci_read_config_dword(pdev, ADF_4XXX_FUSECTL1_OFFSET, &fusectl1); - capabilities_cy = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | - ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | - ICP_ACCEL_CAPABILITIES_CIPHER | - ICP_ACCEL_CAPABILITIES_AUTHENTICATION | - ICP_ACCEL_CAPABILITIES_SHA3 | - ICP_ACCEL_CAPABILITIES_SHA3_EXT | - ICP_ACCEL_CAPABILITIES_HKDF | - ICP_ACCEL_CAPABILITIES_ECEDMONT | - ICP_ACCEL_CAPABILITIES_CHACHA_POLY | - ICP_ACCEL_CAPABILITIES_AESGCM_SPC | - ICP_ACCEL_CAPABILITIES_AES_V2; + if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) + capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) + capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) + capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - /* A set bit in fusectl1 means the feature is OFF in this SKU */ - if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) { - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_HKDF; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER; - } - if (fusectl1 & ICP_ACCEL_4XXX_MASK_UCS_SLICE) { - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AES_V2; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER; - } - if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) { - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_SHA3; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER; - } - if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) { - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT; - } - - capabilities_dc = ICP_ACCEL_CAPABILITIES_COMPRESSION | - ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION | - ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION | - ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; - - if (fusectl1 & ICP_ACCEL_4XXX_MASK_COMPRESS_SLICE) { - capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; - capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION; - capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION; - capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; - } - - switch (get_service_enabled(accel_dev)) { - case SVC_CY: - return capabilities_cy; - case SVC_DC: - return capabilities_dc; - } - - return 0; + return capabilities; } static enum dev_sku_info get_sku(struct adf_hw_device_data *self) @@ -275,37 +191,24 @@ static int adf_init_device(struct adf_accel_dev *accel_dev) return ret; } +static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) +{ + return 0; +} + static u32 uof_get_num_objs(void) { - BUILD_BUG_ON_MSG(ARRAY_SIZE(adf_4xxx_fw_cy_config) != - ARRAY_SIZE(adf_4xxx_fw_dc_config), - "Size mismatch between adf_4xxx_fw_*_config arrays"); - - return ARRAY_SIZE(adf_4xxx_fw_cy_config); + return ARRAY_SIZE(adf_4xxx_fw_config); } -static char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num) +static char *uof_get_name(u32 obj_num) { - switch (get_service_enabled(accel_dev)) { - case SVC_CY: - return adf_4xxx_fw_cy_config[obj_num].obj_name; - case SVC_DC: - return adf_4xxx_fw_dc_config[obj_num].obj_name; - } - - return NULL; + return adf_4xxx_fw_config[obj_num].obj_name; } -static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num) +static u32 uof_get_ae_mask(u32 obj_num) { - switch (get_service_enabled(accel_dev)) { - case SVC_CY: - return adf_4xxx_fw_cy_config[obj_num].ae_mask; - case SVC_DC: - return adf_4xxx_fw_dc_config[obj_num].ae_mask; - } - - return 0; + return adf_4xxx_fw_config[obj_num].ae_mask; } void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) @@ -313,14 +216,12 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) hw_data->dev_class = &adf_4xxx_class; hw_data->instance_id = adf_4xxx_class.instances++; hw_data->num_banks = ADF_4XXX_ETR_MAX_BANKS; - hw_data->num_banks_per_vf = ADF_4XXX_NUM_BANKS_PER_VF; hw_data->num_rings_per_bank = ADF_4XXX_NUM_RINGS_PER_BANK; hw_data->num_accel = ADF_4XXX_MAX_ACCELERATORS; hw_data->num_engines = ADF_4XXX_MAX_ACCELENGINES; hw_data->num_logical_accel = 1; hw_data->tx_rx_gap = ADF_4XXX_RX_RINGS_OFFSET; hw_data->tx_rings_mask = ADF_4XXX_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN4_DEFAULT_RING_TO_SRV_MAP; hw_data->alloc_irq = adf_isr_resource_alloc; hw_data->free_irq = adf_isr_resource_free; hw_data->enable_error_correction = adf_enable_error_correction; @@ -352,11 +253,11 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) hw_data->uof_get_ae_mask = uof_get_ae_mask; hw_data->set_msix_rttable = set_msix_default_rttable; hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer; + hw_data->enable_pfvf_comms = adf_enable_pf2vf_comms; hw_data->disable_iov = adf_disable_sriov; - hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; adf_gen4_init_hw_csr_ops(&hw_data->csr_ops); - adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops); } void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data) diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h index 12e4fb9b40..924bac6feb 100644 --- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h +++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h @@ -37,7 +37,6 @@ /* Bank and ring configuration */ #define ADF_4XXX_NUM_RINGS_PER_BANK 2 -#define ADF_4XXX_NUM_BANKS_PER_VF 4 /* Error source registers */ #define ADF_4XXX_ERRSOU0 (0x41A200) @@ -77,7 +76,6 @@ #define ADF_4XXX_FW "qat_4xxx.bin" #define ADF_4XXX_MMP "qat_4xxx_mmp.bin" #define ADF_4XXX_SYM_OBJ "qat_4xxx_sym.bin" -#define ADF_4XXX_DC_OBJ "qat_4xxx_dc.bin" #define ADF_4XXX_ASYM_OBJ "qat_4xxx_asym.bin" #define ADF_4XXX_ADMIN_OBJ "qat_4xxx_admin.bin" diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c index a6c78b9c73..359fb7989d 100644 --- a/drivers/crypto/qat/qat_4xxx/adf_drv.c +++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c @@ -29,29 +29,6 @@ static void adf_cleanup_accel(struct adf_accel_dev *accel_dev) adf_devmgr_rm_dev(accel_dev, NULL); } -static int adf_cfg_dev_init(struct adf_accel_dev *accel_dev) -{ - const char *config; - int ret; - - config = accel_dev->accel_id % 2 ? ADF_CFG_DC : ADF_CFG_CY; - - ret = adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC); - if (ret) - return ret; - - /* Default configuration is crypto only for even devices - * and compression for odd devices - */ - ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, - ADF_SERVICES_ENABLED, config, - ADF_STR); - if (ret) - return ret; - - return 0; -} - static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev) { char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; @@ -250,18 +227,8 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_err; } - ret = adf_cfg_dev_init(accel_dev); - if (ret) { - dev_err(&pdev->dev, "Failed to initialize configuration.\n"); - goto out_err; - } - /* Get accelerator capabilities mask */ hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev); - if (!hw_data->accel_capabilities_mask) { - dev_err(&pdev->dev, "Failed to get capabilities mask.\n"); - goto out_err; - } /* Find and map all the device's BARS */ bar_mask = pci_select_bars(pdev, IORESOURCE_MEM) & ADF_4XXX_BAR_MASK; @@ -280,7 +247,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - adf_enable_aer(accel_dev); + if (adf_enable_aer(accel_dev)) { + dev_err(&pdev->dev, "Failed to enable aer.\n"); + ret = -EFAULT; + goto out_err; + } if (pci_save_state(pdev)) { dev_err(&pdev->dev, "Failed to save pci state.\n"); @@ -333,7 +304,6 @@ static struct pci_driver adf_driver = { .probe = adf_probe, .remove = adf_remove, .sriov_configure = adf_sriov_configure, - .err_handler = &adf_err_handler, }; module_pci_driver(adf_driver); diff --git a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c index b941fe3713..3027c01bc8 100644 --- a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c +++ b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2014 - 2021 Intel Corporation */ +/* Copyright(c) 2014 - 2020 Intel Corporation */ #include #include +#include #include -#include #include "adf_c3xxx_hw_data.h" #include "icp_qat_hw.h" @@ -48,6 +48,34 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ~(fuses | straps) & ADF_C3XXX_ACCELENGINES_MASK; } +static u32 get_num_accels(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->accel_mask) + return 0; + + for (i = 0; i < ADF_C3XXX_MAX_ACCELERATORS; i++) { + if (self->accel_mask & (1 << i)) + ctr++; + } + return ctr; +} + +static u32 get_num_aes(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->ae_mask) + return 0; + + for (i = 0; i < ADF_C3XXX_MAX_ACCELENGINES; i++) { + if (self->ae_mask & (1 << i)) + ctr++; + } + return ctr; +} + static u32 get_misc_bar_id(struct adf_hw_device_data *self) { return ADF_C3XXX_PMISC_BAR; @@ -60,12 +88,12 @@ static u32 get_etr_bar_id(struct adf_hw_device_data *self) static u32 get_sram_bar_id(struct adf_hw_device_data *self) { - return ADF_C3XXX_SRAM_BAR; + return 0; } static enum dev_sku_info get_sku(struct adf_hw_device_data *self) { - int aes = self->get_num_aes(self); + int aes = get_num_aes(self); if (aes == 6) return DEV_SKU_4; @@ -78,6 +106,41 @@ static const u32 *adf_get_arbiter_mapping(void) return thrd_to_arb_map; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_C3XXX_PF2VF_OFFSET(i); +} + +static void adf_enable_error_correction(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR]; + unsigned long accel_mask = hw_device->accel_mask; + unsigned long ae_mask = hw_device->ae_mask; + void __iomem *csr = misc_bar->virt_addr; + unsigned int val, i; + + /* Enable Accel Engine error detection & correction */ + for_each_set_bit(i, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) { + val = ADF_CSR_RD(csr, ADF_C3XXX_AE_CTX_ENABLES(i)); + val |= ADF_C3XXX_ENABLE_AE_ECC_ERR; + ADF_CSR_WR(csr, ADF_C3XXX_AE_CTX_ENABLES(i), val); + val = ADF_CSR_RD(csr, ADF_C3XXX_AE_MISC_CONTROL(i)); + val |= ADF_C3XXX_ENABLE_AE_ECC_PARITY_CORR; + ADF_CSR_WR(csr, ADF_C3XXX_AE_MISC_CONTROL(i), val); + } + + /* Enable shared memory error detection & correction */ + for_each_set_bit(i, &accel_mask, ADF_C3XXX_MAX_ACCELERATORS) { + val = ADF_CSR_RD(csr, ADF_C3XXX_UERRSSMSH(i)); + val |= ADF_C3XXX_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_C3XXX_UERRSSMSH(i), val); + val = ADF_CSR_RD(csr, ADF_C3XXX_CERRSSMSH(i)); + val |= ADF_C3XXX_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_C3XXX_CERRSSMSH(i), val); + } +} + static void adf_enable_ints(struct adf_accel_dev *accel_dev) { void __iomem *addr; @@ -91,6 +154,13 @@ static void adf_enable_ints(struct adf_accel_dev *accel_dev) ADF_C3XXX_SMIA1_MASK); } +static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) +{ + spin_lock_init(&accel_dev->pf.vf2pf_ints_lock); + + return 0; +} + static void configure_iov_threads(struct adf_accel_dev *accel_dev, bool enable) { adf_gen2_cfg_iov_thds(accel_dev, enable, @@ -107,17 +177,16 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->num_accel = ADF_C3XXX_MAX_ACCELERATORS; hw_data->num_logical_accel = 1; hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES; - hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET; - hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; + hw_data->tx_rx_gap = ADF_C3XXX_RX_RINGS_OFFSET; + hw_data->tx_rings_mask = ADF_C3XXX_TX_RINGS_MASK; hw_data->alloc_irq = adf_isr_resource_alloc; hw_data->free_irq = adf_isr_resource_free; - hw_data->enable_error_correction = adf_gen2_enable_error_correction; + hw_data->enable_error_correction = adf_enable_error_correction; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; - hw_data->get_num_aes = adf_gen2_get_num_aes; + hw_data->get_num_accels = get_num_accels; + hw_data->get_num_aes = get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; @@ -136,9 +205,11 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->reset_device = adf_reset_flr; hw_data->set_ssm_wdtimer = adf_gen2_set_ssm_wdtimer; + hw_data->get_pf2vf_offset = get_pf2vf_offset; + hw_data->enable_pfvf_comms = adf_enable_pf2vf_comms; hw_data->disable_iov = adf_disable_sriov; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; - adf_gen2_init_pf_pfvf_ops(&hw_data->pfvf_ops); adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.h b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.h index 1b86f82872..86ee02a867 100644 --- a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.h +++ b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.h @@ -6,7 +6,8 @@ /* PCIe configuration space */ #define ADF_C3XXX_PMISC_BAR 0 #define ADF_C3XXX_ETR_BAR 1 -#define ADF_C3XXX_SRAM_BAR 0 +#define ADF_C3XXX_RX_RINGS_OFFSET 8 +#define ADF_C3XXX_TX_RINGS_MASK 0xFF #define ADF_C3XXX_MAX_ACCELERATORS 3 #define ADF_C3XXX_MAX_ACCELENGINES 6 #define ADF_C3XXX_ACCELERATORS_REG_OFFSET 16 @@ -18,6 +19,16 @@ #define ADF_C3XXX_SMIA0_MASK 0xFFFF #define ADF_C3XXX_SMIA1_MASK 0x1 #define ADF_C3XXX_SOFTSTRAP_CSR_OFFSET 0x2EC +/* Error detection and correction */ +#define ADF_C3XXX_AE_CTX_ENABLES(i) (i * 0x1000 + 0x20818) +#define ADF_C3XXX_AE_MISC_CONTROL(i) (i * 0x1000 + 0x20960) +#define ADF_C3XXX_ENABLE_AE_ECC_ERR BIT(28) +#define ADF_C3XXX_ENABLE_AE_ECC_PARITY_CORR (BIT(24) | BIT(12)) +#define ADF_C3XXX_UERRSSMSH(i) (i * 0x4000 + 0x18) +#define ADF_C3XXX_CERRSSMSH(i) (i * 0x4000 + 0x10) +#define ADF_C3XXX_ERRSSMSH_EN BIT(3) + +#define ADF_C3XXX_PF2VF_OFFSET(i) (0x3A000 + 0x280 + ((i) * 0x04)) /* AE to function mapping */ #define ADF_C3XXX_AE2FUNC_MAP_GRP_A_NUM_REGS 48 diff --git a/drivers/crypto/qat/qat_c3xxx/adf_drv.c b/drivers/crypto/qat/qat_c3xxx/adf_drv.c index 2aef0bb791..cc6e75dc60 100644 --- a/drivers/crypto/qat/qat_c3xxx/adf_drv.c +++ b/drivers/crypto/qat/qat_c3xxx/adf_drv.c @@ -33,7 +33,6 @@ static struct pci_driver adf_driver = { .probe = adf_probe, .remove = adf_remove, .sriov_configure = adf_sriov_configure, - .err_handler = &adf_err_handler, }; static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev) @@ -193,7 +192,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); - adf_enable_aer(accel_dev); + if (adf_enable_aer(accel_dev)) { + dev_err(&pdev->dev, "Failed to enable aer\n"); + ret = -EFAULT; + goto out_err_free_reg; + } if (pci_save_state(pdev)) { dev_err(&pdev->dev, "Failed to save pci state\n"); diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c index a9fbe57b32..3e69b520e8 100644 --- a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c +++ b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c @@ -1,10 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2015 - 2021 Intel Corporation */ +/* Copyright(c) 2015 - 2020 Intel Corporation */ #include +#include #include #include -#include -#include #include "adf_c3xxxvf_hw_data.h" static struct adf_hw_device_class c3xxxiov_class = { @@ -48,6 +47,11 @@ static enum dev_sku_info get_sku(struct adf_hw_device_data *self) return DEV_SKU_VF; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_C3XXXIOV_PF2VF_OFFSET; +} + static int adf_vf_int_noop(struct adf_accel_dev *accel_dev) { return 0; @@ -67,7 +71,6 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data) hw_data->num_engines = ADF_C3XXXIOV_MAX_ACCELENGINES; hw_data->tx_rx_gap = ADF_C3XXXIOV_RX_RINGS_OFFSET; hw_data->tx_rings_mask = ADF_C3XXXIOV_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; hw_data->alloc_irq = adf_vf_isr_resource_alloc; hw_data->free_irq = adf_vf_isr_resource_free; hw_data->enable_error_correction = adf_vf_void_noop; @@ -83,11 +86,13 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data) hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; + hw_data->get_pf2vf_offset = get_pf2vf_offset; hw_data->get_sku = get_sku; hw_data->enable_ints = adf_vf_void_noop; + hw_data->enable_pfvf_comms = adf_enable_vf2pf_comms; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; hw_data->dev_class->instances++; adf_devmgr_update_class_index(hw_data); - adf_gen2_init_vf_pfvf_ops(&hw_data->pfvf_ops); adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.h b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.h index 6b4bf181d1..f5de4ce660 100644 --- a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.h +++ b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.h @@ -12,6 +12,7 @@ #define ADF_C3XXXIOV_TX_RINGS_MASK 0xFF #define ADF_C3XXXIOV_ETR_BAR 0 #define ADF_C3XXXIOV_ETR_MAX_BANKS 1 +#define ADF_C3XXXIOV_PF2VF_OFFSET 0x200 void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data); void adf_clean_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data); diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c index fa18d8009f..1df1b86897 100644 --- a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c +++ b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c @@ -171,7 +171,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); /* Completion for VF2PF request/response message exchange */ - init_completion(&accel_dev->vf.msg_received); + init_completion(&accel_dev->vf.iov_msg_completion); + + ret = qat_crypto_dev_config(accel_dev); + if (ret) + goto out_err_free_reg; ret = adf_dev_init(accel_dev); if (ret) diff --git a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c index b1eac2f81f..b023c80873 100644 --- a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c +++ b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2014 - 2021 Intel Corporation */ +/* Copyright(c) 2014 - 2020 Intel Corporation */ #include #include +#include #include -#include #include "adf_c62x_hw_data.h" #include "icp_qat_hw.h" @@ -48,6 +48,34 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ~(fuses | straps) & ADF_C62X_ACCELENGINES_MASK; } +static u32 get_num_accels(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->accel_mask) + return 0; + + for (i = 0; i < ADF_C62X_MAX_ACCELERATORS; i++) { + if (self->accel_mask & (1 << i)) + ctr++; + } + return ctr; +} + +static u32 get_num_aes(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->ae_mask) + return 0; + + for (i = 0; i < ADF_C62X_MAX_ACCELENGINES; i++) { + if (self->ae_mask & (1 << i)) + ctr++; + } + return ctr; +} + static u32 get_misc_bar_id(struct adf_hw_device_data *self) { return ADF_C62X_PMISC_BAR; @@ -65,7 +93,7 @@ static u32 get_sram_bar_id(struct adf_hw_device_data *self) static enum dev_sku_info get_sku(struct adf_hw_device_data *self) { - int aes = self->get_num_aes(self); + int aes = get_num_aes(self); if (aes == 8) return DEV_SKU_2; @@ -80,6 +108,41 @@ static const u32 *adf_get_arbiter_mapping(void) return thrd_to_arb_map; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_C62X_PF2VF_OFFSET(i); +} + +static void adf_enable_error_correction(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C62X_PMISC_BAR]; + unsigned long accel_mask = hw_device->accel_mask; + unsigned long ae_mask = hw_device->ae_mask; + void __iomem *csr = misc_bar->virt_addr; + unsigned int val, i; + + /* Enable Accel Engine error detection & correction */ + for_each_set_bit(i, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) { + val = ADF_CSR_RD(csr, ADF_C62X_AE_CTX_ENABLES(i)); + val |= ADF_C62X_ENABLE_AE_ECC_ERR; + ADF_CSR_WR(csr, ADF_C62X_AE_CTX_ENABLES(i), val); + val = ADF_CSR_RD(csr, ADF_C62X_AE_MISC_CONTROL(i)); + val |= ADF_C62X_ENABLE_AE_ECC_PARITY_CORR; + ADF_CSR_WR(csr, ADF_C62X_AE_MISC_CONTROL(i), val); + } + + /* Enable shared memory error detection & correction */ + for_each_set_bit(i, &accel_mask, ADF_C62X_MAX_ACCELERATORS) { + val = ADF_CSR_RD(csr, ADF_C62X_UERRSSMSH(i)); + val |= ADF_C62X_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_C62X_UERRSSMSH(i), val); + val = ADF_CSR_RD(csr, ADF_C62X_CERRSSMSH(i)); + val |= ADF_C62X_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_C62X_CERRSSMSH(i), val); + } +} + static void adf_enable_ints(struct adf_accel_dev *accel_dev) { void __iomem *addr; @@ -93,6 +156,13 @@ static void adf_enable_ints(struct adf_accel_dev *accel_dev) ADF_C62X_SMIA1_MASK); } +static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) +{ + spin_lock_init(&accel_dev->pf.vf2pf_ints_lock); + + return 0; +} + static void configure_iov_threads(struct adf_accel_dev *accel_dev, bool enable) { adf_gen2_cfg_iov_thds(accel_dev, enable, @@ -109,17 +179,16 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->num_accel = ADF_C62X_MAX_ACCELERATORS; hw_data->num_logical_accel = 1; hw_data->num_engines = ADF_C62X_MAX_ACCELENGINES; - hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET; - hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; + hw_data->tx_rx_gap = ADF_C62X_RX_RINGS_OFFSET; + hw_data->tx_rings_mask = ADF_C62X_TX_RINGS_MASK; hw_data->alloc_irq = adf_isr_resource_alloc; hw_data->free_irq = adf_isr_resource_free; - hw_data->enable_error_correction = adf_gen2_enable_error_correction; + hw_data->enable_error_correction = adf_enable_error_correction; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; - hw_data->get_num_aes = adf_gen2_get_num_aes; + hw_data->get_num_accels = get_num_accels; + hw_data->get_num_aes = get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; @@ -138,9 +207,11 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->enable_ints = adf_enable_ints; hw_data->reset_device = adf_reset_flr; hw_data->set_ssm_wdtimer = adf_gen2_set_ssm_wdtimer; + hw_data->get_pf2vf_offset = get_pf2vf_offset; + hw_data->enable_pfvf_comms = adf_enable_pf2vf_comms; hw_data->disable_iov = adf_disable_sriov; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; - adf_gen2_init_pf_pfvf_ops(&hw_data->pfvf_ops); adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.h b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.h index 68c3436bd3..e6664bd20c 100644 --- a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.h +++ b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.h @@ -7,6 +7,8 @@ #define ADF_C62X_SRAM_BAR 0 #define ADF_C62X_PMISC_BAR 1 #define ADF_C62X_ETR_BAR 2 +#define ADF_C62X_RX_RINGS_OFFSET 8 +#define ADF_C62X_TX_RINGS_MASK 0xFF #define ADF_C62X_MAX_ACCELERATORS 5 #define ADF_C62X_MAX_ACCELENGINES 10 #define ADF_C62X_ACCELERATORS_REG_OFFSET 16 @@ -18,6 +20,16 @@ #define ADF_C62X_SMIA0_MASK 0xFFFF #define ADF_C62X_SMIA1_MASK 0x1 #define ADF_C62X_SOFTSTRAP_CSR_OFFSET 0x2EC +/* Error detection and correction */ +#define ADF_C62X_AE_CTX_ENABLES(i) (i * 0x1000 + 0x20818) +#define ADF_C62X_AE_MISC_CONTROL(i) (i * 0x1000 + 0x20960) +#define ADF_C62X_ENABLE_AE_ECC_ERR BIT(28) +#define ADF_C62X_ENABLE_AE_ECC_PARITY_CORR (BIT(24) | BIT(12)) +#define ADF_C62X_UERRSSMSH(i) (i * 0x4000 + 0x18) +#define ADF_C62X_CERRSSMSH(i) (i * 0x4000 + 0x10) +#define ADF_C62X_ERRSSMSH_EN BIT(3) + +#define ADF_C62X_PF2VF_OFFSET(i) (0x3A000 + 0x280 + ((i) * 0x04)) /* AE to function mapping */ #define ADF_C62X_AE2FUNC_MAP_GRP_A_NUM_REGS 80 diff --git a/drivers/crypto/qat/qat_c62x/adf_drv.c b/drivers/crypto/qat/qat_c62x/adf_drv.c index 56163083f1..bf251dfe74 100644 --- a/drivers/crypto/qat/qat_c62x/adf_drv.c +++ b/drivers/crypto/qat/qat_c62x/adf_drv.c @@ -33,7 +33,6 @@ static struct pci_driver adf_driver = { .probe = adf_probe, .remove = adf_remove, .sriov_configure = adf_sriov_configure, - .err_handler = &adf_err_handler, }; static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev) @@ -193,7 +192,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); - adf_enable_aer(accel_dev); + if (adf_enable_aer(accel_dev)) { + dev_err(&pdev->dev, "Failed to enable aer\n"); + ret = -EFAULT; + goto out_err_free_reg; + } if (pci_save_state(pdev)) { dev_err(&pdev->dev, "Failed to save pci state\n"); diff --git a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c index 0282038fca..3bee3e4673 100644 --- a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c +++ b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c @@ -1,10 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2015 - 2021 Intel Corporation */ +/* Copyright(c) 2015 - 2020 Intel Corporation */ #include +#include #include #include -#include -#include #include "adf_c62xvf_hw_data.h" static struct adf_hw_device_class c62xiov_class = { @@ -48,6 +47,11 @@ static enum dev_sku_info get_sku(struct adf_hw_device_data *self) return DEV_SKU_VF; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_C62XIOV_PF2VF_OFFSET; +} + static int adf_vf_int_noop(struct adf_accel_dev *accel_dev) { return 0; @@ -67,7 +71,6 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data) hw_data->num_engines = ADF_C62XIOV_MAX_ACCELENGINES; hw_data->tx_rx_gap = ADF_C62XIOV_RX_RINGS_OFFSET; hw_data->tx_rings_mask = ADF_C62XIOV_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; hw_data->alloc_irq = adf_vf_isr_resource_alloc; hw_data->free_irq = adf_vf_isr_resource_free; hw_data->enable_error_correction = adf_vf_void_noop; @@ -83,11 +86,13 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data) hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; + hw_data->get_pf2vf_offset = get_pf2vf_offset; hw_data->get_sku = get_sku; hw_data->enable_ints = adf_vf_void_noop; + hw_data->enable_pfvf_comms = adf_enable_vf2pf_comms; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; hw_data->dev_class->instances++; adf_devmgr_update_class_index(hw_data); - adf_gen2_init_vf_pfvf_ops(&hw_data->pfvf_ops); adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.h b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.h index a1a62c003e..794778c486 100644 --- a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.h +++ b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.h @@ -12,6 +12,7 @@ #define ADF_C62XIOV_TX_RINGS_MASK 0xFF #define ADF_C62XIOV_ETR_BAR 0 #define ADF_C62XIOV_ETR_MAX_BANKS 1 +#define ADF_C62XIOV_PF2VF_OFFSET 0x200 void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data); void adf_clean_hw_data_c62xiov(struct adf_hw_device_data *hw_data); diff --git a/drivers/crypto/qat/qat_c62xvf/adf_drv.c b/drivers/crypto/qat/qat_c62xvf/adf_drv.c index 686ec752d0..8103bd81d6 100644 --- a/drivers/crypto/qat/qat_c62xvf/adf_drv.c +++ b/drivers/crypto/qat/qat_c62xvf/adf_drv.c @@ -171,7 +171,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); /* Completion for VF2PF request/response message exchange */ - init_completion(&accel_dev->vf.msg_received); + init_completion(&accel_dev->vf.iov_msg_completion); + + ret = qat_crypto_dev_config(accel_dev); + if (ret) + goto out_err_free_reg; ret = adf_dev_init(accel_dev); if (ret) diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile index 7e191a42a5..9c57abdf56 100644 --- a/drivers/crypto/qat/qat_common/Makefile +++ b/drivers/crypto/qat/qat_common/Makefile @@ -19,7 +19,5 @@ intel_qat-objs := adf_cfg.o \ qat_hal.o intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o -intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \ - adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \ - adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \ - adf_gen2_pfvf.o adf_gen4_pfvf.o +intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_pf2vf_msg.o \ + adf_vf2pf_msg.o adf_vf_isr.o diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h index 2d4cd7c7cf..580566cfcb 100644 --- a/drivers/crypto/qat/qat_common/adf_accel_devices.h +++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h @@ -8,7 +8,6 @@ #include #include #include "adf_cfg_common.h" -#include "adf_pfvf_msg.h" #define ADF_DH895XCC_DEVICE_NAME "dh895xcc" #define ADF_DH895XCCVF_DEVICE_NAME "dh895xccvf" @@ -43,17 +42,13 @@ struct adf_bar { resource_size_t base_addr; void __iomem *virt_addr; resource_size_t size; -}; - -struct adf_irq { - bool enabled; - char name[ADF_MAX_MSIX_VECTOR_NAME]; -}; +} __packed; struct adf_accel_msix { - struct adf_irq *irqs; + struct msix_entry *entries; + char **names; u32 num_entries; -}; +} __packed; struct adf_accel_pci { struct pci_dev *pci_dev; @@ -61,7 +56,7 @@ struct adf_accel_pci { struct adf_bar pci_bars[ADF_PCI_MAX_BARS]; u8 revid; u8 sku; -}; +} __packed; enum dev_state { DEV_DOWN = 0, @@ -101,7 +96,7 @@ struct adf_hw_device_class { const char *name; const enum adf_device_type type; u32 instances; -}; +} __packed; struct arb_info { u32 arb_cfg; @@ -148,19 +143,6 @@ struct adf_accel_dev; struct adf_etr_data; struct adf_etr_ring_data; -struct adf_pfvf_ops { - int (*enable_comms)(struct adf_accel_dev *accel_dev); - u32 (*get_pf2vf_offset)(u32 i); - u32 (*get_vf2pf_offset)(u32 i); - u32 (*get_vf2pf_sources)(void __iomem *pmisc_addr); - void (*enable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask); - void (*disable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask); - int (*send_msg)(struct adf_accel_dev *accel_dev, struct pfvf_message msg, - u32 pfvf_offset, struct mutex *csr_lock); - struct pfvf_message (*recv_msg)(struct adf_accel_dev *accel_dev, - u32 pfvf_offset, u8 compat_ver); -}; - struct adf_hw_device_data { struct adf_hw_device_class *dev_class; u32 (*get_accel_mask)(struct adf_hw_device_data *self); @@ -171,6 +153,7 @@ struct adf_hw_device_data { u32 (*get_etr_bar_id)(struct adf_hw_device_data *self); u32 (*get_num_aes)(struct adf_hw_device_data *self); u32 (*get_num_accels)(struct adf_hw_device_data *self); + u32 (*get_pf2vf_offset)(u32 i); void (*get_arb_info)(struct arb_info *arb_csrs_info); void (*get_admin_info)(struct admin_info *admin_csrs_info); enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self); @@ -189,35 +172,31 @@ struct adf_hw_device_data { bool enable); void (*enable_ints)(struct adf_accel_dev *accel_dev); void (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev); - int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, u32 bank_nr); + int (*enable_pfvf_comms)(struct adf_accel_dev *accel_dev); void (*reset_device)(struct adf_accel_dev *accel_dev); void (*set_msix_rttable)(struct adf_accel_dev *accel_dev); - char *(*uof_get_name)(struct adf_accel_dev *accel_dev, u32 obj_num); + char *(*uof_get_name)(u32 obj_num); u32 (*uof_get_num_objs)(void); - u32 (*uof_get_ae_mask)(struct adf_accel_dev *accel_dev, u32 obj_num); - struct adf_pfvf_ops pfvf_ops; + u32 (*uof_get_ae_mask)(u32 obj_num); struct adf_hw_csr_ops csr_ops; const char *fw_name; const char *fw_mmp_name; u32 fuses; u32 straps; u32 accel_capabilities_mask; - u32 extended_dc_capabilities; - u32 clock_frequency; u32 instance_id; u16 accel_mask; u32 ae_mask; u32 admin_ae_mask; u16 tx_rings_mask; - u16 ring_to_svc_map; u8 tx_rx_gap; u8 num_banks; - u16 num_banks_per_vf; u8 num_rings_per_bank; u8 num_accel; u8 num_logical_accel; u8 num_engines; -}; + u8 min_iov_compat_ver; +} __packed; /* CSR write macro */ #define ADF_CSR_WR(csr_base, csr_offset, val) \ @@ -226,22 +205,14 @@ struct adf_hw_device_data { /* CSR read macro */ #define ADF_CSR_RD(csr_base, csr_offset) __raw_readl(csr_base + csr_offset) -#define ADF_CFG_NUM_SERVICES 4 -#define ADF_SRV_TYPE_BIT_LEN 3 -#define ADF_SRV_TYPE_MASK 0x7 - #define GET_DEV(accel_dev) ((accel_dev)->accel_pci_dev.pci_dev->dev) #define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars) #define GET_HW_DATA(accel_dev) (accel_dev->hw_device) #define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks) #define GET_NUM_RINGS_PER_BANK(accel_dev) \ GET_HW_DATA(accel_dev)->num_rings_per_bank -#define GET_SRV_TYPE(accel_dev, idx) \ - (((GET_HW_DATA(accel_dev)->ring_to_svc_map) >> (ADF_SRV_TYPE_BIT_LEN * (idx))) \ - & ADF_SRV_TYPE_MASK) #define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines) #define GET_CSR_OPS(accel_dev) (&(accel_dev)->hw_device->csr_ops) -#define GET_PFVF_OPS(accel_dev) (&(accel_dev)->hw_device->pfvf_ops) #define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev struct adf_admin_comms; @@ -258,7 +229,6 @@ struct adf_accel_vf_info { struct ratelimit_state vf2pf_ratelimit; u32 vf_nr; bool init; - u8 vf_compat_ver; }; struct adf_accel_dev { @@ -282,16 +252,15 @@ struct adf_accel_dev { struct adf_accel_vf_info *vf_info; } pf; struct { - bool irq_enabled; - char irq_name[ADF_MAX_MSIX_VECTOR_NAME]; + char *irq_name; struct tasklet_struct pf2vf_bh_tasklet; struct mutex vf2pf_lock; /* protect CSR access */ - struct completion msg_received; - struct pfvf_message response; /* temp field holding pf2vf response */ - u8 pf_compat_ver; + struct completion iov_msg_completion; + u8 compatible; + u8 pf_version; } vf; }; bool is_vf; u32 accel_id; -}; +} __packed; #endif diff --git a/drivers/crypto/qat/qat_common/adf_accel_engine.c b/drivers/crypto/qat/qat_common/adf_accel_engine.c index 4ce2b66692..ca4eae8cdd 100644 --- a/drivers/crypto/qat/qat_common/adf_accel_engine.c +++ b/drivers/crypto/qat/qat_common/adf_accel_engine.c @@ -22,12 +22,8 @@ static int adf_ae_fw_load_images(struct adf_accel_dev *accel_dev, void *fw_addr, num_objs = hw_device->uof_get_num_objs(); for (i = 0; i < num_objs; i++) { - obj_name = hw_device->uof_get_name(accel_dev, i); - ae_mask = hw_device->uof_get_ae_mask(accel_dev, i); - if (!obj_name || !ae_mask) { - dev_err(&GET_DEV(accel_dev), "Invalid UOF image\n"); - goto out_err; - } + obj_name = hw_device->uof_get_name(i); + ae_mask = hw_device->uof_get_ae_mask(i); if (qat_uclo_set_cfg_ae_mask(loader, ae_mask)) { dev_err(&GET_DEV(accel_dev), diff --git a/drivers/crypto/qat/qat_common/adf_admin.c b/drivers/crypto/qat/qat_common/adf_admin.c index 498eb6f690..43680e1782 100644 --- a/drivers/crypto/qat/qat_common/adf_admin.c +++ b/drivers/crypto/qat/qat_common/adf_admin.c @@ -194,35 +194,6 @@ static int adf_set_fw_constants(struct adf_accel_dev *accel_dev) return adf_send_admin(accel_dev, &req, &resp, ae_mask); } -static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, - u32 *capabilities) -{ - struct adf_hw_device_data *hw_device = accel_dev->hw_device; - struct icp_qat_fw_init_admin_resp resp; - struct icp_qat_fw_init_admin_req req; - unsigned long ae_mask; - unsigned long ae; - int ret; - - /* Target only service accelerator engines */ - ae_mask = hw_device->ae_mask & ~hw_device->admin_ae_mask; - - memset(&req, 0, sizeof(req)); - memset(&resp, 0, sizeof(resp)); - req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET; - - *capabilities = 0; - for_each_set_bit(ae, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) { - ret = adf_send_admin(accel_dev, &req, &resp, 1ULL << ae); - if (ret) - return ret; - - *capabilities |= resp.extended_features; - } - - return 0; -} - /** * adf_send_admin_init() - Function sends init message to FW * @accel_dev: Pointer to acceleration device. @@ -233,16 +204,8 @@ static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, */ int adf_send_admin_init(struct adf_accel_dev *accel_dev) { - u32 dc_capabilities = 0; int ret; - ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities); - if (ret) { - dev_err(&GET_DEV(accel_dev), "Cannot get dc capabilities\n"); - return ret; - } - accel_dev->hw_device->extended_dc_capabilities = dc_capabilities; - ret = adf_set_fw_constants(accel_dev); if (ret) return ret; @@ -255,7 +218,9 @@ int adf_init_admin_comms(struct adf_accel_dev *accel_dev) { struct adf_admin_comms *admin; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_bar *pmisc = + &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + void __iomem *csr = pmisc->virt_addr; struct admin_info admin_csrs_info; u32 mailbox_offset, adminmsg_u, adminmsg_l; void __iomem *mailbox; @@ -289,13 +254,13 @@ int adf_init_admin_comms(struct adf_accel_dev *accel_dev) hw_data->get_admin_info(&admin_csrs_info); mailbox_offset = admin_csrs_info.mailbox_offset; - mailbox = pmisc_addr + mailbox_offset; + mailbox = csr + mailbox_offset; adminmsg_u = admin_csrs_info.admin_msg_ur; adminmsg_l = admin_csrs_info.admin_msg_lr; reg_val = (u64)admin->phy_addr; - ADF_CSR_WR(pmisc_addr, adminmsg_u, upper_32_bits(reg_val)); - ADF_CSR_WR(pmisc_addr, adminmsg_l, lower_32_bits(reg_val)); + ADF_CSR_WR(csr, adminmsg_u, upper_32_bits(reg_val)); + ADF_CSR_WR(csr, adminmsg_l, lower_32_bits(reg_val)); mutex_init(&admin->lock); admin->mailbox_addr = mailbox; diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c index fe9bb2f353..ed3e40bc56 100644 --- a/drivers/crypto/qat/qat_common/adf_aer.c +++ b/drivers/crypto/qat/qat_common/adf_aer.c @@ -166,12 +166,11 @@ static void adf_resume(struct pci_dev *pdev) dev_info(&pdev->dev, "Device is up and running\n"); } -const struct pci_error_handlers adf_err_handler = { +static const struct pci_error_handlers adf_err_handler = { .error_detected = adf_error_detected, .slot_reset = adf_slot_reset, .resume = adf_resume, }; -EXPORT_SYMBOL_GPL(adf_err_handler); /** * adf_enable_aer() - Enable Advance Error Reporting for acceleration device @@ -180,12 +179,17 @@ EXPORT_SYMBOL_GPL(adf_err_handler); * Function enables PCI Advance Error Reporting for the * QAT acceleration device accel_dev. * To be used by QAT device specific drivers. + * + * Return: 0 on success, error code otherwise. */ -void adf_enable_aer(struct adf_accel_dev *accel_dev) +int adf_enable_aer(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); + struct pci_driver *pdrv = pdev->driver; + pdrv->err_handler = &adf_err_handler; pci_enable_pcie_error_reporting(pdev); + return 0; } EXPORT_SYMBOL_GPL(adf_enable_aer); diff --git a/drivers/crypto/qat/qat_common/adf_cfg.c b/drivers/crypto/qat/qat_common/adf_cfg.c index b5b208cbe5..575b6f0023 100644 --- a/drivers/crypto/qat/qat_common/adf_cfg.c +++ b/drivers/crypto/qat/qat_common/adf_cfg.c @@ -297,4 +297,3 @@ int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev, up_read(&cfg->lock); return ret; } -EXPORT_SYMBOL_GPL(adf_cfg_get_param_value); diff --git a/drivers/crypto/qat/qat_common/adf_cfg_common.h b/drivers/crypto/qat/qat_common/adf_cfg_common.h index 6e5de1dab9..4fabb70b1f 100644 --- a/drivers/crypto/qat/qat_common/adf_cfg_common.h +++ b/drivers/crypto/qat/qat_common/adf_cfg_common.h @@ -19,19 +19,6 @@ #define ADF_MAX_DEVICES (32 * 32) #define ADF_DEVS_ARRAY_SIZE BITS_TO_LONGS(ADF_MAX_DEVICES) -#define ADF_CFG_SERV_RING_PAIR_0_SHIFT 0 -#define ADF_CFG_SERV_RING_PAIR_1_SHIFT 3 -#define ADF_CFG_SERV_RING_PAIR_2_SHIFT 6 -#define ADF_CFG_SERV_RING_PAIR_3_SHIFT 9 -enum adf_cfg_service_type { - UNUSED = 0, - CRYPTO, - COMP, - SYM, - ASYM, - USED -}; - enum adf_cfg_val_type { ADF_DEC, ADF_HEX, diff --git a/drivers/crypto/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/qat/qat_common/adf_cfg_strings.h index 655248dbf9..09651e1f93 100644 --- a/drivers/crypto/qat/qat_common/adf_cfg_strings.h +++ b/drivers/crypto/qat/qat_common/adf_cfg_strings.h @@ -22,9 +22,6 @@ #define ADF_RING_ASYM_BANK_NUM "BankAsymNumber" #define ADF_CY "Cy" #define ADF_DC "Dc" -#define ADF_CFG_DC "dc" -#define ADF_CFG_CY "sym;asym" -#define ADF_SERVICES_ENABLED "ServicesEnabled" #define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled" #define ADF_ETRMGR_COALESCING_ENABLED_FORMAT \ ADF_ETRMGR_BANK "%d" ADF_ETRMGR_COALESCING_ENABLED diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h index 76f4f96ec5..4261749fae 100644 --- a/drivers/crypto/qat/qat_common/adf_common_drv.h +++ b/drivers/crypto/qat/qat_common/adf_common_drv.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */ -/* Copyright(c) 2014 - 2021 Intel Corporation */ +/* Copyright(c) 2014 - 2020 Intel Corporation */ #ifndef ADF_DRV_H #define ADF_DRV_H @@ -62,6 +62,10 @@ int adf_dev_start(struct adf_accel_dev *accel_dev); void adf_dev_stop(struct adf_accel_dev *accel_dev); void adf_dev_shutdown(struct adf_accel_dev *accel_dev); +int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); +void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); +int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); +void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info); void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); void adf_clean_vf_map(bool); @@ -91,8 +95,7 @@ void adf_ae_fw_release(struct adf_accel_dev *accel_dev); int adf_ae_start(struct adf_accel_dev *accel_dev); int adf_ae_stop(struct adf_accel_dev *accel_dev); -extern const struct pci_error_handlers adf_err_handler; -void adf_enable_aer(struct adf_accel_dev *accel_dev); +int adf_enable_aer(struct adf_accel_dev *accel_dev); void adf_disable_aer(struct adf_accel_dev *accel_dev); void adf_reset_sbr(struct adf_accel_dev *accel_dev); void adf_reset_flr(struct adf_accel_dev *accel_dev); @@ -114,7 +117,6 @@ void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev); int qat_crypto_register(void); int qat_crypto_unregister(void); int qat_crypto_dev_config(struct adf_accel_dev *accel_dev); -int qat_crypto_vf_dev_config(struct adf_accel_dev *accel_dev); struct qat_crypto_instance *qat_crypto_get_instance_node(int node); void qat_crypto_put_instance(struct qat_crypto_instance *inst); void qat_alg_callback(void *resp); @@ -129,8 +131,6 @@ void adf_isr_resource_free(struct adf_accel_dev *accel_dev); int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev); void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev); -int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev); - int qat_hal_init(struct adf_accel_dev *accel_dev); void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle); int qat_hal_start(struct icp_qat_fw_loader_handle *handle); @@ -193,14 +193,16 @@ int adf_sriov_configure(struct pci_dev *pdev, int numvfs); void adf_disable_sriov(struct adf_accel_dev *accel_dev); void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask); +void adf_disable_vf2pf_interrupts_irq(struct adf_accel_dev *accel_dev, + u32 vf_mask); void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask); -bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev); -bool adf_recv_and_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr); -int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev); void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_schedule_vf2pf_handler(struct adf_accel_vf_info *vf_info); + +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev); +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev); int adf_init_pf_wq(void); void adf_exit_pf_wq(void); int adf_init_vf_wq(void); @@ -221,6 +223,15 @@ static inline void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) { } +static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) +{ + return 0; +} + +static inline void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) +{ +} + static inline int adf_init_pf_wq(void) { return 0; @@ -244,15 +255,4 @@ static inline void adf_flush_vf_wq(struct adf_accel_dev *accel_dev) } #endif - -static inline void __iomem *adf_get_pmisc_base(struct adf_accel_dev *accel_dev) -{ - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct adf_bar *pmisc; - - pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; - - return pmisc->virt_addr; -} - #endif diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c index 57035b7dd4..9e560c7d41 100644 --- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c +++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c @@ -1,64 +1,21 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2020 Intel Corporation */ -#include "adf_common_drv.h" #include "adf_gen2_hw_data.h" #include "icp_qat_hw.h" #include -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self) -{ - if (!self || !self->accel_mask) - return 0; - - return hweight16(self->accel_mask); -} -EXPORT_SYMBOL_GPL(adf_gen2_get_num_accels); - -u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self) -{ - if (!self || !self->ae_mask) - return 0; - - return hweight32(self->ae_mask); -} -EXPORT_SYMBOL_GPL(adf_gen2_get_num_aes); - -void adf_gen2_enable_error_correction(struct adf_accel_dev *accel_dev) -{ - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); - unsigned long accel_mask = hw_data->accel_mask; - unsigned long ae_mask = hw_data->ae_mask; - unsigned int val, i; - - /* Enable Accel Engine error detection & correction */ - for_each_set_bit(i, &ae_mask, hw_data->num_engines) { - val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_AE_CTX_ENABLES(i)); - val |= ADF_GEN2_ENABLE_AE_ECC_ERR; - ADF_CSR_WR(pmisc_addr, ADF_GEN2_AE_CTX_ENABLES(i), val); - val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_AE_MISC_CONTROL(i)); - val |= ADF_GEN2_ENABLE_AE_ECC_PARITY_CORR; - ADF_CSR_WR(pmisc_addr, ADF_GEN2_AE_MISC_CONTROL(i), val); - } - - /* Enable shared memory error detection & correction */ - for_each_set_bit(i, &accel_mask, hw_data->num_accel) { - val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_UERRSSMSH(i)); - val |= ADF_GEN2_ERRSSMSH_EN; - ADF_CSR_WR(pmisc_addr, ADF_GEN2_UERRSSMSH(i), val); - val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_CERRSSMSH(i)); - val |= ADF_GEN2_ERRSSMSH_EN; - ADF_CSR_WR(pmisc_addr, ADF_GEN2_CERRSSMSH(i), val); - } -} -EXPORT_SYMBOL_GPL(adf_gen2_enable_error_correction); - void adf_gen2_cfg_iov_thds(struct adf_accel_dev *accel_dev, bool enable, int num_a_regs, int num_b_regs) { - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + void __iomem *pmisc_addr; + struct adf_bar *pmisc; + int pmisc_id, i; u32 reg; - int i; + + pmisc_id = hw_data->get_misc_bar_id(hw_data); + pmisc = &GET_BARS(accel_dev)[pmisc_id]; + pmisc_addr = pmisc->virt_addr; /* Set/Unset Valid bit in AE Thread to PCIe Function Mapping Group A */ for (i = 0; i < num_a_regs; i++) { @@ -204,33 +161,21 @@ u32 adf_gen2_get_accel_cap(struct adf_accel_dev *accel_dev) u32 legfuses; u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | - ICP_ACCEL_CAPABILITIES_AUTHENTICATION | - ICP_ACCEL_CAPABILITIES_CIPHER | - ICP_ACCEL_CAPABILITIES_COMPRESSION; + ICP_ACCEL_CAPABILITIES_AUTHENTICATION; /* Read accelerator capabilities mask */ pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses); - /* A set bit in legfuses means the feature is OFF in this SKU */ - if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) { + if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; - capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; - } if (legfuses & ICP_ACCEL_MASK_PKE_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) { + if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; - capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; - } - if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) - capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; if ((straps | fuses) & ADF_POWERGATE_PKE) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - if ((straps | fuses) & ADF_POWERGATE_DC) - capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; - return capabilities; } EXPORT_SYMBOL_GPL(adf_gen2_get_accel_cap); @@ -238,12 +183,18 @@ EXPORT_SYMBOL_GPL(adf_gen2_get_accel_cap); void adf_gen2_set_ssm_wdtimer(struct adf_accel_dev *accel_dev) { struct adf_hw_device_data *hw_data = accel_dev->hw_device; - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); u32 timer_val_pke = ADF_SSM_WDT_PKE_DEFAULT_VALUE; u32 timer_val = ADF_SSM_WDT_DEFAULT_VALUE; unsigned long accel_mask = hw_data->accel_mask; + void __iomem *pmisc_addr; + struct adf_bar *pmisc; + int pmisc_id; u32 i = 0; + pmisc_id = hw_data->get_misc_bar_id(hw_data); + pmisc = &GET_BARS(accel_dev)[pmisc_id]; + pmisc_addr = pmisc->virt_addr; + /* Configures WDT timers */ for_each_set_bit(i, &accel_mask, hw_data->num_accel) { /* Enable WDT for sym and dc */ diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h index f2e0451b11..756b0ddfac 100644 --- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h +++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h @@ -4,7 +4,6 @@ #define ADF_GEN2_HW_DATA_H_ #include "adf_accel_devices.h" -#include "adf_cfg_common.h" /* Transport access */ #define ADF_BANK_INT_SRC_SEL_MASK_0 0x4444444CUL @@ -23,8 +22,6 @@ #define ADF_RING_CSR_INT_FLAG_AND_COL 0x184 #define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000 #define ADF_RING_BUNDLE_SIZE 0x1000 -#define ADF_GEN2_RX_RINGS_OFFSET 8 -#define ADF_GEN2_TX_RINGS_MASK 0xFF #define BUILD_RING_BASE_ADDR(addr, size) \ (((addr) >> 6) & (GENMASK_ULL(63, 0) << (size))) @@ -114,16 +111,8 @@ do { \ (ADF_ARB_REG_SLOT * (index)), value) /* Power gating */ -#define ADF_POWERGATE_DC BIT(23) #define ADF_POWERGATE_PKE BIT(24) -/* Default ring mapping */ -#define ADF_GEN2_DEFAULT_RING_TO_SRV_MAP \ - (CRYPTO << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \ - CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ - UNUSED << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ - COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) - /* WDT timers * * Timeout is in cycles. Clock speed may vary across products but this @@ -136,18 +125,6 @@ do { \ #define ADF_SSMWDT(i) (ADF_SSMWDT_OFFSET + ((i) * 0x4000)) #define ADF_SSMWDTPKE(i) (ADF_SSMWDTPKE_OFFSET + ((i) * 0x4000)) -/* Error detection and correction */ -#define ADF_GEN2_AE_CTX_ENABLES(i) ((i) * 0x1000 + 0x20818) -#define ADF_GEN2_AE_MISC_CONTROL(i) ((i) * 0x1000 + 0x20960) -#define ADF_GEN2_ENABLE_AE_ECC_ERR BIT(28) -#define ADF_GEN2_ENABLE_AE_ECC_PARITY_CORR (BIT(24) | BIT(12)) -#define ADF_GEN2_UERRSSMSH(i) ((i) * 0x4000 + 0x18) -#define ADF_GEN2_CERRSSMSH(i) ((i) * 0x4000 + 0x10) -#define ADF_GEN2_ERRSSMSH_EN BIT(3) - -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self); -u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self); -void adf_gen2_enable_error_correction(struct adf_accel_dev *accel_dev); void adf_gen2_cfg_iov_thds(struct adf_accel_dev *accel_dev, bool enable, int num_a_regs, int num_b_regs); void adf_gen2_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops); diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c index 3148a62938..000528327b 100644 --- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c +++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2020 Intel Corporation */ -#include #include "adf_accel_devices.h" -#include "adf_common_drv.h" #include "adf_gen4_hw_data.h" static u64 build_csr_ring_base_addr(dma_addr_t addr, u32 size) @@ -111,13 +109,20 @@ static inline void adf_gen4_unpack_ssm_wdtimer(u64 value, u32 *upper, void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev) { - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; u64 timer_val_pke = ADF_SSM_WDT_PKE_DEFAULT_VALUE; u64 timer_val = ADF_SSM_WDT_DEFAULT_VALUE; u32 ssm_wdt_pke_high = 0; u32 ssm_wdt_pke_low = 0; u32 ssm_wdt_high = 0; u32 ssm_wdt_low = 0; + void __iomem *pmisc_addr; + struct adf_bar *pmisc; + int pmisc_id; + + pmisc_id = hw_data->get_misc_bar_id(hw_data); + pmisc = &GET_BARS(accel_dev)[pmisc_id]; + pmisc_addr = pmisc->virt_addr; /* Convert 64bit WDT timer value into 32bit values for * mmio write to 32bit CSRs. @@ -134,61 +139,3 @@ void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev) ADF_CSR_WR(pmisc_addr, ADF_SSMWDTPKEH_OFFSET, ssm_wdt_pke_high); } EXPORT_SYMBOL_GPL(adf_gen4_set_ssm_wdtimer); - -int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev) -{ - return 0; -} -EXPORT_SYMBOL_GPL(adf_pfvf_comms_disabled); - -static int reset_ring_pair(void __iomem *csr, u32 bank_number) -{ - u32 status; - int ret; - - /* Write rpresetctl register BIT(0) as 1 - * Since rpresetctl registers have no RW fields, no need to preserve - * values for other bits. Just write directly. - */ - ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETCTL(bank_number), - ADF_WQM_CSR_RPRESETCTL_RESET); - - /* Read rpresetsts register and wait for rp reset to complete */ - ret = read_poll_timeout(ADF_CSR_RD, status, - status & ADF_WQM_CSR_RPRESETSTS_STATUS, - ADF_RPRESET_POLL_DELAY_US, - ADF_RPRESET_POLL_TIMEOUT_US, true, - csr, ADF_WQM_CSR_RPRESETSTS(bank_number)); - if (!ret) { - /* When rp reset is done, clear rpresetsts */ - ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETSTS(bank_number), - ADF_WQM_CSR_RPRESETSTS_STATUS); - } - - return ret; -} - -int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number) -{ - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - u32 etr_bar_id = hw_data->get_etr_bar_id(hw_data); - void __iomem *csr; - int ret; - - if (bank_number >= hw_data->num_banks) - return -EINVAL; - - dev_dbg(&GET_DEV(accel_dev), - "ring pair reset for bank:%d\n", bank_number); - - csr = (&GET_BARS(accel_dev)[etr_bar_id])->virt_addr; - ret = reset_ring_pair(csr, bank_number); - if (ret) - dev_err(&GET_DEV(accel_dev), - "ring pair reset failed (timeout)\n"); - else - dev_dbg(&GET_DEV(accel_dev), "ring pair reset successful\n"); - - return ret; -} -EXPORT_SYMBOL_GPL(adf_gen4_ring_pair_reset); diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h index f0f71ca44c..b8fca1ff7a 100644 --- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h +++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h @@ -4,7 +4,6 @@ #define ADF_GEN4_HW_CSR_DATA_H_ #include "adf_accel_devices.h" -#include "adf_cfg_common.h" /* Transport access */ #define ADF_BANK_INT_SRC_SEL_MASK 0x44UL @@ -95,13 +94,6 @@ do { \ ADF_RING_BUNDLE_SIZE * (bank) + \ ADF_RING_CSR_RING_SRV_ARB_EN, (value)) -/* Default ring mapping */ -#define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP \ - (ASYM << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \ - SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ - ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ - SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) - /* WDT timers * * Timeout is in cycles. Clock speed may vary across products but this @@ -114,15 +106,6 @@ do { \ #define ADF_SSMWDTPKEL_OFFSET 0x58 #define ADF_SSMWDTPKEH_OFFSET 0x60 -/* Ring reset */ -#define ADF_RPRESET_POLL_TIMEOUT_US (5 * USEC_PER_SEC) -#define ADF_RPRESET_POLL_DELAY_US 20 -#define ADF_WQM_CSR_RPRESETCTL_RESET BIT(0) -#define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3)) -#define ADF_WQM_CSR_RPRESETSTS_STATUS BIT(0) -#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4) - void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); void adf_gen4_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops); -int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number); #endif diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c index 2edc63c6b6..e3749e5817 100644 --- a/drivers/crypto/qat/qat_common/adf_init.c +++ b/drivers/crypto/qat/qat_common/adf_init.c @@ -69,8 +69,7 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) return -EFAULT; } - if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) && - !accel_dev->is_vf) { + if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) { dev_err(&GET_DEV(accel_dev), "Device not configured\n"); return -EFAULT; } @@ -118,16 +117,10 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) hw_data->enable_ints(accel_dev); hw_data->enable_error_correction(accel_dev); - ret = hw_data->pfvf_ops.enable_comms(accel_dev); + ret = hw_data->enable_pfvf_comms(accel_dev); if (ret) return ret; - if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) && - accel_dev->is_vf) { - if (qat_crypto_vf_dev_config(accel_dev)) - return -EFAULT; - } - /* * Subservice initialisation is divided into two stages: init and start. * This is to facilitate any ordering dependencies between services diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c index 4ca482aa69..c678d5c531 100644 --- a/drivers/crypto/qat/qat_common/adf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_isr.c @@ -16,31 +16,46 @@ #include "adf_transport_internal.h" #define ADF_MAX_NUM_VFS 32 +#define ADF_ERRSOU3 (0x3A000 + 0x0C) +#define ADF_ERRSOU5 (0x3A000 + 0xD8) +#define ADF_ERRMSK3 (0x3A000 + 0x1C) +#define ADF_ERRMSK5 (0x3A000 + 0xDC) +#define ADF_ERR_REG_VF2PF_L(vf_src) (((vf_src) & 0x01FFFE00) >> 9) +#define ADF_ERR_REG_VF2PF_U(vf_src) (((vf_src) & 0x0000FFFF) << 16) static int adf_enable_msix(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - u32 msix_num_entries = hw_data->num_banks + 1; - int ret; + u32 msix_num_entries = 1; if (hw_data->set_msix_rttable) hw_data->set_msix_rttable(accel_dev); - ret = pci_alloc_irq_vectors(pci_dev_info->pci_dev, msix_num_entries, - msix_num_entries, PCI_IRQ_MSIX); - if (unlikely(ret < 0)) { - dev_err(&GET_DEV(accel_dev), - "Failed to allocate %d MSI-X vectors\n", - msix_num_entries); - return ret; + /* If SR-IOV is disabled, add entries for each bank */ + if (!accel_dev->pf.vf_info) { + int i; + + msix_num_entries += hw_data->num_banks; + for (i = 0; i < msix_num_entries; i++) + pci_dev_info->msix_entries.entries[i].entry = i; + } else { + pci_dev_info->msix_entries.entries[0].entry = + hw_data->num_banks; + } + + if (pci_enable_msix_exact(pci_dev_info->pci_dev, + pci_dev_info->msix_entries.entries, + msix_num_entries)) { + dev_err(&GET_DEV(accel_dev), "Failed to enable MSI-X IRQ(s)\n"); + return -EFAULT; } return 0; } static void adf_disable_msix(struct adf_accel_pci *pci_dev_info) { - pci_free_irq_vectors(pci_dev_info->pci_dev); + pci_disable_msix(pci_dev_info->pci_dev); } static irqreturn_t adf_msix_isr_bundle(int irq, void *bank_ptr) @@ -54,83 +69,64 @@ static irqreturn_t adf_msix_isr_bundle(int irq, void *bank_ptr) return IRQ_HANDLED; } -#ifdef CONFIG_PCI_IOV -void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask) -{ - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); - unsigned long flags; - - spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags); - GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask); - spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags); -} - -void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask) -{ - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); - unsigned long flags; - - spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags); - GET_PFVF_OPS(accel_dev)->disable_vf2pf_interrupts(pmisc_addr, vf_mask); - spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags); -} - -static void adf_disable_vf2pf_interrupts_irq(struct adf_accel_dev *accel_dev, - u32 vf_mask) -{ - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); - - spin_lock(&accel_dev->pf.vf2pf_ints_lock); - GET_PFVF_OPS(accel_dev)->disable_vf2pf_interrupts(pmisc_addr, vf_mask); - spin_unlock(&accel_dev->pf.vf2pf_ints_lock); -} - -static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev) -{ - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); - bool irq_handled = false; - unsigned long vf_mask; - - /* Get the interrupt sources triggered by VFs */ - vf_mask = GET_PFVF_OPS(accel_dev)->get_vf2pf_sources(pmisc_addr); - - if (vf_mask) { - struct adf_accel_vf_info *vf_info; - int i; - - /* Disable VF2PF interrupts for VFs with pending ints */ - adf_disable_vf2pf_interrupts_irq(accel_dev, vf_mask); - - /* - * Handle VF2PF interrupt unless the VF is malicious and - * is attempting to flood the host OS with VF2PF interrupts. - */ - for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) { - vf_info = accel_dev->pf.vf_info + i; - - if (!__ratelimit(&vf_info->vf2pf_ratelimit)) { - dev_info(&GET_DEV(accel_dev), - "Too many ints from VF%d\n", - vf_info->vf_nr); - continue; - } - - adf_schedule_vf2pf_handler(vf_info); - irq_handled = true; - } - } - return irq_handled; -} -#endif /* CONFIG_PCI_IOV */ - static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr) { struct adf_accel_dev *accel_dev = dev_ptr; #ifdef CONFIG_PCI_IOV /* If SR-IOV is enabled (vf_info is non-NULL), check for VF->PF ints */ - if (accel_dev->pf.vf_info && adf_handle_vf2pf_int(accel_dev)) - return IRQ_HANDLED; + if (accel_dev->pf.vf_info) { + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + struct adf_bar *pmisc = + &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + void __iomem *pmisc_addr = pmisc->virt_addr; + u32 errsou3, errsou5, errmsk3, errmsk5; + unsigned long vf_mask; + + /* Get the interrupt sources triggered by VFs */ + errsou3 = ADF_CSR_RD(pmisc_addr, ADF_ERRSOU3); + errsou5 = ADF_CSR_RD(pmisc_addr, ADF_ERRSOU5); + vf_mask = ADF_ERR_REG_VF2PF_L(errsou3); + vf_mask |= ADF_ERR_REG_VF2PF_U(errsou5); + + /* To avoid adding duplicate entries to work queue, clear + * vf_int_mask_sets bits that are already masked in ERRMSK register. + */ + errmsk3 = ADF_CSR_RD(pmisc_addr, ADF_ERRMSK3); + errmsk5 = ADF_CSR_RD(pmisc_addr, ADF_ERRMSK5); + vf_mask &= ~ADF_ERR_REG_VF2PF_L(errmsk3); + vf_mask &= ~ADF_ERR_REG_VF2PF_U(errmsk5); + + if (vf_mask) { + struct adf_accel_vf_info *vf_info; + bool irq_handled = false; + int i; + + /* Disable VF2PF interrupts for VFs with pending ints */ + adf_disable_vf2pf_interrupts_irq(accel_dev, vf_mask); + + /* + * Handle VF2PF interrupt unless the VF is malicious and + * is attempting to flood the host OS with VF2PF interrupts. + */ + for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) { + vf_info = accel_dev->pf.vf_info + i; + + if (!__ratelimit(&vf_info->vf2pf_ratelimit)) { + dev_info(&GET_DEV(accel_dev), + "Too many ints from VF%d\n", + vf_info->vf_nr + 1); + continue; + } + + adf_schedule_vf2pf_handler(vf_info); + irq_handled = true; + } + + if (irq_handled) + return IRQ_HANDLED; + } + } #endif /* CONFIG_PCI_IOV */ dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n", @@ -139,39 +135,13 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr) return IRQ_NONE; } -static void adf_free_irqs(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct adf_irq *irqs = pci_dev_info->msix_entries.irqs; - struct adf_etr_data *etr_data = accel_dev->transport; - int clust_irq = hw_data->num_banks; - int irq, i = 0; - - if (pci_dev_info->msix_entries.num_entries > 1) { - for (i = 0; i < hw_data->num_banks; i++) { - if (irqs[i].enabled) { - irq = pci_irq_vector(pci_dev_info->pci_dev, i); - irq_set_affinity_hint(irq, NULL); - free_irq(irq, &etr_data->banks[i]); - } - } - } - - if (irqs[i].enabled) { - irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq); - free_irq(irq, accel_dev); - } -} - static int adf_request_irqs(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct adf_irq *irqs = pci_dev_info->msix_entries.irqs; + struct msix_entry *msixe = pci_dev_info->msix_entries.entries; struct adf_etr_data *etr_data = accel_dev->transport; - int clust_irq = hw_data->num_banks; - int ret, irq, i = 0; + int ret, i = 0; char *name; /* Request msix irq for all banks unless SR-IOV enabled */ @@ -180,82 +150,105 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev) struct adf_etr_bank_data *bank = &etr_data->banks[i]; unsigned int cpu, cpus = num_online_cpus(); - name = irqs[i].name; + name = *(pci_dev_info->msix_entries.names + i); snprintf(name, ADF_MAX_MSIX_VECTOR_NAME, "qat%d-bundle%d", accel_dev->accel_id, i); - irq = pci_irq_vector(pci_dev_info->pci_dev, i); - if (unlikely(irq < 0)) { - dev_err(&GET_DEV(accel_dev), - "Failed to get IRQ number of device vector %d - %s\n", - i, name); - ret = irq; - goto err; - } - ret = request_irq(irq, adf_msix_isr_bundle, 0, - &name[0], bank); + ret = request_irq(msixe[i].vector, + adf_msix_isr_bundle, 0, name, bank); if (ret) { dev_err(&GET_DEV(accel_dev), - "Failed to allocate IRQ %d for %s\n", - irq, name); - goto err; + "failed to enable irq %d for %s\n", + msixe[i].vector, name); + return ret; } cpu = ((accel_dev->accel_id * hw_data->num_banks) + i) % cpus; - irq_set_affinity_hint(irq, get_cpu_mask(cpu)); - irqs[i].enabled = true; + irq_set_affinity_hint(msixe[i].vector, + get_cpu_mask(cpu)); } } /* Request msix irq for AE */ - name = irqs[i].name; + name = *(pci_dev_info->msix_entries.names + i); snprintf(name, ADF_MAX_MSIX_VECTOR_NAME, "qat%d-ae-cluster", accel_dev->accel_id); - irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq); - if (unlikely(irq < 0)) { - dev_err(&GET_DEV(accel_dev), - "Failed to get IRQ number of device vector %d - %s\n", - i, name); - ret = irq; - goto err; - } - ret = request_irq(irq, adf_msix_isr_ae, 0, &name[0], accel_dev); + ret = request_irq(msixe[i].vector, adf_msix_isr_ae, 0, name, accel_dev); if (ret) { dev_err(&GET_DEV(accel_dev), - "Failed to allocate IRQ %d for %s\n", irq, name); - goto err; + "failed to enable irq %d, for %s\n", + msixe[i].vector, name); + return ret; } - irqs[i].enabled = true; - return ret; -err: - adf_free_irqs(accel_dev); return ret; } -static int adf_isr_alloc_msix_vectors_data(struct adf_accel_dev *accel_dev) +static void adf_free_irqs(struct adf_accel_dev *accel_dev) { + struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + struct msix_entry *msixe = pci_dev_info->msix_entries.entries; + struct adf_etr_data *etr_data = accel_dev->transport; + int i = 0; + + if (pci_dev_info->msix_entries.num_entries > 1) { + for (i = 0; i < hw_data->num_banks; i++) { + irq_set_affinity_hint(msixe[i].vector, NULL); + free_irq(msixe[i].vector, &etr_data->banks[i]); + } + } + irq_set_affinity_hint(msixe[i].vector, NULL); + free_irq(msixe[i].vector, accel_dev); +} + +static int adf_isr_alloc_msix_entry_table(struct adf_accel_dev *accel_dev) +{ + int i; + char **names; + struct msix_entry *entries; struct adf_hw_device_data *hw_data = accel_dev->hw_device; u32 msix_num_entries = 1; - struct adf_irq *irqs; /* If SR-IOV is disabled (vf_info is NULL), add entries for each bank */ if (!accel_dev->pf.vf_info) msix_num_entries += hw_data->num_banks; - irqs = kzalloc_node(msix_num_entries * sizeof(*irqs), - GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev))); - if (!irqs) + entries = kcalloc_node(msix_num_entries, sizeof(*entries), + GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev))); + if (!entries) return -ENOMEM; + names = kcalloc(msix_num_entries, sizeof(char *), GFP_KERNEL); + if (!names) { + kfree(entries); + return -ENOMEM; + } + for (i = 0; i < msix_num_entries; i++) { + *(names + i) = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL); + if (!(*(names + i))) + goto err; + } accel_dev->accel_pci_dev.msix_entries.num_entries = msix_num_entries; - accel_dev->accel_pci_dev.msix_entries.irqs = irqs; + accel_dev->accel_pci_dev.msix_entries.entries = entries; + accel_dev->accel_pci_dev.msix_entries.names = names; return 0; +err: + for (i = 0; i < msix_num_entries; i++) + kfree(*(names + i)); + kfree(entries); + kfree(names); + return -ENOMEM; } -static void adf_isr_free_msix_vectors_data(struct adf_accel_dev *accel_dev) +static void adf_isr_free_msix_entry_table(struct adf_accel_dev *accel_dev) { - kfree(accel_dev->accel_pci_dev.msix_entries.irqs); - accel_dev->accel_pci_dev.msix_entries.irqs = NULL; + char **names = accel_dev->accel_pci_dev.msix_entries.names; + int i; + + kfree(accel_dev->accel_pci_dev.msix_entries.entries); + for (i = 0; i < accel_dev->accel_pci_dev.msix_entries.num_entries; i++) + kfree(*(names + i)); + kfree(names); } static int adf_setup_bh(struct adf_accel_dev *accel_dev) @@ -294,7 +287,7 @@ void adf_isr_resource_free(struct adf_accel_dev *accel_dev) adf_free_irqs(accel_dev); adf_cleanup_bh(accel_dev); adf_disable_msix(&accel_dev->accel_pci_dev); - adf_isr_free_msix_vectors_data(accel_dev); + adf_isr_free_msix_entry_table(accel_dev); } EXPORT_SYMBOL_GPL(adf_isr_resource_free); @@ -310,7 +303,7 @@ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev) { int ret; - ret = adf_isr_alloc_msix_vectors_data(accel_dev); + ret = adf_isr_alloc_msix_entry_table(accel_dev); if (ret) goto err_out; @@ -335,7 +328,7 @@ int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev) adf_disable_msix(&accel_dev->accel_pci_dev); err_free_msix_table: - adf_isr_free_msix_vectors_data(accel_dev); + adf_isr_free_msix_entry_table(accel_dev); err_out: return ret; diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c index 976b9ab761..7ec81989be 100644 --- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -117,37 +117,19 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) mutex_lock(lock); - /* Check if PF2VF CSR is in use by remote function */ + /* Check if the PFVF CSR is in use by remote function */ val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); if ((val & remote_in_use_mask) == remote_in_use_pattern) { dev_dbg(&GET_DEV(accel_dev), - "PF2VF CSR in use by remote function\n"); + "PFVF CSR in use by remote function\n"); ret = -EBUSY; goto out; } - /* Attempt to get ownership of PF2VF CSR */ msg &= ~local_in_use_mask; msg |= local_in_use_pattern; - ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg); - /* Wait in case remote func also attempting to get ownership */ - msleep(ADF_IOV_MSG_COLLISION_DETECT_DELAY); - - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - if ((val & local_in_use_mask) != local_in_use_pattern) { - dev_dbg(&GET_DEV(accel_dev), - "PF2VF CSR in use by remote - collision detected\n"); - ret = -EBUSY; - goto out; - } - - /* - * This function now owns the PV2VF CSR. The IN_USE_BY pattern must - * remain in the PF2VF CSR for all writes including ACK from remote - * until this local function relinquishes the CSR. Send the message - * by interrupting the remote. - */ + /* Attempt to get ownership of the PFVF CSR */ ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg | int_bit); /* Wait for confirmation from remote func it received the message */ @@ -162,7 +144,14 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) ret = -EIO; } - /* Finished with PF2VF CSR; relinquish it and leave msg in CSR */ + if (val != msg) { + dev_dbg(&GET_DEV(accel_dev), + "Collision - PFVF CSR overwritten by remote function\n"); + ret = -EIO; + goto out; + } + + /* Finished with the PFVF CSR; relinquish it and leave msg in CSR */ ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, val & ~local_in_use_mask); out: mutex_unlock(lock); @@ -170,12 +159,13 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) } /** - * adf_iov_putmsg() - send PF2VF message + * adf_iov_putmsg() - send PFVF message * @accel_dev: Pointer to acceleration device. * @msg: Message to send - * @vf_nr: VF number to which the message will be sent + * @vf_nr: VF number to which the message will be sent if on PF, ignored + * otherwise * - * Function sends a message from the PF to a VF + * Function sends a message through the PFVF channel * * Return: 0 on success, error code otherwise. */ @@ -204,6 +194,11 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) /* Read message from the VF */ msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); + if (!(msg & ADF_VF2PF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious VF2PF interrupt, msg %X. Ignored\n", msg); + goto out; + } /* To ACK, clear the VF2PFINT bit */ msg &= ~ADF_VF2PF_INT; @@ -287,6 +282,7 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n"); +out: /* re-enable interrupt on PF from this VF */ adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr)); diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c index b960bca1f9..90ec057f91 100644 --- a/drivers/crypto/qat/qat_common/adf_sriov.c +++ b/drivers/crypto/qat/qat_common/adf_sriov.c @@ -1,15 +1,12 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2015 - 2021 Intel Corporation */ +/* Copyright(c) 2015 - 2020 Intel Corporation */ #include #include #include #include #include "adf_common_drv.h" #include "adf_cfg.h" -#include "adf_pfvf_pf_msg.h" - -#define ADF_VF2PF_RATELIMIT_INTERVAL 8 -#define ADF_VF2PF_RATELIMIT_BURST 130 +#include "adf_pf2vf_msg.h" static struct workqueue_struct *pf2vf_resp_wq; @@ -22,16 +19,8 @@ static void adf_iov_send_resp(struct work_struct *work) { struct adf_pf2vf_resp *pf2vf_resp = container_of(work, struct adf_pf2vf_resp, pf2vf_resp_work); - struct adf_accel_vf_info *vf_info = pf2vf_resp->vf_info; - struct adf_accel_dev *accel_dev = vf_info->accel_dev; - u32 vf_nr = vf_info->vf_nr; - bool ret; - - ret = adf_recv_and_handle_vf2pf_msg(accel_dev, vf_nr); - if (ret) - /* re-enable interrupt on PF from this VF */ - adf_enable_vf2pf_interrupts(accel_dev, 1 << vf_nr); + adf_vf2pf_req_hndl(pf2vf_resp->vf_info); kfree(pf2vf_resp); } @@ -61,12 +50,11 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev) /* This ptr will be populated when VFs will be created */ vf_info->accel_dev = accel_dev; vf_info->vf_nr = i; - vf_info->vf_compat_ver = 0; mutex_init(&vf_info->pf2vf_lock); ratelimit_state_init(&vf_info->vf2pf_ratelimit, - ADF_VF2PF_RATELIMIT_INTERVAL, - ADF_VF2PF_RATELIMIT_BURST); + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); } /* Set Valid bits in AE Thread to PCIe Function Mapping */ @@ -74,7 +62,7 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev) hw_data->configure_iov_threads(accel_dev, true); /* Enable VF to PF interrupts for all VFs */ - if (hw_data->pfvf_ops.get_pf2vf_offset) + if (hw_data->get_pf2vf_offset) adf_enable_vf2pf_interrupts(accel_dev, BIT_ULL(totalvfs) - 1); /* @@ -104,13 +92,13 @@ void adf_disable_sriov(struct adf_accel_dev *accel_dev) if (!accel_dev->pf.vf_info) return; - if (hw_data->pfvf_ops.get_pf2vf_offset) + if (hw_data->get_pf2vf_offset) adf_pf2vf_notify_restarting(accel_dev); pci_disable_sriov(accel_to_pci_dev(accel_dev)); /* Disable VF to PF interrupts */ - if (hw_data->pfvf_ops.get_pf2vf_offset) + if (hw_data->get_pf2vf_offset) adf_disable_vf2pf_interrupts(accel_dev, GENMASK(31, 0)); /* Clear Valid bits in AE Thread to PCIe Function Mapping */ @@ -126,32 +114,6 @@ void adf_disable_sriov(struct adf_accel_dev *accel_dev) } EXPORT_SYMBOL_GPL(adf_disable_sriov); -static int adf_sriov_prepare_restart(struct adf_accel_dev *accel_dev) -{ - char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; - int ret; - - ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, - ADF_SERVICES_ENABLED, services); - - adf_dev_stop(accel_dev); - adf_dev_shutdown(accel_dev); - - if (!ret) { - ret = adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC); - if (ret) - return ret; - - ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, - ADF_SERVICES_ENABLED, - services, ADF_STR); - if (ret) - return ret; - } - - return 0; -} - /** * adf_sriov_configure() - Enable SRIOV for the device * @pdev: Pointer to PCI device. @@ -191,9 +153,8 @@ int adf_sriov_configure(struct pci_dev *pdev, int numvfs) return -EBUSY; } - ret = adf_sriov_prepare_restart(accel_dev); - if (ret) - return ret; + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); } if (adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC)) diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c index 86c3bd0c9c..2e300c255a 100644 --- a/drivers/crypto/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c @@ -15,6 +15,7 @@ #include "adf_cfg_common.h" #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" +#include "adf_pf2vf_msg.h" #define ADF_VINTSOU_OFFSET 0x204 #define ADF_VINTMSK_OFFSET 0x208 @@ -30,38 +31,49 @@ struct adf_vf_stop_data { void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) { - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + void __iomem *pmisc_bar_addr = + pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - ADF_CSR_WR(pmisc_addr, ADF_VINTMSK_OFFSET, 0x0); + ADF_CSR_WR(pmisc_bar_addr, ADF_VINTMSK_OFFSET, 0x0); } void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev) { - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + void __iomem *pmisc_bar_addr = + pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - ADF_CSR_WR(pmisc_addr, ADF_VINTMSK_OFFSET, 0x2); + ADF_CSR_WR(pmisc_bar_addr, ADF_VINTMSK_OFFSET, 0x2); } EXPORT_SYMBOL_GPL(adf_disable_pf2vf_interrupts); static int adf_enable_msi(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; - int stat = pci_alloc_irq_vectors(pci_dev_info->pci_dev, 1, 1, - PCI_IRQ_MSI); - if (unlikely(stat < 0)) { + int stat = pci_enable_msi(pci_dev_info->pci_dev); + + if (stat) { dev_err(&GET_DEV(accel_dev), - "Failed to enable MSI interrupt: %d\n", stat); + "Failed to enable MSI interrupts\n"); return stat; } - return 0; + accel_dev->vf.irq_name = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL); + if (!accel_dev->vf.irq_name) + return -ENOMEM; + + return stat; } static void adf_disable_msi(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); - pci_free_irq_vectors(pdev); + kfree(accel_dev->vf.irq_name); + pci_disable_msi(pdev); } static void adf_dev_stop_async(struct work_struct *work) @@ -78,37 +90,78 @@ static void adf_dev_stop_async(struct work_struct *work) kfree(stop_data); } -int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev) -{ - struct adf_vf_stop_data *stop_data; - - clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); - if (!stop_data) { - dev_err(&GET_DEV(accel_dev), - "Couldn't schedule stop for vf_%d\n", - accel_dev->accel_id); - return -ENOMEM; - } - stop_data->accel_dev = accel_dev; - INIT_WORK(&stop_data->work, adf_dev_stop_async); - queue_work(adf_vf_stop_wq, &stop_data->work); - - return 0; -} - static void adf_pf2vf_bh_handler(void *data) { struct adf_accel_dev *accel_dev = data; - bool ret; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + struct adf_bar *pmisc = + &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + void __iomem *pmisc_bar_addr = pmisc->virt_addr; + u32 msg; - ret = adf_recv_and_handle_pf2vf_msg(accel_dev); - if (ret) - /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); + /* Read the message from PF */ + msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); + if (!(msg & ADF_PF2VF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious PF2VF interrupt, msg %X. Ignored\n", msg); + goto out; + } + if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) + /* Ignore legacy non-system (non-kernel) PF2VF messages */ + goto err; + + switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) { + case ADF_PF2VF_MSGTYPE_RESTARTING: { + struct adf_vf_stop_data *stop_data; + + dev_dbg(&GET_DEV(accel_dev), + "Restarting msg received from PF 0x%x\n", msg); + + clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + + stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); + if (!stop_data) { + dev_err(&GET_DEV(accel_dev), + "Couldn't schedule stop for vf_%d\n", + accel_dev->accel_id); + return; + } + stop_data->accel_dev = accel_dev; + INIT_WORK(&stop_data->work, adf_dev_stop_async); + queue_work(adf_vf_stop_wq, &stop_data->work); + /* To ack, clear the PF2VFINT bit */ + msg &= ~ADF_PF2VF_INT; + ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); + return; + } + case ADF_PF2VF_MSGTYPE_VERSION_RESP: + dev_dbg(&GET_DEV(accel_dev), + "Version resp received from PF 0x%x\n", msg); + accel_dev->vf.pf_version = + (msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >> + ADF_PF2VF_VERSION_RESP_VERS_SHIFT; + accel_dev->vf.compatible = + (msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >> + ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; + complete(&accel_dev->vf.iov_msg_completion); + break; + default: + goto err; + } + + /* To ack, clear the PF2VFINT bit */ + msg &= ~ADF_PF2VF_INT; + ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); + +out: + /* Re-enable PF2VF interrupts */ + adf_enable_pf2vf_interrupts(accel_dev); return; - +err: + dev_err(&GET_DEV(accel_dev), + "Unknown message from PF (0x%x); leaving PF2VF ints disabled\n", + msg); } static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev) @@ -193,7 +246,6 @@ static int adf_request_msi_irq(struct adf_accel_dev *accel_dev) } cpu = accel_dev->accel_id % num_online_cpus(); irq_set_affinity_hint(pdev->irq, get_cpu_mask(cpu)); - accel_dev->vf.irq_enabled = true; return ret; } @@ -225,10 +277,8 @@ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); - if (accel_dev->vf.irq_enabled) { - irq_set_affinity_hint(pdev->irq, NULL); - free_irq(pdev->irq, accel_dev); - } + irq_set_affinity_hint(pdev->irq, NULL); + free_irq(pdev->irq, (void *)accel_dev); adf_cleanup_bh(accel_dev); adf_cleanup_pf2vf_bh(accel_dev); adf_disable_msi(accel_dev); diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h index afe59a7684..f05ad17fbd 100644 --- a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h +++ b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h @@ -14,8 +14,7 @@ enum icp_qat_fw_init_admin_cmd_id { ICP_QAT_FW_COUNTERS_GET = 5, ICP_QAT_FW_LOOPBACK = 6, ICP_QAT_FW_HEARTBEAT_SYNC = 7, - ICP_QAT_FW_HEARTBEAT_GET = 8, - ICP_QAT_FW_COMP_CAPABILITY_GET = 9, + ICP_QAT_FW_HEARTBEAT_GET = 8 }; enum icp_qat_fw_init_admin_resp_status { @@ -53,7 +52,6 @@ struct icp_qat_fw_init_admin_resp { __u16 version_minor_num; __u16 version_major_num; }; - __u32 extended_features; }; __u64 opaque_data; union { diff --git a/drivers/crypto/qat/qat_common/icp_qat_hw.h b/drivers/crypto/qat/qat_common/icp_qat_hw.h index 433304cad2..e39e8a2d51 100644 --- a/drivers/crypto/qat/qat_common/icp_qat_hw.h +++ b/drivers/crypto/qat/qat_common/icp_qat_hw.h @@ -91,18 +91,7 @@ enum icp_qat_capabilities_mask { ICP_ACCEL_CAPABILITIES_RAND = BIT(7), ICP_ACCEL_CAPABILITIES_ZUC = BIT(8), ICP_ACCEL_CAPABILITIES_SHA3 = BIT(9), - /* Bits 10-11 are currently reserved */ - ICP_ACCEL_CAPABILITIES_HKDF = BIT(12), - ICP_ACCEL_CAPABILITIES_ECEDMONT = BIT(13), - /* Bit 14 is currently reserved */ - ICP_ACCEL_CAPABILITIES_SHA3_EXT = BIT(15), - ICP_ACCEL_CAPABILITIES_AESGCM_SPC = BIT(16), - ICP_ACCEL_CAPABILITIES_CHACHA_POLY = BIT(17), - /* Bits 18-21 are currently reserved */ - ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY = BIT(22), - ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64 = BIT(23), - ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION = BIT(24), - ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION = BIT(25), + /* Bits 10-25 are currently reserved */ ICP_ACCEL_CAPABILITIES_AES_V2 = BIT(26) }; diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c index 7234c4940f..ece6776fbd 100644 --- a/drivers/crypto/qat/qat_common/qat_crypto.c +++ b/drivers/crypto/qat/qat_common/qat_crypto.c @@ -8,7 +8,6 @@ #include "adf_transport_access_macros.h" #include "adf_cfg.h" #include "adf_cfg_strings.h" -#include "adf_gen2_hw_data.h" #include "qat_crypto.h" #include "icp_qat_fw.h" @@ -105,30 +104,6 @@ struct qat_crypto_instance *qat_crypto_get_instance_node(int node) return inst; } -/** - * qat_crypto_vf_dev_config() - * create dev config required to create crypto inst. - * - * @accel_dev: Pointer to acceleration device. - * - * Function creates device configuration required to create - * asym, sym or, crypto instances - * - * Return: 0 on success, error code otherwise. - */ -int qat_crypto_vf_dev_config(struct adf_accel_dev *accel_dev) -{ - u16 ring_to_svc_map = GET_HW_DATA(accel_dev)->ring_to_svc_map; - - if (ring_to_svc_map != ADF_GEN2_DEFAULT_RING_TO_SRV_MAP) { - dev_err(&GET_DEV(accel_dev), - "Unsupported ring/service mapping present on PF"); - return -EFAULT; - } - - return qat_crypto_dev_config(accel_dev); -} - /** * qat_crypto_dev_config() - create dev config required to create crypto inst. * diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c index 4bfd8f3566..12ca6b8764 100644 --- a/drivers/crypto/qat/qat_common/qat_hal.c +++ b/drivers/crypto/qat/qat_common/qat_hal.c @@ -684,7 +684,8 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle, { struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_bar *misc_bar = + &pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)]; unsigned int max_en_ae_id = 0; struct adf_bar *sram_bar; unsigned int csr_val = 0; @@ -714,12 +715,18 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle, handle->chip_info->fcu_loaded_ae_csr = FCU_AE_LOADED_4XXX; handle->chip_info->fcu_loaded_ae_pos = 0; - handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET_4XXX; - handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET_4XXX; - handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET_4XXX; + handle->hal_cap_g_ctl_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_CAP_OFFSET_4XXX); + handle->hal_cap_ae_xfer_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_AE_OFFSET_4XXX); + handle->hal_ep_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_EP_OFFSET_4XXX); handle->hal_cap_ae_local_csr_addr_v = (void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v - + LOCAL_TO_XFER_REG_OFFSET); + + LOCAL_TO_XFER_REG_OFFSET); break; case PCI_DEVICE_ID_INTEL_QAT_C62X: case PCI_DEVICE_ID_INTEL_QAT_C3XXX: @@ -742,9 +749,15 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle, handle->chip_info->fcu_dram_addr_lo = FCU_DRAM_ADDR_LO; handle->chip_info->fcu_loaded_ae_csr = FCU_STATUS; handle->chip_info->fcu_loaded_ae_pos = FCU_LOADED_AE_POS; - handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET; - handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET; - handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET; + handle->hal_cap_g_ctl_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_CAP_OFFSET); + handle->hal_cap_ae_xfer_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_AE_OFFSET); + handle->hal_ep_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_EP_OFFSET); handle->hal_cap_ae_local_csr_addr_v = (void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v + LOCAL_TO_XFER_REG_OFFSET); @@ -769,9 +782,15 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle, handle->chip_info->fcu_dram_addr_lo = 0; handle->chip_info->fcu_loaded_ae_csr = 0; handle->chip_info->fcu_loaded_ae_pos = 0; - handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET; - handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET; - handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET; + handle->hal_cap_g_ctl_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_CAP_OFFSET); + handle->hal_cap_ae_xfer_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_AE_OFFSET); + handle->hal_ep_csr_addr_v = + (void __iomem *)((uintptr_t)misc_bar->virt_addr + + ICP_QAT_EP_OFFSET); handle->hal_cap_ae_local_csr_addr_v = (void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v + LOCAL_TO_XFER_REG_OFFSET); diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c index 09599fe4d2..0a9ce365a5 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2014 - 2021 Intel Corporation */ +/* Copyright(c) 2014 - 2020 Intel Corporation */ #include +#include #include #include -#include #include "adf_dh895xcc_hw_data.h" #include "icp_qat_hw.h" @@ -35,6 +35,34 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ~fuses & ADF_DH895XCC_ACCELENGINES_MASK; } +static u32 get_num_accels(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->accel_mask) + return 0; + + for (i = 0; i < ADF_DH895XCC_MAX_ACCELERATORS; i++) { + if (self->accel_mask & (1 << i)) + ctr++; + } + return ctr; +} + +static u32 get_num_aes(struct adf_hw_device_data *self) +{ + u32 i, ctr = 0; + + if (!self || !self->ae_mask) + return 0; + + for (i = 0; i < ADF_DH895XCC_MAX_ACCELENGINES; i++) { + if (self->ae_mask & (1 << i)) + ctr++; + } + return ctr; +} + static u32 get_misc_bar_id(struct adf_hw_device_data *self) { return ADF_DH895XCC_PMISC_BAR; @@ -69,8 +97,6 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; - if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) - capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; return capabilities; } @@ -100,6 +126,41 @@ static const u32 *adf_get_arbiter_mapping(void) return thrd_to_arb_map; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_DH895XCC_PF2VF_OFFSET(i); +} + +static void adf_enable_error_correction(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR]; + unsigned long accel_mask = hw_device->accel_mask; + unsigned long ae_mask = hw_device->ae_mask; + void __iomem *csr = misc_bar->virt_addr; + unsigned int val, i; + + /* Enable Accel Engine error detection & correction */ + for_each_set_bit(i, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) { + val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_CTX_ENABLES(i)); + val |= ADF_DH895XCC_ENABLE_AE_ECC_ERR; + ADF_CSR_WR(csr, ADF_DH895XCC_AE_CTX_ENABLES(i), val); + val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_MISC_CONTROL(i)); + val |= ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR; + ADF_CSR_WR(csr, ADF_DH895XCC_AE_MISC_CONTROL(i), val); + } + + /* Enable shared memory error detection & correction */ + for_each_set_bit(i, &accel_mask, ADF_DH895XCC_MAX_ACCELERATORS) { + val = ADF_CSR_RD(csr, ADF_DH895XCC_UERRSSMSH(i)); + val |= ADF_DH895XCC_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_DH895XCC_UERRSSMSH(i), val); + val = ADF_CSR_RD(csr, ADF_DH895XCC_CERRSSMSH(i)); + val |= ADF_DH895XCC_ERRSSMSH_EN; + ADF_CSR_WR(csr, ADF_DH895XCC_CERRSSMSH(i), val); + } +} + static void adf_enable_ints(struct adf_accel_dev *accel_dev) { void __iomem *addr; @@ -114,63 +175,11 @@ static void adf_enable_ints(struct adf_accel_dev *accel_dev) ADF_DH895XCC_SMIA1_MASK); } -static u32 get_vf2pf_sources(void __iomem *pmisc_bar) +static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) { - u32 errsou3, errmsk3, errsou5, errmsk5, vf_int_mask; + spin_lock_init(&accel_dev->pf.vf2pf_ints_lock); - /* Get the interrupt sources triggered by VFs */ - errsou3 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRSOU3); - vf_int_mask = ADF_DH895XCC_ERR_REG_VF2PF_L(errsou3); - - /* To avoid adding duplicate entries to work queue, clear - * vf_int_mask_sets bits that are already masked in ERRMSK register. - */ - errmsk3 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRMSK3); - vf_int_mask &= ~ADF_DH895XCC_ERR_REG_VF2PF_L(errmsk3); - - /* Do the same for ERRSOU5 */ - errsou5 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRSOU5); - errmsk5 = ADF_CSR_RD(pmisc_bar, ADF_GEN2_ERRMSK5); - vf_int_mask |= ADF_DH895XCC_ERR_REG_VF2PF_U(errsou5); - vf_int_mask &= ~ADF_DH895XCC_ERR_REG_VF2PF_U(errmsk5); - - return vf_int_mask; -} - -static void enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask) -{ - /* Enable VF2PF Messaging Ints - VFs 0 through 15 per vf_mask[15:0] */ - if (vf_mask & 0xFFFF) { - u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3) - & ~ADF_DH895XCC_ERR_MSK_VF2PF_L(vf_mask); - ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val); - } - - /* Enable VF2PF Messaging Ints - VFs 16 through 31 per vf_mask[31:16] */ - if (vf_mask >> 16) { - u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5) - & ~ADF_DH895XCC_ERR_MSK_VF2PF_U(vf_mask); - - ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, val); - } -} - -static void disable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask) -{ - /* Disable VF2PF interrupts for VFs 0 through 15 per vf_mask[15:0] */ - if (vf_mask & 0xFFFF) { - u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK3) - | ADF_DH895XCC_ERR_MSK_VF2PF_L(vf_mask); - ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, val); - } - - /* Disable VF2PF interrupts for VFs 16 through 31 per vf_mask[31:16] */ - if (vf_mask >> 16) { - u32 val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_ERRMSK5) - | ADF_DH895XCC_ERR_MSK_VF2PF_U(vf_mask); - - ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, val); - } + return 0; } static void configure_iov_threads(struct adf_accel_dev *accel_dev, bool enable) @@ -189,17 +198,16 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS; hw_data->num_logical_accel = 1; hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES; - hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET; - hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; + hw_data->tx_rx_gap = ADF_DH895XCC_RX_RINGS_OFFSET; + hw_data->tx_rings_mask = ADF_DH895XCC_TX_RINGS_MASK; hw_data->alloc_irq = adf_isr_resource_alloc; hw_data->free_irq = adf_isr_resource_free; - hw_data->enable_error_correction = adf_gen2_enable_error_correction; + hw_data->enable_error_correction = adf_enable_error_correction; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; - hw_data->get_num_aes = adf_gen2_get_num_aes; + hw_data->get_num_accels = get_num_accels; + hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; hw_data->get_admin_info = adf_gen2_get_admin_info; @@ -217,12 +225,11 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->get_arb_mapping = adf_get_arbiter_mapping; hw_data->enable_ints = adf_enable_ints; hw_data->reset_device = adf_reset_sbr; + hw_data->get_pf2vf_offset = get_pf2vf_offset; + hw_data->enable_pfvf_comms = adf_enable_pf2vf_comms; hw_data->disable_iov = adf_disable_sriov; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; - adf_gen2_init_pf_pfvf_ops(&hw_data->pfvf_ops); - hw_data->pfvf_ops.get_vf2pf_sources = get_vf2pf_sources; - hw_data->pfvf_ops.enable_vf2pf_interrupts = enable_vf2pf_interrupts; - hw_data->pfvf_ops.disable_vf2pf_interrupts = disable_vf2pf_interrupts; adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h index aa17272a15..f99319cd45 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h +++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.h @@ -7,6 +7,8 @@ #define ADF_DH895XCC_SRAM_BAR 0 #define ADF_DH895XCC_PMISC_BAR 1 #define ADF_DH895XCC_ETR_BAR 2 +#define ADF_DH895XCC_RX_RINGS_OFFSET 8 +#define ADF_DH895XCC_TX_RINGS_MASK 0xFF #define ADF_DH895XCC_FUSECTL_SKU_MASK 0x300000 #define ADF_DH895XCC_FUSECTL_SKU_SHIFT 20 #define ADF_DH895XCC_FUSECTL_SKU_1 0x0 @@ -23,12 +25,16 @@ #define ADF_DH895XCC_SMIAPF1_MASK_OFFSET (0x3A000 + 0x30) #define ADF_DH895XCC_SMIA0_MASK 0xFFFFFFFF #define ADF_DH895XCC_SMIA1_MASK 0x1 +/* Error detection and correction */ +#define ADF_DH895XCC_AE_CTX_ENABLES(i) (i * 0x1000 + 0x20818) +#define ADF_DH895XCC_AE_MISC_CONTROL(i) (i * 0x1000 + 0x20960) +#define ADF_DH895XCC_ENABLE_AE_ECC_ERR BIT(28) +#define ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR (BIT(24) | BIT(12)) +#define ADF_DH895XCC_UERRSSMSH(i) (i * 0x4000 + 0x18) +#define ADF_DH895XCC_CERRSSMSH(i) (i * 0x4000 + 0x10) +#define ADF_DH895XCC_ERRSSMSH_EN BIT(3) -/* Masks for VF2PF interrupts */ -#define ADF_DH895XCC_ERR_REG_VF2PF_L(vf_src) (((vf_src) & 0x01FFFE00) >> 9) -#define ADF_DH895XCC_ERR_MSK_VF2PF_L(vf_mask) (((vf_mask) & 0xFFFF) << 9) -#define ADF_DH895XCC_ERR_REG_VF2PF_U(vf_src) (((vf_src) & 0x0000FFFF) << 16) -#define ADF_DH895XCC_ERR_MSK_VF2PF_U(vf_mask) ((vf_mask) >> 16) +#define ADF_DH895XCC_PF2VF_OFFSET(i) (0x3A000 + 0x280 + ((i) * 0x04)) /* AE to function mapping */ #define ADF_DH895XCC_AE2FUNC_MAP_GRP_A_NUM_REGS 96 diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c index acca56752a..3976a81bd9 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_drv.c +++ b/drivers/crypto/qat/qat_dh895xcc/adf_drv.c @@ -33,7 +33,6 @@ static struct pci_driver adf_driver = { .probe = adf_probe, .remove = adf_remove, .sriov_configure = adf_sriov_configure, - .err_handler = &adf_err_handler, }; static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev) @@ -193,7 +192,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); - adf_enable_aer(accel_dev); + if (adf_enable_aer(accel_dev)) { + dev_err(&pdev->dev, "Failed to enable aer\n"); + ret = -EFAULT; + goto out_err_free_reg; + } if (pci_save_state(pdev)) { dev_err(&pdev->dev, "Failed to save pci state\n"); diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c index 31c14d7e1c..7c6ed6bc8a 100644 --- a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c @@ -1,10 +1,9 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) -/* Copyright(c) 2015 - 2021 Intel Corporation */ +/* Copyright(c) 2015 - 2020 Intel Corporation */ #include +#include #include #include -#include -#include #include "adf_dh895xccvf_hw_data.h" static struct adf_hw_device_class dh895xcciov_class = { @@ -48,6 +47,11 @@ static enum dev_sku_info get_sku(struct adf_hw_device_data *self) return DEV_SKU_VF; } +static u32 get_pf2vf_offset(u32 i) +{ + return ADF_DH895XCCIOV_PF2VF_OFFSET; +} + static int adf_vf_int_noop(struct adf_accel_dev *accel_dev) { return 0; @@ -67,7 +71,6 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) hw_data->num_engines = ADF_DH895XCCIOV_MAX_ACCELENGINES; hw_data->tx_rx_gap = ADF_DH895XCCIOV_RX_RINGS_OFFSET; hw_data->tx_rings_mask = ADF_DH895XCCIOV_TX_RINGS_MASK; - hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP; hw_data->alloc_irq = adf_vf_isr_resource_alloc; hw_data->free_irq = adf_vf_isr_resource_free; hw_data->enable_error_correction = adf_vf_void_noop; @@ -83,11 +86,13 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; + hw_data->get_pf2vf_offset = get_pf2vf_offset; hw_data->get_sku = get_sku; hw_data->enable_ints = adf_vf_void_noop; + hw_data->enable_pfvf_comms = adf_enable_vf2pf_comms; + hw_data->min_iov_compat_ver = ADF_PFVF_COMPAT_THIS_VERSION; hw_data->dev_class->instances++; adf_devmgr_update_class_index(hw_data); - adf_gen2_init_vf_pfvf_ops(&hw_data->pfvf_ops); adf_gen2_init_hw_csr_ops(&hw_data->csr_ops); } diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h index 6973fa967b..306ebb71a4 100644 --- a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h @@ -12,6 +12,7 @@ #define ADF_DH895XCCIOV_TX_RINGS_MASK 0xFF #define ADF_DH895XCCIOV_ETR_BAR 0 #define ADF_DH895XCCIOV_ETR_MAX_BANKS 1 +#define ADF_DH895XCCIOV_PF2VF_OFFSET 0x200 void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data); void adf_clean_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data); diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c index 18756b2e1c..99d90f3ea2 100644 --- a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c @@ -171,7 +171,11 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } pci_set_master(pdev); /* Completion for VF2PF request/response message exchange */ - init_completion(&accel_dev->vf.msg_received); + init_completion(&accel_dev->vf.iov_msg_completion); + + ret = qat_crypto_dev_config(accel_dev); + if (ret) + goto out_err_free_reg; ret = adf_dev_init(accel_dev); if (ret) diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index 51b58e5715..544d7040cf 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c @@ -8,7 +8,6 @@ * Vitaly Andrianov * Tero Kristo */ -#include #include #include #include @@ -647,8 +646,8 @@ static inline void sa_update_cmdl(struct sa_req *req, u32 *cmdl, cmdl[upd_info->enc_offset.index] &= ~SA_CMDL_SOP_BYPASS_LEN_MASK; cmdl[upd_info->enc_offset.index] |= - FIELD_PREP(SA_CMDL_SOP_BYPASS_LEN_MASK, - req->enc_offset); + ((u32)req->enc_offset << + __ffs(SA_CMDL_SOP_BYPASS_LEN_MASK)); if (likely(upd_info->flags & SA_CMDL_UPD_ENC_IV)) { __be32 *data = (__be32 *)&cmdl[upd_info->enc_iv.index]; @@ -667,8 +666,8 @@ static inline void sa_update_cmdl(struct sa_req *req, u32 *cmdl, cmdl[upd_info->auth_offset.index] &= ~SA_CMDL_SOP_BYPASS_LEN_MASK; cmdl[upd_info->auth_offset.index] |= - FIELD_PREP(SA_CMDL_SOP_BYPASS_LEN_MASK, - req->auth_offset); + ((u32)req->auth_offset << + __ffs(SA_CMDL_SOP_BYPASS_LEN_MASK)); if (upd_info->flags & SA_CMDL_UPD_AUTH_IV) { sa_copy_iv((void *)&cmdl[upd_info->auth_iv.index], req->auth_iv, @@ -690,16 +689,16 @@ void sa_set_swinfo(u8 eng_id, u16 sc_id, dma_addr_t sc_phys, u8 hash_size, u32 *swinfo) { swinfo[0] = sc_id; - swinfo[0] |= FIELD_PREP(SA_SW0_FLAGS_MASK, flags); + swinfo[0] |= (flags << __ffs(SA_SW0_FLAGS_MASK)); if (likely(cmdl_present)) - swinfo[0] |= FIELD_PREP(SA_SW0_CMDL_INFO_MASK, - cmdl_offset | SA_SW0_CMDL_PRESENT); - swinfo[0] |= FIELD_PREP(SA_SW0_ENG_ID_MASK, eng_id); + swinfo[0] |= ((cmdl_offset | SA_SW0_CMDL_PRESENT) << + __ffs(SA_SW0_CMDL_INFO_MASK)); + swinfo[0] |= (eng_id << __ffs(SA_SW0_ENG_ID_MASK)); swinfo[0] |= SA_SW0_DEST_INFO_PRESENT; swinfo[1] = (u32)(sc_phys & 0xFFFFFFFFULL); swinfo[2] = (u32)((sc_phys & 0xFFFFFFFF00000000ULL) >> 32); - swinfo[2] |= FIELD_PREP(SA_SW2_EGRESS_LENGTH, hash_size); + swinfo[2] |= (hash_size << __ffs(SA_SW2_EGRESS_LENGTH)); } /* Dump the security context */ @@ -2413,7 +2412,8 @@ static int sa_ul_probe(struct platform_device *pdev) pm_runtime_enable(dev); ret = pm_runtime_resume_and_get(dev); if (ret < 0) { - dev_err(dev, "%s: failed to get sync: %d\n", __func__, ret); + dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__, + ret); pm_runtime_disable(dev); return ret; } @@ -2435,16 +2435,16 @@ static int sa_ul_probe(struct platform_device *pdev) sa_register_algos(dev_data); - ret = of_platform_populate(node, NULL, NULL, dev); + ret = of_platform_populate(node, NULL, NULL, &pdev->dev); if (ret) goto release_dma; - device_for_each_child(dev, dev, sa_link_child); + device_for_each_child(&pdev->dev, &pdev->dev, sa_link_child); return 0; release_dma: - sa_unregister_algos(dev); + sa_unregister_algos(&pdev->dev); dma_release_channel(dev_data->dma_rx2); dma_release_channel(dev_data->dma_rx1); @@ -2453,8 +2453,8 @@ static int sa_ul_probe(struct platform_device *pdev) destroy_dma_pool: dma_pool_destroy(dev_data->sc_pool); - pm_runtime_put_sync(dev); - pm_runtime_disable(dev); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); return ret; } diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c index 59ef541123..81eb136b6c 100644 --- a/drivers/crypto/stm32/stm32-cryp.c +++ b/drivers/crypto/stm32/stm32-cryp.c @@ -232,11 +232,6 @@ static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp) !(status & SR_BUSY), 10, 100000); } -static inline void stm32_cryp_enable(struct stm32_cryp *cryp) -{ - writel_relaxed(readl_relaxed(cryp->regs + CRYP_CR) | CR_CRYPEN, cryp->regs + CRYP_CR); -} - static inline int stm32_cryp_wait_enable(struct stm32_cryp *cryp) { u32 status; @@ -540,6 +535,9 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) /* Disable interrupt */ stm32_cryp_write(cryp, CRYP_IMSCR, 0); + /* Set key */ + stm32_cryp_hw_write_key(cryp); + /* Set configuration */ cfg = CR_DATA8 | CR_FFLUSH; @@ -565,37 +563,24 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) /* AES ECB/CBC decrypt: run key preparation first */ if (is_decrypt(cryp) && ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) { - /* Configure in key preparation mode */ - stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP); + stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN); - /* Set key only after full configuration done */ - stm32_cryp_hw_write_key(cryp); - - /* Start prepare key */ - stm32_cryp_enable(cryp); /* Wait for end of processing */ ret = stm32_cryp_wait_busy(cryp); if (ret) { dev_err(cryp->dev, "Timeout (key preparation)\n"); return ret; } - - cfg |= hw_mode | CR_DEC_NOT_ENC; - - /* Apply updated config (Decrypt + algo) and flush */ - stm32_cryp_write(cryp, CRYP_CR, cfg); - } else { - cfg |= hw_mode; - if (is_decrypt(cryp)) - cfg |= CR_DEC_NOT_ENC; - - /* Apply config and flush */ - stm32_cryp_write(cryp, CRYP_CR, cfg); - - /* Set key only after configuration done */ - stm32_cryp_hw_write_key(cryp); } + cfg |= hw_mode; + + if (is_decrypt(cryp)) + cfg |= CR_DEC_NOT_ENC; + + /* Apply config and flush (valid when CRYPEN = 0) */ + stm32_cryp_write(cryp, CRYP_CR, cfg); + switch (hw_mode) { case CR_AES_GCM: case CR_AES_CCM: @@ -622,7 +607,9 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) } /* Enable now */ - stm32_cryp_enable(cryp); + cfg |= CR_CRYPEN; + + stm32_cryp_write(cryp, CRYP_CR, cfg); return 0; } @@ -1774,8 +1761,7 @@ static int stm32_cryp_probe(struct platform_device *pdev) cryp->clk = devm_clk_get(dev, NULL); if (IS_ERR(cryp->clk)) { - dev_err_probe(dev, PTR_ERR(cryp->clk), "Could not get clock\n"); - + dev_err(dev, "Could not get clock\n"); return PTR_ERR(cryp->clk); } @@ -1793,11 +1779,7 @@ static int stm32_cryp_probe(struct platform_device *pdev) pm_runtime_enable(dev); rst = devm_reset_control_get(dev, NULL); - if (IS_ERR(rst)) { - ret = PTR_ERR(rst); - if (ret == -EPROBE_DEFER) - goto err_rst; - } else { + if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); reset_control_deassert(rst); @@ -1848,7 +1830,7 @@ static int stm32_cryp_probe(struct platform_device *pdev) spin_lock(&cryp_list.lock); list_del(&cryp->list); spin_unlock(&cryp_list.lock); -err_rst: + pm_runtime_disable(dev); pm_runtime_put_noidle(dev); diff --git a/drivers/crypto/ux500/cryp/cryp.h b/drivers/crypto/ux500/cryp/cryp.h index 59e1557a62..db5713d7c9 100644 --- a/drivers/crypto/ux500/cryp/cryp.h +++ b/drivers/crypto/ux500/cryp/cryp.h @@ -224,7 +224,6 @@ struct cryp_dma { * @phybase: Pointer to physical memory location of the cryp device. * @dev: Pointer to the devices dev structure. * @clk: Pointer to the device's clock control. - * @irq: IRQ number * @pwr_regulator: Pointer to the device's power control. * @power_status: Current status of the power. * @ctx_lock: Lock for current_ctx. @@ -240,7 +239,6 @@ struct cryp_device_data { phys_addr_t phybase; struct device *dev; struct clk *clk; - int irq; struct regulator *pwr_regulator; int power_status; spinlock_t ctx_lock; diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 97277b7150..30cdd52539 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c @@ -1257,6 +1257,7 @@ static int ux500_cryp_probe(struct platform_device *pdev) { int ret; struct resource *res; + struct resource *res_irq; struct cryp_device_data *device_data; struct cryp_protection_config prot = { .privilege_access = CRYP_STATE_ENABLE @@ -1340,13 +1341,15 @@ static int ux500_cryp_probe(struct platform_device *pdev) goto out_power; } - device_data->irq = platform_get_irq(pdev, 0); - if (device_data->irq <= 0) { - ret = device_data->irq ? device_data->irq : -ENXIO; + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res_irq) { + dev_err(dev, "[%s]: IORESOURCE_IRQ unavailable", + __func__); + ret = -ENODEV; goto out_power; } - ret = devm_request_irq(&pdev->dev, device_data->irq, + ret = devm_request_irq(&pdev->dev, res_irq->start, cryp_interrupt_handler, 0, "cryp1", device_data); if (ret) { dev_err(dev, "[%s]: Unable to request IRQ", __func__); @@ -1486,6 +1489,7 @@ static int ux500_cryp_suspend(struct device *dev) int ret; struct platform_device *pdev = to_platform_device(dev); struct cryp_device_data *device_data; + struct resource *res_irq; struct cryp_ctx *temp_ctx = NULL; dev_dbg(dev, "[%s]", __func__); @@ -1497,7 +1501,11 @@ static int ux500_cryp_suspend(struct device *dev) return -ENOMEM; } - disable_irq(device_data->irq); + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res_irq) + dev_err(dev, "[%s]: IORESOURCE_IRQ, unavailable", __func__); + else + disable_irq(res_irq->start); spin_lock(&device_data->ctx_lock); if (!device_data->current_ctx) @@ -1524,6 +1532,7 @@ static int ux500_cryp_resume(struct device *dev) int ret = 0; struct platform_device *pdev = to_platform_device(dev); struct cryp_device_data *device_data; + struct resource *res_irq; struct cryp_ctx *temp_ctx = NULL; dev_dbg(dev, "[%s]", __func__); @@ -1547,8 +1556,11 @@ static int ux500_cryp_resume(struct device *dev) if (ret) dev_err(dev, "[%s]: cryp_enable_power() failed!", __func__); - else - enable_irq(device_data->irq); + else { + res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res_irq) + enable_irq(res_irq->start); + } return ret; } diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c index 8e977b7627..e2375d9923 100644 --- a/drivers/crypto/virtio/virtio_crypto_core.c +++ b/drivers/crypto/virtio/virtio_crypto_core.c @@ -404,7 +404,7 @@ static int virtcrypto_probe(struct virtio_device *vdev) free_engines: virtcrypto_clear_crypto_engines(vcrypto); free_vqs: - virtio_reset_device(vdev); + vcrypto->vdev->config->reset(vdev); virtcrypto_del_vqs(vcrypto); free_dev: virtcrypto_devmgr_rm_dev(vcrypto); @@ -436,7 +436,7 @@ static void virtcrypto_remove(struct virtio_device *vdev) if (virtcrypto_dev_started(vcrypto)) virtcrypto_dev_stop(vcrypto); - virtio_reset_device(vdev); + vdev->config->reset(vdev); virtcrypto_free_unused_reqs(vcrypto); virtcrypto_clear_crypto_engines(vcrypto); virtcrypto_del_vqs(vcrypto); @@ -456,7 +456,7 @@ static int virtcrypto_freeze(struct virtio_device *vdev) { struct virtio_crypto *vcrypto = vdev->priv; - virtio_reset_device(vdev); + vdev->config->reset(vdev); virtcrypto_free_unused_reqs(vcrypto); if (virtcrypto_dev_started(vcrypto)) virtcrypto_dev_stop(vcrypto); @@ -492,7 +492,7 @@ static int virtcrypto_restore(struct virtio_device *vdev) free_engines: virtcrypto_clear_crypto_engines(vcrypto); free_vqs: - virtio_reset_device(vdev); + vcrypto->vdev->config->reset(vdev); virtcrypto_del_vqs(vcrypto); return err; } diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index 67c91378f2..e6de221cc5 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -51,7 +51,6 @@ config CXL_ACPI tristate "CXL ACPI: Platform Support" depends on ACPI default CXL_BUS - select ACPI_TABLE_LIB help Enable support for host managed device memory (HDM) resources published by a platform's ACPI CXL memory layout description. See diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 3163167ecc..54e9d4d2cf 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -8,6 +8,8 @@ #include #include "cxl.h" +static struct acpi_table_header *acpi_cedt; + /* Encode defined in CXL 2.0 8.2.5.12.7 HDM Decoder Control Register */ #define CFMWS_INTERLEAVE_WAYS(x) (1 << (x)->interleave_ways) #define CFMWS_INTERLEAVE_GRANULARITY(x) ((x)->granularity + 8) @@ -50,12 +52,6 @@ static int cxl_acpi_cfmws_verify(struct device *dev, return -EINVAL; } - if (CFMWS_INTERLEAVE_WAYS(cfmws) > CXL_DECODER_MAX_INTERLEAVE) { - dev_err(dev, "CFMWS Interleave Ways (%d) too large\n", - CFMWS_INTERLEAVE_WAYS(cfmws)); - return -EINVAL; - } - expected_len = struct_size((cfmws), interleave_targets, CFMWS_INTERLEAVE_WAYS(cfmws)); @@ -72,67 +68,129 @@ static int cxl_acpi_cfmws_verify(struct device *dev, return 0; } -struct cxl_cfmws_context { - struct device *dev; - struct cxl_port *root_port; -}; - -static int cxl_parse_cfmws(union acpi_subtable_headers *header, void *arg, - const unsigned long end) +static void cxl_add_cfmws_decoders(struct device *dev, + struct cxl_port *root_port) { - int target_map[CXL_DECODER_MAX_INTERLEAVE]; - struct cxl_cfmws_context *ctx = arg; - struct cxl_port *root_port = ctx->root_port; - struct device *dev = ctx->dev; struct acpi_cedt_cfmws *cfmws; struct cxl_decoder *cxld; - int rc, i; + acpi_size len, cur = 0; + void *cedt_subtable; + unsigned long flags; + int rc; - cfmws = (struct acpi_cedt_cfmws *) header; + len = acpi_cedt->length - sizeof(*acpi_cedt); + cedt_subtable = acpi_cedt + 1; - rc = cxl_acpi_cfmws_verify(dev, cfmws); - if (rc) { - dev_err(dev, "CFMWS range %#llx-%#llx not registered\n", - cfmws->base_hpa, - cfmws->base_hpa + cfmws->window_size - 1); - return 0; + while (cur < len) { + struct acpi_cedt_header *c = cedt_subtable + cur; + + if (c->type != ACPI_CEDT_TYPE_CFMWS) { + cur += c->length; + continue; + } + + cfmws = cedt_subtable + cur; + + if (cfmws->header.length < sizeof(*cfmws)) { + dev_warn_once(dev, + "CFMWS entry skipped:invalid length:%u\n", + cfmws->header.length); + cur += c->length; + continue; + } + + rc = cxl_acpi_cfmws_verify(dev, cfmws); + if (rc) { + dev_err(dev, "CFMWS range %#llx-%#llx not registered\n", + cfmws->base_hpa, cfmws->base_hpa + + cfmws->window_size - 1); + cur += c->length; + continue; + } + + flags = cfmws_to_decoder_flags(cfmws->restrictions); + cxld = devm_cxl_add_decoder(dev, root_port, + CFMWS_INTERLEAVE_WAYS(cfmws), + cfmws->base_hpa, cfmws->window_size, + CFMWS_INTERLEAVE_WAYS(cfmws), + CFMWS_INTERLEAVE_GRANULARITY(cfmws), + CXL_DECODER_EXPANDER, + flags); + + if (IS_ERR(cxld)) { + dev_err(dev, "Failed to add decoder for %#llx-%#llx\n", + cfmws->base_hpa, cfmws->base_hpa + + cfmws->window_size - 1); + } else { + dev_dbg(dev, "add: %s range %#llx-%#llx\n", + dev_name(&cxld->dev), cfmws->base_hpa, + cfmws->base_hpa + cfmws->window_size - 1); + } + cur += c->length; } - - for (i = 0; i < CFMWS_INTERLEAVE_WAYS(cfmws); i++) - target_map[i] = cfmws->interleave_targets[i]; - - cxld = cxl_decoder_alloc(root_port, CFMWS_INTERLEAVE_WAYS(cfmws)); - if (IS_ERR(cxld)) - return 0; - - cxld->flags = cfmws_to_decoder_flags(cfmws->restrictions); - cxld->target_type = CXL_DECODER_EXPANDER; - cxld->range = (struct range){ - .start = cfmws->base_hpa, - .end = cfmws->base_hpa + cfmws->window_size - 1, - }; - cxld->interleave_ways = CFMWS_INTERLEAVE_WAYS(cfmws); - cxld->interleave_granularity = CFMWS_INTERLEAVE_GRANULARITY(cfmws); - - rc = cxl_decoder_add(cxld, target_map); - if (rc) - put_device(&cxld->dev); - else - rc = cxl_decoder_autoremove(dev, cxld); - if (rc) { - dev_err(dev, "Failed to add decoder for %#llx-%#llx\n", - cfmws->base_hpa, - cfmws->base_hpa + cfmws->window_size - 1); - return 0; - } - dev_dbg(dev, "add: %s node: %d range %#llx-%#llx\n", - dev_name(&cxld->dev), phys_to_target_node(cxld->range.start), - cfmws->base_hpa, cfmws->base_hpa + cfmws->window_size - 1); - - return 0; } -__mock int match_add_root_ports(struct pci_dev *pdev, void *data) +static struct acpi_cedt_chbs *cxl_acpi_match_chbs(struct device *dev, u32 uid) +{ + struct acpi_cedt_chbs *chbs, *chbs_match = NULL; + acpi_size len, cur = 0; + void *cedt_subtable; + + len = acpi_cedt->length - sizeof(*acpi_cedt); + cedt_subtable = acpi_cedt + 1; + + while (cur < len) { + struct acpi_cedt_header *c = cedt_subtable + cur; + + if (c->type != ACPI_CEDT_TYPE_CHBS) { + cur += c->length; + continue; + } + + chbs = cedt_subtable + cur; + + if (chbs->header.length < sizeof(*chbs)) { + dev_warn_once(dev, + "CHBS entry skipped: invalid length:%u\n", + chbs->header.length); + cur += c->length; + continue; + } + + if (chbs->uid != uid) { + cur += c->length; + continue; + } + + if (chbs_match) { + dev_warn_once(dev, + "CHBS entry skipped: duplicate UID:%u\n", + uid); + cur += c->length; + continue; + } + + chbs_match = chbs; + cur += c->length; + } + + return chbs_match ? chbs_match : ERR_PTR(-ENODEV); +} + +static resource_size_t get_chbcr(struct acpi_cedt_chbs *chbs) +{ + return IS_ERR(chbs) ? CXL_RESOURCE_NONE : chbs->base; +} + +struct cxl_walk_context { + struct device *dev; + struct pci_bus *root; + struct cxl_port *port; + int error; + int count; +}; + +static int match_add_root_ports(struct pci_dev *pdev, void *data) { struct cxl_walk_context *ctx = data; struct pci_bus *root_bus = ctx->root; @@ -181,8 +239,7 @@ static struct cxl_dport *find_dport_by_dev(struct cxl_port *port, struct device return NULL; } -__mock struct acpi_device *to_cxl_host_bridge(struct device *host, - struct device *dev) +static struct acpi_device *to_cxl_host_bridge(struct device *dev) { struct acpi_device *adev = to_acpi_device(dev); @@ -200,12 +257,11 @@ __mock struct acpi_device *to_cxl_host_bridge(struct device *host, */ static int add_host_bridge_uport(struct device *match, void *arg) { + struct acpi_device *bridge = to_cxl_host_bridge(match); struct cxl_port *root_port = arg; struct device *host = root_port->dev.parent; - struct acpi_device *bridge = to_cxl_host_bridge(host, match); struct acpi_pci_root *pci_root; struct cxl_walk_context ctx; - int single_port_map[1], rc; struct cxl_decoder *cxld; struct cxl_dport *dport; struct cxl_port *port; @@ -216,7 +272,7 @@ static int add_host_bridge_uport(struct device *match, void *arg) dport = find_dport_by_dev(root_port, match); if (!dport) { dev_dbg(host, "host bridge expected and not found\n"); - return 0; + return -ENODEV; } port = devm_cxl_add_port(host, match, dport->component_reg_phys, @@ -241,68 +297,20 @@ static int add_host_bridge_uport(struct device *match, void *arg) return -ENODEV; if (ctx.error) return ctx.error; - if (ctx.count > 1) - return 0; /* TODO: Scan CHBCR for HDM Decoder resources */ /* - * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability - * Structure) single ported host-bridges need not publish a decoder - * capability when a passthrough decode can be assumed, i.e. all - * transactions that the uport sees are claimed and passed to the single - * dport. Disable the range until the first CXL region is enumerated / - * activated. + * In the single-port host-bridge case there are no HDM decoders + * in the CHBCR and a 1:1 passthrough decode is implied. */ - cxld = cxl_decoder_alloc(port, 1); - if (IS_ERR(cxld)) - return PTR_ERR(cxld); + if (ctx.count == 1) { + cxld = devm_cxl_add_passthrough_decoder(host, port); + if (IS_ERR(cxld)) + return PTR_ERR(cxld); - cxld->interleave_ways = 1; - cxld->interleave_granularity = PAGE_SIZE; - cxld->target_type = CXL_DECODER_EXPANDER; - cxld->range = (struct range) { - .start = 0, - .end = -1, - }; - - device_lock(&port->dev); - dport = list_first_entry(&port->dports, typeof(*dport), list); - device_unlock(&port->dev); - - single_port_map[0] = dport->port_id; - - rc = cxl_decoder_add(cxld, single_port_map); - if (rc) - put_device(&cxld->dev); - else - rc = cxl_decoder_autoremove(host, cxld); - - if (rc == 0) dev_dbg(host, "add: %s\n", dev_name(&cxld->dev)); - return rc; -} - -struct cxl_chbs_context { - struct device *dev; - unsigned long long uid; - resource_size_t chbcr; -}; - -static int cxl_get_chbcr(union acpi_subtable_headers *header, void *arg, - const unsigned long end) -{ - struct cxl_chbs_context *ctx = arg; - struct acpi_cedt_chbs *chbs; - - if (ctx->chbcr) - return 0; - - chbs = (struct acpi_cedt_chbs *) header; - - if (ctx->uid != chbs->uid) - return 0; - ctx->chbcr = chbs->base; + } return 0; } @@ -312,10 +320,10 @@ static int add_host_bridge_dport(struct device *match, void *arg) int rc; acpi_status status; unsigned long long uid; - struct cxl_chbs_context ctx; + struct acpi_cedt_chbs *chbs; struct cxl_port *root_port = arg; struct device *host = root_port->dev.parent; - struct acpi_device *bridge = to_cxl_host_bridge(host, match); + struct acpi_device *bridge = to_cxl_host_bridge(match); if (!bridge) return 0; @@ -328,19 +336,12 @@ static int add_host_bridge_dport(struct device *match, void *arg) return -ENODEV; } - ctx = (struct cxl_chbs_context) { - .dev = host, - .uid = uid, - }; - acpi_table_parse_cedt(ACPI_CEDT_TYPE_CHBS, cxl_get_chbcr, &ctx); + chbs = cxl_acpi_match_chbs(host, uid); + if (IS_ERR(chbs)) + dev_dbg(host, "No CHBS found for Host Bridge: %s\n", + dev_name(match)); - if (ctx.chbcr == 0) { - dev_warn(host, "No CHBS found for Host Bridge: %s\n", - dev_name(match)); - return 0; - } - - rc = cxl_add_dport(root_port, match, uid, ctx.chbcr); + rc = cxl_add_dport(root_port, match, uid, get_chbcr(chbs)); if (rc) { dev_err(host, "failed to add downstream port: %s\n", dev_name(match)); @@ -377,26 +378,26 @@ static int add_root_nvdimm_bridge(struct device *match, void *data) static int cxl_acpi_probe(struct platform_device *pdev) { int rc; + acpi_status status; struct cxl_port *root_port; struct device *host = &pdev->dev; struct acpi_device *adev = ACPI_COMPANION(host); - struct cxl_cfmws_context ctx; root_port = devm_cxl_add_port(host, host, CXL_RESOURCE_NONE, NULL); if (IS_ERR(root_port)) return PTR_ERR(root_port); dev_dbg(host, "add: %s\n", dev_name(&root_port->dev)); + status = acpi_get_table(ACPI_SIG_CEDT, 0, &acpi_cedt); + if (ACPI_FAILURE(status)) + return -ENXIO; + rc = bus_for_each_dev(adev->dev.bus, NULL, root_port, add_host_bridge_dport); - if (rc < 0) - return rc; + if (rc) + goto out; - ctx = (struct cxl_cfmws_context) { - .dev = host, - .root_port = root_port, - }; - acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, cxl_parse_cfmws, &ctx); + cxl_add_cfmws_decoders(host, root_port); /* * Root level scanned with host-bridge as dports, now scan host-bridges @@ -404,21 +405,23 @@ static int cxl_acpi_probe(struct platform_device *pdev) */ rc = bus_for_each_dev(adev->dev.bus, NULL, root_port, add_host_bridge_uport); - if (rc < 0) - return rc; + if (rc) + goto out; if (IS_ENABLED(CONFIG_CXL_PMEM)) rc = device_for_each_child(&root_port->dev, root_port, add_root_nvdimm_bridge); + +out: + acpi_put_table(acpi_cedt); if (rc < 0) return rc; - return 0; } static const struct acpi_device_id cxl_acpi_ids[] = { - { "ACPI0017" }, - { }, + { "ACPI0017", 0 }, + { "", 0 }, }; MODULE_DEVICE_TABLE(acpi, cxl_acpi_ids); @@ -433,4 +436,3 @@ static struct platform_driver cxl_acpi_driver = { module_platform_driver(cxl_acpi_driver); MODULE_LICENSE("GPL v2"); MODULE_IMPORT_NS(CXL); -MODULE_IMPORT_NS(ACPI); diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index 40ab50318d..0fdbf3c6ac 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CXL_BUS) += cxl_core.o -ccflags-y += -I$(srctree)/drivers/cxl +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl cxl_core-y := bus.o cxl_core-y += pmem.o cxl_core-y += regs.o cxl_core-y += memdev.o -cxl_core-y += mbox.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index 3f9b98ecd1..267d8042be 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -200,7 +200,7 @@ bool is_root_decoder(struct device *dev) { return dev->type == &cxl_decoder_root_type; } -EXPORT_SYMBOL_NS_GPL(is_root_decoder, CXL); +EXPORT_SYMBOL_GPL(is_root_decoder); struct cxl_decoder *to_cxl_decoder(struct device *dev) { @@ -209,7 +209,7 @@ struct cxl_decoder *to_cxl_decoder(struct device *dev) return NULL; return container_of(dev, struct cxl_decoder, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL); +EXPORT_SYMBOL_GPL(to_cxl_decoder); static void cxl_dport_release(struct cxl_dport *dport) { @@ -376,7 +376,7 @@ struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_port, CXL); +EXPORT_SYMBOL_GPL(devm_cxl_add_port); static struct cxl_dport *find_dport(struct cxl_port *port, int id) { @@ -451,47 +451,28 @@ int cxl_add_dport(struct cxl_port *port, struct device *dport_dev, int port_id, cxl_dport_release(dport); return rc; } -EXPORT_SYMBOL_NS_GPL(cxl_add_dport, CXL); +EXPORT_SYMBOL_GPL(cxl_add_dport); -static int decoder_populate_targets(struct cxl_decoder *cxld, - struct cxl_port *port, int *target_map) -{ - int rc = 0, i; - - if (!target_map) - return 0; - - device_lock(&port->dev); - if (list_empty(&port->dports)) { - rc = -EINVAL; - goto out_unlock; - } - - for (i = 0; i < cxld->nr_targets; i++) { - struct cxl_dport *dport = find_dport(port, target_map[i]); - - if (!dport) { - rc = -ENXIO; - goto out_unlock; - } - cxld->target[i] = dport; - } - -out_unlock: - device_unlock(&port->dev); - - return rc; -} - -struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets) +static struct cxl_decoder * +cxl_decoder_alloc(struct cxl_port *port, int nr_targets, resource_size_t base, + resource_size_t len, int interleave_ways, + int interleave_granularity, enum cxl_decoder_type type, + unsigned long flags) { struct cxl_decoder *cxld; struct device *dev; int rc = 0; - if (nr_targets > CXL_DECODER_MAX_INTERLEAVE || nr_targets < 1) + if (interleave_ways < 1) return ERR_PTR(-EINVAL); + device_lock(&port->dev); + if (list_empty(&port->dports)) + rc = -EINVAL; + device_unlock(&port->dev); + if (rc) + return ERR_PTR(rc); + cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL); if (!cxld) return ERR_PTR(-ENOMEM); @@ -500,8 +481,22 @@ struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets) if (rc < 0) goto err; - cxld->id = rc; - cxld->nr_targets = nr_targets; + *cxld = (struct cxl_decoder) { + .id = rc, + .range = { + .start = base, + .end = base + len - 1, + }, + .flags = flags, + .interleave_ways = interleave_ways, + .interleave_granularity = interleave_granularity, + .target_type = type, + }; + + /* handle implied target_list */ + if (interleave_ways == 1) + cxld->target[0] = + list_first_entry(&port->dports, struct cxl_dport, list); dev = &cxld->dev; device_initialize(dev); device_set_pm_not_required(dev); @@ -519,47 +514,41 @@ struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets) kfree(cxld); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(cxl_decoder_alloc, CXL); -int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map) +struct cxl_decoder * +devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, + resource_size_t base, resource_size_t len, + int interleave_ways, int interleave_granularity, + enum cxl_decoder_type type, unsigned long flags) { - struct cxl_port *port; + struct cxl_decoder *cxld; struct device *dev; int rc; - if (WARN_ON_ONCE(!cxld)) - return -EINVAL; - - if (WARN_ON_ONCE(IS_ERR(cxld))) - return PTR_ERR(cxld); - - if (cxld->interleave_ways < 1) - return -EINVAL; - - port = to_cxl_port(cxld->dev.parent); - rc = decoder_populate_targets(cxld, port, target_map); - if (rc) - return rc; + cxld = cxl_decoder_alloc(port, nr_targets, base, len, interleave_ways, + interleave_granularity, type, flags); + if (IS_ERR(cxld)) + return cxld; dev = &cxld->dev; rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id); if (rc) - return rc; + goto err; - return device_add(dev); -} -EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, CXL); + rc = device_add(dev); + if (rc) + goto err; -static void cxld_unregister(void *dev) -{ - device_unregister(dev); -} + rc = devm_add_action_or_reset(host, unregister_cxl_dev, dev); + if (rc) + return ERR_PTR(rc); + return cxld; -int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld) -{ - return devm_add_action_or_reset(host, cxld_unregister, &cxld->dev); +err: + put_device(dev); + return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(cxl_decoder_autoremove, CXL); +EXPORT_SYMBOL_GPL(devm_cxl_add_decoder); /** * __cxl_driver_register - register a driver for the cxl bus @@ -592,13 +581,13 @@ int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, return driver_register(&cxl_drv->drv); } -EXPORT_SYMBOL_NS_GPL(__cxl_driver_register, CXL); +EXPORT_SYMBOL_GPL(__cxl_driver_register); void cxl_driver_unregister(struct cxl_driver *cxl_drv) { driver_unregister(&cxl_drv->drv); } -EXPORT_SYMBOL_NS_GPL(cxl_driver_unregister, CXL); +EXPORT_SYMBOL_GPL(cxl_driver_unregister); static int cxl_device_id(struct device *dev) { @@ -640,14 +629,12 @@ struct bus_type cxl_bus_type = { .probe = cxl_bus_probe, .remove = cxl_bus_remove, }; -EXPORT_SYMBOL_NS_GPL(cxl_bus_type, CXL); +EXPORT_SYMBOL_GPL(cxl_bus_type); static __init int cxl_core_init(void) { int rc; - cxl_mbox_init(); - rc = cxl_memdev_init(); if (rc) return rc; @@ -659,7 +646,6 @@ static __init int cxl_core_init(void) err: cxl_memdev_exit(); - cxl_mbox_exit(); return rc; } @@ -667,7 +653,6 @@ static void cxl_core_exit(void) { bus_unregister(&cxl_bus_type); cxl_memdev_exit(); - cxl_mbox_exit(); } module_init(cxl_core_init); diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index e0c9aacc4e..036a3c8106 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -9,15 +9,12 @@ extern const struct device_type cxl_nvdimm_type; extern struct attribute_group cxl_base_attribute_group; -struct cxl_send_command; -struct cxl_mem_query_commands; -int cxl_query_cmd(struct cxl_memdev *cxlmd, - struct cxl_mem_query_commands __user *q); -int cxl_send_cmd(struct cxl_memdev *cxlmd, struct cxl_send_command __user *s); +static inline void unregister_cxl_dev(void *dev) +{ + device_unregister(dev); +} int cxl_memdev_init(void); void cxl_memdev_exit(void); -void cxl_mbox_init(void); -void cxl_mbox_exit(void); #endif /* __CXL_CORE_H__ */ diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index 61029cb7ac..a9c317e320 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -8,8 +8,6 @@ #include #include "core.h" -static DECLARE_RWSEM(cxl_memdev_rwsem); - /* * An entire PCI topology full of devices should be enough for any * config @@ -37,9 +35,9 @@ static ssize_t firmware_version_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_mem *cxlm = cxlmd->cxlm; - return sysfs_emit(buf, "%.16s\n", cxlds->firmware_version); + return sysfs_emit(buf, "%.16s\n", cxlm->firmware_version); } static DEVICE_ATTR_RO(firmware_version); @@ -47,9 +45,9 @@ static ssize_t payload_max_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_mem *cxlm = cxlmd->cxlm; - return sysfs_emit(buf, "%zu\n", cxlds->payload_size); + return sysfs_emit(buf, "%zu\n", cxlm->payload_size); } static DEVICE_ATTR_RO(payload_max); @@ -57,9 +55,9 @@ static ssize_t label_storage_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_dev_state *cxlds = cxlmd->cxlds; + struct cxl_mem *cxlm = cxlmd->cxlm; - return sysfs_emit(buf, "%zu\n", cxlds->lsa_size); + return sysfs_emit(buf, "%zu\n", cxlm->lsa_size); } static DEVICE_ATTR_RO(label_storage_size); @@ -67,8 +65,8 @@ static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_dev_state *cxlds = cxlmd->cxlds; - unsigned long long len = range_len(&cxlds->ram_range); + struct cxl_mem *cxlm = cxlmd->cxlm; + unsigned long long len = range_len(&cxlm->ram_range); return sysfs_emit(buf, "%#llx\n", len); } @@ -80,8 +78,8 @@ static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_dev_state *cxlds = cxlmd->cxlds; - unsigned long long len = range_len(&cxlds->pmem_range); + struct cxl_mem *cxlm = cxlmd->cxlm; + unsigned long long len = range_len(&cxlm->pmem_range); return sysfs_emit(buf, "%#llx\n", len); } @@ -134,60 +132,24 @@ static const struct device_type cxl_memdev_type = { .groups = cxl_memdev_attribute_groups, }; -/** - * set_exclusive_cxl_commands() - atomically disable user cxl commands - * @cxlds: The device state to operate on - * @cmds: bitmap of commands to mark exclusive - * - * Grab the cxl_memdev_rwsem in write mode to flush in-flight - * invocations of the ioctl path and then disable future execution of - * commands with the command ids set in @cmds. - */ -void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds) -{ - down_write(&cxl_memdev_rwsem); - bitmap_or(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds, - CXL_MEM_COMMAND_ID_MAX); - up_write(&cxl_memdev_rwsem); -} -EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, CXL); - -/** - * clear_exclusive_cxl_commands() - atomically enable user cxl commands - * @cxlds: The device state to modify - * @cmds: bitmap of commands to mark available for userspace - */ -void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds) -{ - down_write(&cxl_memdev_rwsem); - bitmap_andnot(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds, - CXL_MEM_COMMAND_ID_MAX); - up_write(&cxl_memdev_rwsem); -} -EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, CXL); - -static void cxl_memdev_shutdown(struct device *dev) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - - down_write(&cxl_memdev_rwsem); - cxlmd->cxlds = NULL; - up_write(&cxl_memdev_rwsem); -} - static void cxl_memdev_unregister(void *_cxlmd) { struct cxl_memdev *cxlmd = _cxlmd; struct device *dev = &cxlmd->dev; + struct cdev *cdev = &cxlmd->cdev; + const struct cdevm_file_operations *cdevm_fops; + + cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops); + cdevm_fops->shutdown(dev); - cxl_memdev_shutdown(dev); cdev_device_del(&cxlmd->cdev, dev); put_device(dev); } -static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds, +static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm, const struct file_operations *fops) { + struct pci_dev *pdev = cxlm->pdev; struct cxl_memdev *cxlmd; struct device *dev; struct cdev *cdev; @@ -204,7 +166,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds, dev = &cxlmd->dev; device_initialize(dev); - dev->parent = cxlds->dev; + dev->parent = &pdev->dev; dev->bus = &cxl_bus_type; dev->devt = MKDEV(cxl_mem_major, cxlmd->id); dev->type = &cxl_memdev_type; @@ -219,71 +181,16 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds, return ERR_PTR(rc); } -static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { - case CXL_MEM_QUERY_COMMANDS: - return cxl_query_cmd(cxlmd, (void __user *)arg); - case CXL_MEM_SEND_COMMAND: - return cxl_send_cmd(cxlmd, (void __user *)arg); - default: - return -ENOTTY; - } -} - -static long cxl_memdev_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct cxl_memdev *cxlmd = file->private_data; - int rc = -ENXIO; - - down_read(&cxl_memdev_rwsem); - if (cxlmd->cxlds) - rc = __cxl_memdev_ioctl(cxlmd, cmd, arg); - up_read(&cxl_memdev_rwsem); - - return rc; -} - -static int cxl_memdev_open(struct inode *inode, struct file *file) -{ - struct cxl_memdev *cxlmd = - container_of(inode->i_cdev, typeof(*cxlmd), cdev); - - get_device(&cxlmd->dev); - file->private_data = cxlmd; - - return 0; -} - -static int cxl_memdev_release_file(struct inode *inode, struct file *file) -{ - struct cxl_memdev *cxlmd = - container_of(inode->i_cdev, typeof(*cxlmd), cdev); - - put_device(&cxlmd->dev); - - return 0; -} - -static const struct file_operations cxl_memdev_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cxl_memdev_ioctl, - .open = cxl_memdev_open, - .release = cxl_memdev_release_file, - .compat_ioctl = compat_ptr_ioctl, - .llseek = noop_llseek, -}; - -struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) +struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops) { struct cxl_memdev *cxlmd; struct device *dev; struct cdev *cdev; int rc; - cxlmd = cxl_memdev_alloc(cxlds, &cxl_memdev_fops); + cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops); if (IS_ERR(cxlmd)) return cxlmd; @@ -296,14 +203,14 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) * Activate ioctl operations, no cxl_memdev_rwsem manipulation * needed as this is ordered with cdev_add() publishing the device. */ - cxlmd->cxlds = cxlds; + cxlmd->cxlm = cxlm; cdev = &cxlmd->cdev; rc = cdev_device_add(cdev, dev); if (rc) goto err; - rc = devm_add_action_or_reset(cxlds->dev, cxl_memdev_unregister, cxlmd); + rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd); if (rc) return ERR_PTR(rc); return cxlmd; @@ -313,11 +220,11 @@ struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds) * The cdev was briefly live, shutdown any ioctl operations that * saw that state. */ - cxl_memdev_shutdown(dev); + cdevm_fops->shutdown(dev); put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_memdev, CXL); +EXPORT_SYMBOL_GPL(devm_cxl_add_memdev); __init int cxl_memdev_init(void) { diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c index b5fca97b0a..d24570f5b8 100644 --- a/drivers/cxl/core/pmem.c +++ b/drivers/cxl/core/pmem.c @@ -2,7 +2,6 @@ /* Copyright(c) 2020 Intel Corporation. */ #include #include -#include #include #include #include "core.h" @@ -21,13 +20,10 @@ * operations, for example, namespace label access commands. */ -static DEFINE_IDA(cxl_nvdimm_bridge_ida); - static void cxl_nvdimm_bridge_release(struct device *dev) { struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); - ida_free(&cxl_nvdimm_bridge_ida, cxl_nvb->id); kfree(cxl_nvb); } @@ -49,46 +45,18 @@ struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm_bridge, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm_bridge, CXL); - -bool is_cxl_nvdimm_bridge(struct device *dev) -{ - return dev->type == &cxl_nvdimm_bridge_type; -} -EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm_bridge, CXL); - -__mock int match_nvdimm_bridge(struct device *dev, const void *data) -{ - return is_cxl_nvdimm_bridge(dev); -} - -struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd) -{ - struct device *dev; - - dev = bus_find_device(&cxl_bus_type, NULL, cxl_nvd, match_nvdimm_bridge); - if (!dev) - return NULL; - return to_cxl_nvdimm_bridge(dev); -} -EXPORT_SYMBOL_NS_GPL(cxl_find_nvdimm_bridge, CXL); +EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); static struct cxl_nvdimm_bridge * cxl_nvdimm_bridge_alloc(struct cxl_port *port) { struct cxl_nvdimm_bridge *cxl_nvb; struct device *dev; - int rc; cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); if (!cxl_nvb) return ERR_PTR(-ENOMEM); - rc = ida_alloc(&cxl_nvdimm_bridge_ida, GFP_KERNEL); - if (rc < 0) - goto err; - cxl_nvb->id = rc; - dev = &cxl_nvb->dev; cxl_nvb->port = port; cxl_nvb->state = CXL_NVB_NEW; @@ -99,10 +67,6 @@ cxl_nvdimm_bridge_alloc(struct cxl_port *port) dev->type = &cxl_nvdimm_bridge_type; return cxl_nvb; - -err: - kfree(cxl_nvb); - return ERR_PTR(rc); } static void unregister_nvb(void *_cxl_nvb) @@ -155,7 +119,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, return cxl_nvb; dev = &cxl_nvb->dev; - rc = dev_set_name(dev, "nvdimm-bridge%d", cxl_nvb->id); + rc = dev_set_name(dev, "nvdimm-bridge"); if (rc) goto err; @@ -173,7 +137,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, CXL); +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); static void cxl_nvdimm_release(struct device *dev) { @@ -197,7 +161,7 @@ bool is_cxl_nvdimm(struct device *dev) { return dev->type == &cxl_nvdimm_type; } -EXPORT_SYMBOL_NS_GPL(is_cxl_nvdimm, CXL); +EXPORT_SYMBOL_GPL(is_cxl_nvdimm); struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) { @@ -206,7 +170,7 @@ struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) return NULL; return container_of(dev, struct cxl_nvdimm, dev); } -EXPORT_SYMBOL_NS_GPL(to_cxl_nvdimm, CXL); +EXPORT_SYMBOL_GPL(to_cxl_nvdimm); static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) { @@ -228,11 +192,6 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) return cxl_nvd; } -static void cxl_nvd_unregister(void *dev) -{ - device_unregister(dev); -} - /** * devm_cxl_add_nvdimm() - add a bridge between a cxl_memdev and an nvdimm * @host: same host as @cxlmd @@ -262,10 +221,10 @@ int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd) dev_dbg(host, "%s: register %s\n", dev_name(dev->parent), dev_name(dev)); - return devm_add_action_or_reset(host, cxl_nvd_unregister, dev); + return devm_add_action_or_reset(host, unregister_cxl_dev, dev); err: put_device(dev); return rc; } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm, CXL); +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index e37e23bf43..41de4a136e 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -90,7 +90,7 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, } } } -EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL); +EXPORT_SYMBOL_GPL(cxl_probe_component_regs); /** * cxl_probe_device_regs() - Detect CXL Device register blocks @@ -156,7 +156,7 @@ void cxl_probe_device_regs(struct device *dev, void __iomem *base, } } } -EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, CXL); +EXPORT_SYMBOL_GPL(cxl_probe_device_regs); static void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, @@ -199,7 +199,7 @@ int cxl_map_component_regs(struct pci_dev *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL); +EXPORT_SYMBOL_GPL(cxl_map_component_regs); int cxl_map_device_regs(struct pci_dev *pdev, struct cxl_device_regs *regs, @@ -246,4 +246,4 @@ int cxl_map_device_regs(struct pci_dev *pdev, return 0; } -EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL); +EXPORT_SYMBOL_GPL(cxl_map_device_regs); diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index a5a0be3f08..53927f9fa7 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -75,27 +75,52 @@ static inline int cxl_hdm_decoder_count(u32 cap_hdr) #define CXLDEV_MBOX_BG_CMD_STATUS_OFFSET 0x18 #define CXLDEV_MBOX_PAYLOAD_OFFSET 0x20 +#define CXL_COMPONENT_REGS() \ + void __iomem *hdm_decoder + +#define CXL_DEVICE_REGS() \ + void __iomem *status; \ + void __iomem *mbox; \ + void __iomem *memdev + +/* See note for 'struct cxl_regs' for the rationale of this organization */ /* - * Using struct_group() allows for per register-block-type helper routines, - * without requiring block-type agnostic code to include the prefix. + * CXL_COMPONENT_REGS - Common set of CXL Component register block base pointers + * @hdm_decoder: CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure + */ +struct cxl_component_regs { + CXL_COMPONENT_REGS(); +}; + +/* See note for 'struct cxl_regs' for the rationale of this organization */ +/* + * CXL_DEVICE_REGS - Common set of CXL Device register block base pointers + * @status: CXL 2.0 8.2.8.3 Device Status Registers + * @mbox: CXL 2.0 8.2.8.4 Mailbox Registers + * @memdev: CXL 2.0 8.2.8.5 Memory Device Registers + */ +struct cxl_device_regs { + CXL_DEVICE_REGS(); +}; + +/* + * Note, the anonymous union organization allows for per + * register-block-type helper routines, without requiring block-type + * agnostic code to include the prefix. */ struct cxl_regs { - /* - * Common set of CXL Component register block base pointers - * @hdm_decoder: CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure - */ - struct_group_tagged(cxl_component_regs, component, - void __iomem *hdm_decoder; - ); - /* - * Common set of CXL Device register block base pointers - * @status: CXL 2.0 8.2.8.3 Device Status Registers - * @mbox: CXL 2.0 8.2.8.4 Mailbox Registers - * @memdev: CXL 2.0 8.2.8.5 Memory Device Registers - */ - struct_group_tagged(cxl_device_regs, device_regs, - void __iomem *status, *mbox, *memdev; - ); + union { + struct { + CXL_COMPONENT_REGS(); + }; + struct cxl_component_regs component; + }; + union { + struct { + CXL_DEVICE_REGS(); + }; + struct cxl_device_regs device_regs; + }; }; struct cxl_reg_map { @@ -114,17 +139,7 @@ struct cxl_device_reg_map { struct cxl_reg_map memdev; }; -/** - * struct cxl_register_map - DVSEC harvested register block mapping parameters - * @base: virtual base of the register-block-BAR + @block_offset - * @block_offset: offset to start of register block in @barno - * @reg_type: see enum cxl_regloc_type - * @barno: PCI BAR number containing the register block - * @component_map: cxl_reg_map for component registers - * @device_map: cxl_reg_maps for device registers - */ struct cxl_register_map { - void __iomem *base; u64 block_offset; u8 reg_type; u8 barno; @@ -165,12 +180,6 @@ enum cxl_decoder_type { CXL_DECODER_EXPANDER = 3, }; -/* - * Current specification goes up to 8, double that seems a reasonable - * software max for the foreseeable future - */ -#define CXL_DECODER_MAX_INTERLEAVE 16 - /** * struct cxl_decoder - CXL address range decode configuration * @dev: this decoder's device @@ -180,7 +189,6 @@ enum cxl_decoder_type { * @interleave_granularity: data stride per dport * @target_type: accelerator vs expander (type2 vs type3) selector * @flags: memory type capabilities and locking - * @nr_targets: number of elements in @target * @target: active ordered target list in current decoder configuration */ struct cxl_decoder { @@ -191,18 +199,10 @@ struct cxl_decoder { int interleave_granularity; enum cxl_decoder_type target_type; unsigned long flags; - int nr_targets; struct cxl_dport *target[]; }; -/** - * enum cxl_nvdimm_brige_state - state machine for managing bus rescans - * @CXL_NVB_NEW: Set at bridge create and after cxl_pmem_wq is destroyed - * @CXL_NVB_DEAD: Set at brige unregistration to preclude async probing - * @CXL_NVB_ONLINE: Target state after successful ->probe() - * @CXL_NVB_OFFLINE: Target state after ->remove() or failed ->probe() - */ enum cxl_nvdimm_brige_state { CXL_NVB_NEW, CXL_NVB_DEAD, @@ -211,7 +211,6 @@ enum cxl_nvdimm_brige_state { }; struct cxl_nvdimm_bridge { - int id; struct device dev; struct cxl_port *port; struct nvdimm_bus *nvdimm_bus; @@ -226,14 +225,6 @@ struct cxl_nvdimm { struct nvdimm *nvdimm; }; -struct cxl_walk_context { - struct device *dev; - struct pci_bus *root; - struct cxl_port *port; - int error; - int count; -}; - /** * struct cxl_port - logical collection of upstream port devices and * downstream port devices to construct a CXL memory @@ -280,9 +271,25 @@ int cxl_add_dport(struct cxl_port *port, struct device *dport, int port_id, struct cxl_decoder *to_cxl_decoder(struct device *dev); bool is_root_decoder(struct device *dev); -struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port, int nr_targets); -int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map); -int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld); +struct cxl_decoder * +devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, + resource_size_t base, resource_size_t len, + int interleave_ways, int interleave_granularity, + enum cxl_decoder_type type, unsigned long flags); + +/* + * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability Structure) + * single ported host-bridges need not publish a decoder capability when a + * passthrough decode can be assumed, i.e. all transactions that the uport sees + * are claimed and passed to the single dport. Default the range a 0-base + * 0-length until the first CXL region is activated. + */ +static inline struct cxl_decoder * +devm_cxl_add_passthrough_decoder(struct device *host, struct cxl_port *port) +{ + return devm_cxl_add_decoder(host, port, 1, 0, 0, 1, PAGE_SIZE, + CXL_DECODER_EXPANDER, 0); +} extern struct bus_type cxl_bus_type; @@ -315,15 +322,5 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, struct cxl_port *port); struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev); bool is_cxl_nvdimm(struct device *dev); -bool is_cxl_nvdimm_bridge(struct device *dev); int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd); -struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_nvdimm *cxl_nvd); - -/* - * Unit test builds overrides this to __weak, find the 'strong' version - * of these symbols in tools/testing/cxl/. - */ -#ifndef __mock -#define __mock static -#endif #endif /* __CXL_H__ */ diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 8d96d009ad..6c0b1e2ea9 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -2,7 +2,6 @@ /* Copyright(c) 2020-2021 Intel Corporation. */ #ifndef __CXL_MEM_H__ #define __CXL_MEM_H__ -#include #include #include "cxl.h" @@ -29,17 +28,32 @@ (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \ CXLMDEV_RESET_NEEDED_NOT) +/** + * struct cdevm_file_operations - devm coordinated cdev file operations + * @fops: file operations that are synchronized against @shutdown + * @shutdown: disconnect driver data + * + * @shutdown is invoked in the devres release path to disconnect any + * driver instance data from @dev. It assumes synchronization with any + * fops operation that requires driver data. After @shutdown an + * operation may only reference @device data. + */ +struct cdevm_file_operations { + struct file_operations fops; + void (*shutdown)(struct device *dev); +}; + /** * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device * @dev: driver core device object * @cdev: char dev core object for ioctl operations - * @cxlds: The device state backing this device + * @cxlm: pointer to the parent device driver data * @id: id number of this memdev instance. */ struct cxl_memdev { struct device dev; struct cdev cdev; - struct cxl_dev_state *cxlds; + struct cxl_mem *cxlm; int id; }; @@ -48,55 +62,14 @@ static inline struct cxl_memdev *to_cxl_memdev(struct device *dev) return container_of(dev, struct cxl_memdev, dev); } -struct cxl_memdev *devm_cxl_add_memdev(struct cxl_dev_state *cxlds); +struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops); /** - * struct cxl_mbox_cmd - A command to be submitted to hardware. - * @opcode: (input) The command set and command submitted to hardware. - * @payload_in: (input) Pointer to the input payload. - * @payload_out: (output) Pointer to the output payload. Must be allocated by - * the caller. - * @size_in: (input) Number of bytes to load from @payload_in. - * @size_out: (input) Max number of bytes loaded into @payload_out. - * (output) Number of bytes generated by the device. For fixed size - * outputs commands this is always expected to be deterministic. For - * variable sized output commands, it tells the exact number of bytes - * written. - * @return_code: (output) Error code returned from hardware. - * - * This is the primary mechanism used to send commands to the hardware. - * All the fields except @payload_* correspond exactly to the fields described in - * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and - * @payload_out are written to, and read from the Command Payload Registers - * defined in CXL 2.0 8.2.8.4.8. - */ -struct cxl_mbox_cmd { - u16 opcode; - void *payload_in; - void *payload_out; - size_t size_in; - size_t size_out; - u16 return_code; -#define CXL_MBOX_SUCCESS 0 -}; - -/* - * CXL 2.0 - Memory capacity multiplier - * See Section 8.2.9.5 - * - * Volatile, Persistent, and Partition capacities are specified to be in - * multiples of 256MB - define a multiplier to convert to/from bytes. - */ -#define CXL_CAPACITY_MULTIPLIER SZ_256M - -/** - * struct cxl_dev_state - The driver device state - * - * cxl_dev_state represents the CXL driver/device state. It provides an - * interface to mailbox commands as well as some cached data about the device. - * Currently only memory devices are represented. - * - * @dev: The device associated with this CXL state + * struct cxl_mem - A CXL memory device + * @pdev: The PCI device associated with this CXL device. + * @cxlmd: Logical memory device chardev / interface * @regs: Parsed register blocks * @payload_size: Size of space for payload * (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register) @@ -105,24 +78,12 @@ struct cxl_mbox_cmd { * @mbox_mutex: Mutex to synchronize mailbox access. * @firmware_version: Firmware version for the memory device. * @enabled_cmds: Hardware commands found enabled in CEL. - * @exclusive_cmds: Commands that are kernel-internal only - * @pmem_range: Active Persistent memory capacity configuration - * @ram_range: Active Volatile memory capacity configuration - * @total_bytes: sum of all possible capacities - * @volatile_only_bytes: hard volatile capacity - * @persistent_only_bytes: hard persistent capacity - * @partition_align_bytes: alignment size for partition-able capacity - * @active_volatile_bytes: sum of hard + soft volatile - * @active_persistent_bytes: sum of hard + soft persistent - * @next_volatile_bytes: volatile capacity change pending device reset - * @next_persistent_bytes: persistent capacity change pending device reset - * @mbox_send: @dev specific transport for transmitting mailbox commands - * - * See section 8.2.9.5.2 Capacity Configuration and Label Storage for - * details on capacity parameters. + * @pmem_range: Persistent memory capacity information. + * @ram_range: Volatile memory capacity information. */ -struct cxl_dev_state { - struct device *dev; +struct cxl_mem { + struct pci_dev *pdev; + struct cxl_memdev *cxlmd; struct cxl_regs regs; @@ -130,8 +91,7 @@ struct cxl_dev_state { size_t lsa_size; struct mutex mbox_mutex; /* Protects device mailbox and firmware */ char firmware_version[0x10]; - DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX); - DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); + unsigned long *enabled_cmds; struct range pmem_range; struct range ram_range; @@ -144,124 +104,5 @@ struct cxl_dev_state { u64 active_persistent_bytes; u64 next_volatile_bytes; u64 next_persistent_bytes; - - int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); }; - -enum cxl_opcode { - CXL_MBOX_OP_INVALID = 0x0000, - CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID, - CXL_MBOX_OP_GET_FW_INFO = 0x0200, - CXL_MBOX_OP_ACTIVATE_FW = 0x0202, - CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400, - CXL_MBOX_OP_GET_LOG = 0x0401, - CXL_MBOX_OP_IDENTIFY = 0x4000, - CXL_MBOX_OP_GET_PARTITION_INFO = 0x4100, - CXL_MBOX_OP_SET_PARTITION_INFO = 0x4101, - CXL_MBOX_OP_GET_LSA = 0x4102, - CXL_MBOX_OP_SET_LSA = 0x4103, - CXL_MBOX_OP_GET_HEALTH_INFO = 0x4200, - CXL_MBOX_OP_GET_ALERT_CONFIG = 0x4201, - CXL_MBOX_OP_SET_ALERT_CONFIG = 0x4202, - CXL_MBOX_OP_GET_SHUTDOWN_STATE = 0x4203, - CXL_MBOX_OP_SET_SHUTDOWN_STATE = 0x4204, - CXL_MBOX_OP_GET_POISON = 0x4300, - CXL_MBOX_OP_INJECT_POISON = 0x4301, - CXL_MBOX_OP_CLEAR_POISON = 0x4302, - CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303, - CXL_MBOX_OP_SCAN_MEDIA = 0x4304, - CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305, - CXL_MBOX_OP_MAX = 0x10000 -}; - -#define DEFINE_CXL_CEL_UUID \ - UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96, 0xb1, 0x62, \ - 0x3b, 0x3f, 0x17) - -#define DEFINE_CXL_VENDOR_DEBUG_UUID \ - UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6, 0x07, 0x19, \ - 0x40, 0x3d, 0x86) - -struct cxl_mbox_get_supported_logs { - __le16 entries; - u8 rsvd[6]; - struct cxl_gsl_entry { - uuid_t uuid; - __le32 size; - } __packed entry[]; -} __packed; - -struct cxl_cel_entry { - __le16 opcode; - __le16 effect; -} __packed; - -struct cxl_mbox_get_log { - uuid_t uuid; - __le32 offset; - __le32 length; -} __packed; - -/* See CXL 2.0 Table 175 Identify Memory Device Output Payload */ -struct cxl_mbox_identify { - char fw_revision[0x10]; - __le64 total_capacity; - __le64 volatile_capacity; - __le64 persistent_capacity; - __le64 partition_align; - __le16 info_event_log_size; - __le16 warning_event_log_size; - __le16 failure_event_log_size; - __le16 fatal_event_log_size; - __le32 lsa_size; - u8 poison_list_max_mer[3]; - __le16 inject_poison_limit; - u8 poison_caps; - u8 qos_telemetry_caps; -} __packed; - -struct cxl_mbox_get_lsa { - u32 offset; - u32 length; -} __packed; - -struct cxl_mbox_set_lsa { - u32 offset; - u32 reserved; - u8 data[]; -} __packed; - -/** - * struct cxl_mem_command - Driver representation of a memory device command - * @info: Command information as it exists for the UAPI - * @opcode: The actual bits used for the mailbox protocol - * @flags: Set of flags effecting driver behavior. - * - * * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag - * will be enabled by the driver regardless of what hardware may have - * advertised. - * - * The cxl_mem_command is the driver's internal representation of commands that - * are supported by the driver. Some of these commands may not be supported by - * the hardware. The driver will use @info to validate the fields passed in by - * the user then submit the @opcode to the hardware. - * - * See struct cxl_command_info. - */ -struct cxl_mem_command { - struct cxl_command_info info; - enum cxl_opcode opcode; - u32 flags; -#define CXL_CMD_FLAG_NONE 0 -#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0) -}; - -int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in, - size_t in_size, void *out, size_t out_size); -int cxl_dev_state_identify(struct cxl_dev_state *cxlds); -int cxl_enumerate_cmds(struct cxl_dev_state *cxlds); -int cxl_mem_create_range_info(struct cxl_dev_state *cxlds); -struct cxl_dev_state *cxl_dev_state_create(struct device *dev); -void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); -void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds); #endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 8dc91fd339..5444b5a7fd 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1,12 +1,17 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2020 Intel Corporation. All rights reserved. */ -#include +#include +#include +#include #include #include #include #include +#include +#include #include #include +#include #include "cxlmem.h" #include "pci.h" #include "cxl.h" @@ -16,59 +21,262 @@ * * This implements the PCI exclusive functionality for a CXL device as it is * defined by the Compute Express Link specification. CXL devices may surface - * certain functionality even if it isn't CXL enabled. While this driver is - * focused around the PCI specific aspects of a CXL device, it binds to the - * specific CXL memory device class code, and therefore the implementation of - * cxl_pci is focused around CXL memory devices. + * certain functionality even if it isn't CXL enabled. * * The driver has several responsibilities, mainly: * - Create the memX device and register on the CXL bus. * - Enumerate device's register interface and map them. - * - Registers nvdimm bridge device with cxl_core. - * - Registers a CXL mailbox with cxl_core. + * - Probe the device attributes to establish sysfs interface. + * - Provide an IOCTL interface to userspace to communicate with the device for + * things like firmware update. */ -#define cxl_doorbell_busy(cxlds) \ - (readl((cxlds)->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET) & \ +#define cxl_doorbell_busy(cxlm) \ + (readl((cxlm)->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET) & \ CXLDEV_MBOX_CTRL_DOORBELL) /* CXL 2.0 - 8.2.8.4 */ #define CXL_MAILBOX_TIMEOUT_MS (2 * HZ) -static int cxl_pci_mbox_wait_for_doorbell(struct cxl_dev_state *cxlds) +enum opcode { + CXL_MBOX_OP_INVALID = 0x0000, + CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID, + CXL_MBOX_OP_GET_FW_INFO = 0x0200, + CXL_MBOX_OP_ACTIVATE_FW = 0x0202, + CXL_MBOX_OP_GET_SUPPORTED_LOGS = 0x0400, + CXL_MBOX_OP_GET_LOG = 0x0401, + CXL_MBOX_OP_IDENTIFY = 0x4000, + CXL_MBOX_OP_GET_PARTITION_INFO = 0x4100, + CXL_MBOX_OP_SET_PARTITION_INFO = 0x4101, + CXL_MBOX_OP_GET_LSA = 0x4102, + CXL_MBOX_OP_SET_LSA = 0x4103, + CXL_MBOX_OP_GET_HEALTH_INFO = 0x4200, + CXL_MBOX_OP_GET_ALERT_CONFIG = 0x4201, + CXL_MBOX_OP_SET_ALERT_CONFIG = 0x4202, + CXL_MBOX_OP_GET_SHUTDOWN_STATE = 0x4203, + CXL_MBOX_OP_SET_SHUTDOWN_STATE = 0x4204, + CXL_MBOX_OP_GET_POISON = 0x4300, + CXL_MBOX_OP_INJECT_POISON = 0x4301, + CXL_MBOX_OP_CLEAR_POISON = 0x4302, + CXL_MBOX_OP_GET_SCAN_MEDIA_CAPS = 0x4303, + CXL_MBOX_OP_SCAN_MEDIA = 0x4304, + CXL_MBOX_OP_GET_SCAN_MEDIA = 0x4305, + CXL_MBOX_OP_MAX = 0x10000 +}; + +/* + * CXL 2.0 - Memory capacity multiplier + * See Section 8.2.9.5 + * + * Volatile, Persistent, and Partition capacities are specified to be in + * multiples of 256MB - define a multiplier to convert to/from bytes. + */ +#define CXL_CAPACITY_MULTIPLIER SZ_256M + +/** + * struct mbox_cmd - A command to be submitted to hardware. + * @opcode: (input) The command set and command submitted to hardware. + * @payload_in: (input) Pointer to the input payload. + * @payload_out: (output) Pointer to the output payload. Must be allocated by + * the caller. + * @size_in: (input) Number of bytes to load from @payload_in. + * @size_out: (input) Max number of bytes loaded into @payload_out. + * (output) Number of bytes generated by the device. For fixed size + * outputs commands this is always expected to be deterministic. For + * variable sized output commands, it tells the exact number of bytes + * written. + * @return_code: (output) Error code returned from hardware. + * + * This is the primary mechanism used to send commands to the hardware. + * All the fields except @payload_* correspond exactly to the fields described in + * Command Register section of the CXL 2.0 8.2.8.4.5. @payload_in and + * @payload_out are written to, and read from the Command Payload Registers + * defined in CXL 2.0 8.2.8.4.8. + */ +struct mbox_cmd { + u16 opcode; + void *payload_in; + void *payload_out; + size_t size_in; + size_t size_out; + u16 return_code; +#define CXL_MBOX_SUCCESS 0 +}; + +static DECLARE_RWSEM(cxl_memdev_rwsem); +static struct dentry *cxl_debugfs; +static bool cxl_raw_allow_all; + +enum { + CEL_UUID, + VENDOR_DEBUG_UUID, +}; + +/* See CXL 2.0 Table 170. Get Log Input Payload */ +static const uuid_t log_uuid[] = { + [CEL_UUID] = UUID_INIT(0xda9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79, 0x96, + 0xb1, 0x62, 0x3b, 0x3f, 0x17), + [VENDOR_DEBUG_UUID] = UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f, + 0xd6, 0x07, 0x19, 0x40, 0x3d, 0x86), +}; + +/** + * struct cxl_mem_command - Driver representation of a memory device command + * @info: Command information as it exists for the UAPI + * @opcode: The actual bits used for the mailbox protocol + * @flags: Set of flags effecting driver behavior. + * + * * %CXL_CMD_FLAG_FORCE_ENABLE: In cases of error, commands with this flag + * will be enabled by the driver regardless of what hardware may have + * advertised. + * + * The cxl_mem_command is the driver's internal representation of commands that + * are supported by the driver. Some of these commands may not be supported by + * the hardware. The driver will use @info to validate the fields passed in by + * the user then submit the @opcode to the hardware. + * + * See struct cxl_command_info. + */ +struct cxl_mem_command { + struct cxl_command_info info; + enum opcode opcode; + u32 flags; +#define CXL_CMD_FLAG_NONE 0 +#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0) +}; + +#define CXL_CMD(_id, sin, sout, _flags) \ + [CXL_MEM_COMMAND_ID_##_id] = { \ + .info = { \ + .id = CXL_MEM_COMMAND_ID_##_id, \ + .size_in = sin, \ + .size_out = sout, \ + }, \ + .opcode = CXL_MBOX_OP_##_id, \ + .flags = _flags, \ + } + +/* + * This table defines the supported mailbox commands for the driver. This table + * is made up of a UAPI structure. Non-negative values as parameters in the + * table will be validated against the user's input. For example, if size_in is + * 0, and the user passed in 1, it is an error. + */ +static struct cxl_mem_command mem_commands[CXL_MEM_COMMAND_ID_MAX] = { + CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE), +#ifdef CONFIG_CXL_MEM_RAW_COMMANDS + CXL_CMD(RAW, ~0, ~0, 0), +#endif + CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE), + CXL_CMD(GET_FW_INFO, 0, 0x50, 0), + CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0), + CXL_CMD(GET_LSA, 0x8, ~0, 0), + CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0), + CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE), + CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0), + CXL_CMD(SET_LSA, ~0, 0, 0), + CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0), + CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0), + CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0), + CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0), + CXL_CMD(GET_POISON, 0x10, ~0, 0), + CXL_CMD(INJECT_POISON, 0x8, 0, 0), + CXL_CMD(CLEAR_POISON, 0x48, 0, 0), + CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0), + CXL_CMD(SCAN_MEDIA, 0x11, 0, 0), + CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0), +}; + +/* + * Commands that RAW doesn't permit. The rationale for each: + * + * CXL_MBOX_OP_ACTIVATE_FW: Firmware activation requires adjustment / + * coordination of transaction timeout values at the root bridge level. + * + * CXL_MBOX_OP_SET_PARTITION_INFO: The device memory map may change live + * and needs to be coordinated with HDM updates. + * + * CXL_MBOX_OP_SET_LSA: The label storage area may be cached by the + * driver and any writes from userspace invalidates those contents. + * + * CXL_MBOX_OP_SET_SHUTDOWN_STATE: Set shutdown state assumes no writes + * to the device after it is marked clean, userspace can not make that + * assertion. + * + * CXL_MBOX_OP_[GET_]SCAN_MEDIA: The kernel provides a native error list that + * is kept up to date with patrol notifications and error management. + */ +static u16 cxl_disabled_raw_commands[] = { + CXL_MBOX_OP_ACTIVATE_FW, + CXL_MBOX_OP_SET_PARTITION_INFO, + CXL_MBOX_OP_SET_LSA, + CXL_MBOX_OP_SET_SHUTDOWN_STATE, + CXL_MBOX_OP_SCAN_MEDIA, + CXL_MBOX_OP_GET_SCAN_MEDIA, +}; + +/* + * Command sets that RAW doesn't permit. All opcodes in this set are + * disabled because they pass plain text security payloads over the + * user/kernel boundary. This functionality is intended to be wrapped + * behind the keys ABI which allows for encrypted payloads in the UAPI + */ +static u8 security_command_sets[] = { + 0x44, /* Sanitize */ + 0x45, /* Persistent Memory Data-at-rest Security */ + 0x46, /* Security Passthrough */ +}; + +#define cxl_for_each_cmd(cmd) \ + for ((cmd) = &mem_commands[0]; \ + ((cmd) - mem_commands) < ARRAY_SIZE(mem_commands); (cmd)++) + +#define cxl_cmd_count ARRAY_SIZE(mem_commands) + +static int cxl_mem_wait_for_doorbell(struct cxl_mem *cxlm) { const unsigned long start = jiffies; unsigned long end = start; - while (cxl_doorbell_busy(cxlds)) { + while (cxl_doorbell_busy(cxlm)) { end = jiffies; if (time_after(end, start + CXL_MAILBOX_TIMEOUT_MS)) { /* Check again in case preempted before timeout test */ - if (!cxl_doorbell_busy(cxlds)) + if (!cxl_doorbell_busy(cxlm)) break; return -ETIMEDOUT; } cpu_relax(); } - dev_dbg(cxlds->dev, "Doorbell wait took %dms", + dev_dbg(&cxlm->pdev->dev, "Doorbell wait took %dms", jiffies_to_msecs(end) - jiffies_to_msecs(start)); return 0; } -static void cxl_pci_mbox_timeout(struct cxl_dev_state *cxlds, - struct cxl_mbox_cmd *mbox_cmd) +static bool cxl_is_security_command(u16 opcode) { - struct device *dev = cxlds->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(security_command_sets); i++) + if (security_command_sets[i] == (opcode >> 8)) + return true; + return false; +} + +static void cxl_mem_mbox_timeout(struct cxl_mem *cxlm, + struct mbox_cmd *mbox_cmd) +{ + struct device *dev = &cxlm->pdev->dev; dev_dbg(dev, "Mailbox command (opcode: %#x size: %zub) timed out\n", mbox_cmd->opcode, mbox_cmd->size_in); } /** - * __cxl_pci_mbox_send_cmd() - Execute a mailbox command - * @cxlds: The device state to communicate with. + * __cxl_mem_mbox_send_cmd() - Execute a mailbox command + * @cxlm: The CXL memory device to communicate with. * @mbox_cmd: Command to send to the memory device. * * Context: Any context. Expects mbox_mutex to be held. @@ -88,16 +296,15 @@ static void cxl_pci_mbox_timeout(struct cxl_dev_state *cxlds, * not need to coordinate with each other. The driver only uses the primary * mailbox. */ -static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds, - struct cxl_mbox_cmd *mbox_cmd) +static int __cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, + struct mbox_cmd *mbox_cmd) { - void __iomem *payload = cxlds->regs.mbox + CXLDEV_MBOX_PAYLOAD_OFFSET; - struct device *dev = cxlds->dev; + void __iomem *payload = cxlm->regs.mbox + CXLDEV_MBOX_PAYLOAD_OFFSET; u64 cmd_reg, status_reg; size_t out_len; int rc; - lockdep_assert_held(&cxlds->mbox_mutex); + lockdep_assert_held(&cxlm->mbox_mutex); /* * Here are the steps from 8.2.8.4 of the CXL 2.0 spec. @@ -117,8 +324,9 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds, */ /* #1 */ - if (cxl_doorbell_busy(cxlds)) { - dev_err_ratelimited(dev, "Mailbox re-busy after acquiring\n"); + if (cxl_doorbell_busy(cxlm)) { + dev_err_ratelimited(&cxlm->pdev->dev, + "Mailbox re-busy after acquiring\n"); return -EBUSY; } @@ -134,32 +342,32 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds, } /* #2, #3 */ - writeq(cmd_reg, cxlds->regs.mbox + CXLDEV_MBOX_CMD_OFFSET); + writeq(cmd_reg, cxlm->regs.mbox + CXLDEV_MBOX_CMD_OFFSET); /* #4 */ - dev_dbg(dev, "Sending command\n"); + dev_dbg(&cxlm->pdev->dev, "Sending command\n"); writel(CXLDEV_MBOX_CTRL_DOORBELL, - cxlds->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); + cxlm->regs.mbox + CXLDEV_MBOX_CTRL_OFFSET); /* #5 */ - rc = cxl_pci_mbox_wait_for_doorbell(cxlds); + rc = cxl_mem_wait_for_doorbell(cxlm); if (rc == -ETIMEDOUT) { - cxl_pci_mbox_timeout(cxlds, mbox_cmd); + cxl_mem_mbox_timeout(cxlm, mbox_cmd); return rc; } /* #6 */ - status_reg = readq(cxlds->regs.mbox + CXLDEV_MBOX_STATUS_OFFSET); + status_reg = readq(cxlm->regs.mbox + CXLDEV_MBOX_STATUS_OFFSET); mbox_cmd->return_code = FIELD_GET(CXLDEV_MBOX_STATUS_RET_CODE_MASK, status_reg); if (mbox_cmd->return_code != 0) { - dev_dbg(dev, "Mailbox operation had an error\n"); + dev_dbg(&cxlm->pdev->dev, "Mailbox operation had an error\n"); return 0; } /* #7 */ - cmd_reg = readq(cxlds->regs.mbox + CXLDEV_MBOX_CMD_OFFSET); + cmd_reg = readq(cxlm->regs.mbox + CXLDEV_MBOX_CMD_OFFSET); out_len = FIELD_GET(CXLDEV_MBOX_CMD_PAYLOAD_LENGTH_MASK, cmd_reg); /* #8 */ @@ -171,7 +379,7 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds, * have requested less data than the hardware supplied even * within spec. */ - size_t n = min3(mbox_cmd->size_out, cxlds->payload_size, out_len); + size_t n = min3(mbox_cmd->size_out, cxlm->payload_size, out_len); memcpy_fromio(mbox_cmd->payload_out, payload, n); mbox_cmd->size_out = n; @@ -183,19 +391,19 @@ static int __cxl_pci_mbox_send_cmd(struct cxl_dev_state *cxlds, } /** - * cxl_pci_mbox_get() - Acquire exclusive access to the mailbox. - * @cxlds: The device state to gain access to. + * cxl_mem_mbox_get() - Acquire exclusive access to the mailbox. + * @cxlm: The memory device to gain access to. * * Context: Any context. Takes the mbox_mutex. * Return: 0 if exclusive access was acquired. */ -static int cxl_pci_mbox_get(struct cxl_dev_state *cxlds) +static int cxl_mem_mbox_get(struct cxl_mem *cxlm) { - struct device *dev = cxlds->dev; + struct device *dev = &cxlm->pdev->dev; u64 md_status; int rc; - mutex_lock_io(&cxlds->mbox_mutex); + mutex_lock_io(&cxlm->mbox_mutex); /* * XXX: There is some amount of ambiguity in the 2.0 version of the spec @@ -214,13 +422,13 @@ static int cxl_pci_mbox_get(struct cxl_dev_state *cxlds) * Mailbox Interface Ready bit. Therefore, waiting for the doorbell * to be ready is sufficient. */ - rc = cxl_pci_mbox_wait_for_doorbell(cxlds); + rc = cxl_mem_wait_for_doorbell(cxlm); if (rc) { dev_warn(dev, "Mailbox interface not ready\n"); goto out; } - md_status = readq(cxlds->regs.memdev + CXLMDEV_STATUS_OFFSET); + md_status = readq(cxlm->regs.memdev + CXLMDEV_STATUS_OFFSET); if (!(md_status & CXLMDEV_MBOX_IF_READY && CXLMDEV_READY(md_status))) { dev_err(dev, "mbox: reported doorbell ready, but not mbox ready\n"); rc = -EBUSY; @@ -249,41 +457,463 @@ static int cxl_pci_mbox_get(struct cxl_dev_state *cxlds) return 0; out: - mutex_unlock(&cxlds->mbox_mutex); + mutex_unlock(&cxlm->mbox_mutex); return rc; } /** - * cxl_pci_mbox_put() - Release exclusive access to the mailbox. - * @cxlds: The device state to communicate with. + * cxl_mem_mbox_put() - Release exclusive access to the mailbox. + * @cxlm: The CXL memory device to communicate with. * * Context: Any context. Expects mbox_mutex to be held. */ -static void cxl_pci_mbox_put(struct cxl_dev_state *cxlds) +static void cxl_mem_mbox_put(struct cxl_mem *cxlm) { - mutex_unlock(&cxlds->mbox_mutex); + mutex_unlock(&cxlm->mbox_mutex); } -static int cxl_pci_mbox_send(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd) +/** + * handle_mailbox_cmd_from_user() - Dispatch a mailbox command for userspace. + * @cxlm: The CXL memory device to communicate with. + * @cmd: The validated command. + * @in_payload: Pointer to userspace's input payload. + * @out_payload: Pointer to userspace's output payload. + * @size_out: (Input) Max payload size to copy out. + * (Output) Payload size hardware generated. + * @retval: Hardware generated return code from the operation. + * + * Return: + * * %0 - Mailbox transaction succeeded. This implies the mailbox + * protocol completed successfully not that the operation itself + * was successful. + * * %-ENOMEM - Couldn't allocate a bounce buffer. + * * %-EFAULT - Something happened with copy_to/from_user. + * * %-EINTR - Mailbox acquisition interrupted. + * * %-EXXX - Transaction level failures. + * + * Creates the appropriate mailbox command and dispatches it on behalf of a + * userspace request. The input and output payloads are copied between + * userspace. + * + * See cxl_send_cmd(). + */ +static int handle_mailbox_cmd_from_user(struct cxl_mem *cxlm, + const struct cxl_mem_command *cmd, + u64 in_payload, u64 out_payload, + s32 *size_out, u32 *retval) { + struct device *dev = &cxlm->pdev->dev; + struct mbox_cmd mbox_cmd = { + .opcode = cmd->opcode, + .size_in = cmd->info.size_in, + .size_out = cmd->info.size_out, + }; int rc; - rc = cxl_pci_mbox_get(cxlds); + if (cmd->info.size_out) { + mbox_cmd.payload_out = kvzalloc(cmd->info.size_out, GFP_KERNEL); + if (!mbox_cmd.payload_out) + return -ENOMEM; + } + + if (cmd->info.size_in) { + mbox_cmd.payload_in = vmemdup_user(u64_to_user_ptr(in_payload), + cmd->info.size_in); + if (IS_ERR(mbox_cmd.payload_in)) { + kvfree(mbox_cmd.payload_out); + return PTR_ERR(mbox_cmd.payload_in); + } + } + + rc = cxl_mem_mbox_get(cxlm); + if (rc) + goto out; + + dev_dbg(dev, + "Submitting %s command for user\n" + "\topcode: %x\n" + "\tsize: %ub\n", + cxl_command_names[cmd->info.id].name, mbox_cmd.opcode, + cmd->info.size_in); + + dev_WARN_ONCE(dev, cmd->info.id == CXL_MEM_COMMAND_ID_RAW, + "raw command path used\n"); + + rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd); + cxl_mem_mbox_put(cxlm); + if (rc) + goto out; + + /* + * @size_out contains the max size that's allowed to be written back out + * to userspace. While the payload may have written more output than + * this it will have to be ignored. + */ + if (mbox_cmd.size_out) { + dev_WARN_ONCE(dev, mbox_cmd.size_out > *size_out, + "Invalid return size\n"); + if (copy_to_user(u64_to_user_ptr(out_payload), + mbox_cmd.payload_out, mbox_cmd.size_out)) { + rc = -EFAULT; + goto out; + } + } + + *size_out = mbox_cmd.size_out; + *retval = mbox_cmd.return_code; + +out: + kvfree(mbox_cmd.payload_in); + kvfree(mbox_cmd.payload_out); + return rc; +} + +static bool cxl_mem_raw_command_allowed(u16 opcode) +{ + int i; + + if (!IS_ENABLED(CONFIG_CXL_MEM_RAW_COMMANDS)) + return false; + + if (security_locked_down(LOCKDOWN_PCI_ACCESS)) + return false; + + if (cxl_raw_allow_all) + return true; + + if (cxl_is_security_command(opcode)) + return false; + + for (i = 0; i < ARRAY_SIZE(cxl_disabled_raw_commands); i++) + if (cxl_disabled_raw_commands[i] == opcode) + return false; + + return true; +} + +/** + * cxl_validate_cmd_from_user() - Check fields for CXL_MEM_SEND_COMMAND. + * @cxlm: &struct cxl_mem device whose mailbox will be used. + * @send_cmd: &struct cxl_send_command copied in from userspace. + * @out_cmd: Sanitized and populated &struct cxl_mem_command. + * + * Return: + * * %0 - @out_cmd is ready to send. + * * %-ENOTTY - Invalid command specified. + * * %-EINVAL - Reserved fields or invalid values were used. + * * %-ENOMEM - Input or output buffer wasn't sized properly. + * * %-EPERM - Attempted to use a protected command. + * + * The result of this command is a fully validated command in @out_cmd that is + * safe to send to the hardware. + * + * See handle_mailbox_cmd_from_user() + */ +static int cxl_validate_cmd_from_user(struct cxl_mem *cxlm, + const struct cxl_send_command *send_cmd, + struct cxl_mem_command *out_cmd) +{ + const struct cxl_command_info *info; + struct cxl_mem_command *c; + + if (send_cmd->id == 0 || send_cmd->id >= CXL_MEM_COMMAND_ID_MAX) + return -ENOTTY; + + /* + * The user can never specify an input payload larger than what hardware + * supports, but output can be arbitrarily large (simply write out as + * much data as the hardware provides). + */ + if (send_cmd->in.size > cxlm->payload_size) + return -EINVAL; + + /* + * Checks are bypassed for raw commands but a WARN/taint will occur + * later in the callchain + */ + if (send_cmd->id == CXL_MEM_COMMAND_ID_RAW) { + const struct cxl_mem_command temp = { + .info = { + .id = CXL_MEM_COMMAND_ID_RAW, + .flags = 0, + .size_in = send_cmd->in.size, + .size_out = send_cmd->out.size, + }, + .opcode = send_cmd->raw.opcode + }; + + if (send_cmd->raw.rsvd) + return -EINVAL; + + /* + * Unlike supported commands, the output size of RAW commands + * gets passed along without further checking, so it must be + * validated here. + */ + if (send_cmd->out.size > cxlm->payload_size) + return -EINVAL; + + if (!cxl_mem_raw_command_allowed(send_cmd->raw.opcode)) + return -EPERM; + + memcpy(out_cmd, &temp, sizeof(temp)); + + return 0; + } + + if (send_cmd->flags & ~CXL_MEM_COMMAND_FLAG_MASK) + return -EINVAL; + + if (send_cmd->rsvd) + return -EINVAL; + + if (send_cmd->in.rsvd || send_cmd->out.rsvd) + return -EINVAL; + + /* Convert user's command into the internal representation */ + c = &mem_commands[send_cmd->id]; + info = &c->info; + + /* Check that the command is enabled for hardware */ + if (!test_bit(info->id, cxlm->enabled_cmds)) + return -ENOTTY; + + /* Check the input buffer is the expected size */ + if (info->size_in >= 0 && info->size_in != send_cmd->in.size) + return -ENOMEM; + + /* Check the output buffer is at least large enough */ + if (info->size_out >= 0 && send_cmd->out.size < info->size_out) + return -ENOMEM; + + memcpy(out_cmd, c, sizeof(*c)); + out_cmd->info.size_in = send_cmd->in.size; + /* + * XXX: out_cmd->info.size_out will be controlled by the driver, and the + * specified number of bytes @send_cmd->out.size will be copied back out + * to userspace. + */ + + return 0; +} + +static int cxl_query_cmd(struct cxl_memdev *cxlmd, + struct cxl_mem_query_commands __user *q) +{ + struct device *dev = &cxlmd->dev; + struct cxl_mem_command *cmd; + u32 n_commands; + int j = 0; + + dev_dbg(dev, "Query IOCTL\n"); + + if (get_user(n_commands, &q->n_commands)) + return -EFAULT; + + /* returns the total number if 0 elements are requested. */ + if (n_commands == 0) + return put_user(cxl_cmd_count, &q->n_commands); + + /* + * otherwise, return max(n_commands, total commands) cxl_command_info + * structures. + */ + cxl_for_each_cmd(cmd) { + const struct cxl_command_info *info = &cmd->info; + + if (copy_to_user(&q->commands[j++], info, sizeof(*info))) + return -EFAULT; + + if (j == n_commands) + break; + } + + return 0; +} + +static int cxl_send_cmd(struct cxl_memdev *cxlmd, + struct cxl_send_command __user *s) +{ + struct cxl_mem *cxlm = cxlmd->cxlm; + struct device *dev = &cxlmd->dev; + struct cxl_send_command send; + struct cxl_mem_command c; + int rc; + + dev_dbg(dev, "Send IOCTL\n"); + + if (copy_from_user(&send, s, sizeof(send))) + return -EFAULT; + + rc = cxl_validate_cmd_from_user(cxlmd->cxlm, &send, &c); if (rc) return rc; - rc = __cxl_pci_mbox_send_cmd(cxlds, cmd); - cxl_pci_mbox_put(cxlds); + /* Prepare to handle a full payload for variable sized output */ + if (c.info.size_out < 0) + c.info.size_out = cxlm->payload_size; + + rc = handle_mailbox_cmd_from_user(cxlm, &c, send.in.payload, + send.out.payload, &send.out.size, + &send.retval); + if (rc) + return rc; + + if (copy_to_user(s, &send, sizeof(send))) + return -EFAULT; + + return 0; +} + +static long __cxl_memdev_ioctl(struct cxl_memdev *cxlmd, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case CXL_MEM_QUERY_COMMANDS: + return cxl_query_cmd(cxlmd, (void __user *)arg); + case CXL_MEM_SEND_COMMAND: + return cxl_send_cmd(cxlmd, (void __user *)arg); + default: + return -ENOTTY; + } +} + +static long cxl_memdev_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct cxl_memdev *cxlmd = file->private_data; + int rc = -ENXIO; + + down_read(&cxl_memdev_rwsem); + if (cxlmd->cxlm) + rc = __cxl_memdev_ioctl(cxlmd, cmd, arg); + up_read(&cxl_memdev_rwsem); return rc; } -static int cxl_pci_setup_mailbox(struct cxl_dev_state *cxlds) +static int cxl_memdev_open(struct inode *inode, struct file *file) { - const int cap = readl(cxlds->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET); + struct cxl_memdev *cxlmd = + container_of(inode->i_cdev, typeof(*cxlmd), cdev); - cxlds->mbox_send = cxl_pci_mbox_send; - cxlds->payload_size = + get_device(&cxlmd->dev); + file->private_data = cxlmd; + + return 0; +} + +static int cxl_memdev_release_file(struct inode *inode, struct file *file) +{ + struct cxl_memdev *cxlmd = + container_of(inode->i_cdev, typeof(*cxlmd), cdev); + + put_device(&cxlmd->dev); + + return 0; +} + +static void cxl_memdev_shutdown(struct device *dev) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + + down_write(&cxl_memdev_rwsem); + cxlmd->cxlm = NULL; + up_write(&cxl_memdev_rwsem); +} + +static const struct cdevm_file_operations cxl_memdev_fops = { + .fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = cxl_memdev_ioctl, + .open = cxl_memdev_open, + .release = cxl_memdev_release_file, + .compat_ioctl = compat_ptr_ioctl, + .llseek = noop_llseek, + }, + .shutdown = cxl_memdev_shutdown, +}; + +static inline struct cxl_mem_command *cxl_mem_find_command(u16 opcode) +{ + struct cxl_mem_command *c; + + cxl_for_each_cmd(c) + if (c->opcode == opcode) + return c; + + return NULL; +} + +/** + * cxl_mem_mbox_send_cmd() - Send a mailbox command to a memory device. + * @cxlm: The CXL memory device to communicate with. + * @opcode: Opcode for the mailbox command. + * @in: The input payload for the mailbox command. + * @in_size: The length of the input payload + * @out: Caller allocated buffer for the output. + * @out_size: Expected size of output. + * + * Context: Any context. Will acquire and release mbox_mutex. + * Return: + * * %>=0 - Number of bytes returned in @out. + * * %-E2BIG - Payload is too large for hardware. + * * %-EBUSY - Couldn't acquire exclusive mailbox access. + * * %-EFAULT - Hardware error occurred. + * * %-ENXIO - Command completed, but device reported an error. + * * %-EIO - Unexpected output size. + * + * Mailbox commands may execute successfully yet the device itself reported an + * error. While this distinction can be useful for commands from userspace, the + * kernel will only be able to use results when both are successful. + * + * See __cxl_mem_mbox_send_cmd() + */ +static int cxl_mem_mbox_send_cmd(struct cxl_mem *cxlm, u16 opcode, + void *in, size_t in_size, + void *out, size_t out_size) +{ + const struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); + struct mbox_cmd mbox_cmd = { + .opcode = opcode, + .payload_in = in, + .size_in = in_size, + .size_out = out_size, + .payload_out = out, + }; + int rc; + + if (out_size > cxlm->payload_size) + return -E2BIG; + + rc = cxl_mem_mbox_get(cxlm); + if (rc) + return rc; + + rc = __cxl_mem_mbox_send_cmd(cxlm, &mbox_cmd); + cxl_mem_mbox_put(cxlm); + if (rc) + return rc; + + /* TODO: Map return code to proper kernel style errno */ + if (mbox_cmd.return_code != CXL_MBOX_SUCCESS) + return -ENXIO; + + /* + * Variable sized commands can't be validated and so it's up to the + * caller to do that if they wish. + */ + if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size) + return -EIO; + + return 0; +} + +static int cxl_mem_setup_mailbox(struct cxl_mem *cxlm) +{ + const int cap = readl(cxlm->regs.mbox + CXLDEV_MBOX_CAPS_OFFSET); + + cxlm->payload_size = 1 << FIELD_GET(CXLDEV_MBOX_CAP_PAYLOAD_SIZE_MASK, cap); /* @@ -293,59 +923,105 @@ static int cxl_pci_setup_mailbox(struct cxl_dev_state *cxlds) * there's no point in going forward. If the size is too large, there's * no harm is soft limiting it. */ - cxlds->payload_size = min_t(size_t, cxlds->payload_size, SZ_1M); - if (cxlds->payload_size < 256) { - dev_err(cxlds->dev, "Mailbox is too small (%zub)", - cxlds->payload_size); + cxlm->payload_size = min_t(size_t, cxlm->payload_size, SZ_1M); + if (cxlm->payload_size < 256) { + dev_err(&cxlm->pdev->dev, "Mailbox is too small (%zub)", + cxlm->payload_size); return -ENXIO; } - dev_dbg(cxlds->dev, "Mailbox payload sized %zu", - cxlds->payload_size); + dev_dbg(&cxlm->pdev->dev, "Mailbox payload sized %zu", + cxlm->payload_size); return 0; } -static int cxl_map_regblock(struct pci_dev *pdev, struct cxl_register_map *map) +static struct cxl_mem *cxl_mem_create(struct pci_dev *pdev) { - void __iomem *addr; - int bar = map->barno; struct device *dev = &pdev->dev; - resource_size_t offset = map->block_offset; + struct cxl_mem *cxlm; + + cxlm = devm_kzalloc(dev, sizeof(*cxlm), GFP_KERNEL); + if (!cxlm) { + dev_err(dev, "No memory available\n"); + return ERR_PTR(-ENOMEM); + } + + mutex_init(&cxlm->mbox_mutex); + cxlm->pdev = pdev; + cxlm->enabled_cmds = + devm_kmalloc_array(dev, BITS_TO_LONGS(cxl_cmd_count), + sizeof(unsigned long), + GFP_KERNEL | __GFP_ZERO); + if (!cxlm->enabled_cmds) { + dev_err(dev, "No memory available for bitmap\n"); + return ERR_PTR(-ENOMEM); + } + + return cxlm; +} + +static void __iomem *cxl_mem_map_regblock(struct cxl_mem *cxlm, + u8 bar, u64 offset) +{ + struct pci_dev *pdev = cxlm->pdev; + struct device *dev = &pdev->dev; + void __iomem *addr; /* Basic sanity check that BAR is big enough */ if (pci_resource_len(pdev, bar) < offset) { - dev_err(dev, "BAR%d: %pr: too small (offset: %pa)\n", bar, - &pdev->resource[bar], &offset); - return -ENXIO; + dev_err(dev, "BAR%d: %pr: too small (offset: %#llx)\n", bar, + &pdev->resource[bar], (unsigned long long)offset); + return NULL; } addr = pci_iomap(pdev, bar, 0); if (!addr) { dev_err(dev, "failed to map registers\n"); - return -ENOMEM; + return addr; } - dev_dbg(dev, "Mapped CXL Memory Device resource bar %u @ %pa\n", - bar, &offset); + dev_dbg(dev, "Mapped CXL Memory Device resource bar %u @ %#llx\n", + bar, offset); + + return addr; +} + +static void cxl_mem_unmap_regblock(struct cxl_mem *cxlm, void __iomem *base) +{ + pci_iounmap(cxlm->pdev, base); +} + +static int cxl_mem_dvsec(struct pci_dev *pdev, int dvsec) +{ + int pos; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DVSEC); + if (!pos) + return 0; + + while (pos) { + u16 vendor, id; + + pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER1, &vendor); + pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER2, &id); + if (vendor == PCI_DVSEC_VENDOR_ID_CXL && dvsec == id) + return pos; + + pos = pci_find_next_ext_capability(pdev, pos, + PCI_EXT_CAP_ID_DVSEC); + } - map->base = addr + map->block_offset; return 0; } -static void cxl_unmap_regblock(struct pci_dev *pdev, - struct cxl_register_map *map) -{ - pci_iounmap(pdev, map->base - map->block_offset); - map->base = NULL; -} - -static int cxl_probe_regs(struct pci_dev *pdev, struct cxl_register_map *map) +static int cxl_probe_regs(struct cxl_mem *cxlm, void __iomem *base, + struct cxl_register_map *map) { + struct pci_dev *pdev = cxlm->pdev; + struct device *dev = &pdev->dev; struct cxl_component_reg_map *comp_map; struct cxl_device_reg_map *dev_map; - struct device *dev = &pdev->dev; - void __iomem *base = map->base; switch (map->reg_type) { case CXL_REGLOC_RBI_COMPONENT: @@ -379,18 +1055,18 @@ static int cxl_probe_regs(struct pci_dev *pdev, struct cxl_register_map *map) return 0; } -static int cxl_map_regs(struct cxl_dev_state *cxlds, struct cxl_register_map *map) +static int cxl_map_regs(struct cxl_mem *cxlm, struct cxl_register_map *map) { - struct device *dev = cxlds->dev; - struct pci_dev *pdev = to_pci_dev(dev); + struct pci_dev *pdev = cxlm->pdev; + struct device *dev = &pdev->dev; switch (map->reg_type) { case CXL_REGLOC_RBI_COMPONENT: - cxl_map_component_regs(pdev, &cxlds->regs.component, map); + cxl_map_component_regs(pdev, &cxlm->regs.component, map); dev_dbg(dev, "Mapping component registers...\n"); break; case CXL_REGLOC_RBI_MEMDEV: - cxl_map_device_regs(pdev, &cxlds->regs.device_regs, map); + cxl_map_device_regs(pdev, &cxlm->regs.device_regs, map); dev_dbg(dev, "Probing device registers...\n"); break; default: @@ -400,128 +1076,446 @@ static int cxl_map_regs(struct cxl_dev_state *cxlds, struct cxl_register_map *ma return 0; } -static void cxl_decode_regblock(u32 reg_lo, u32 reg_hi, - struct cxl_register_map *map) +static void cxl_decode_register_block(u32 reg_lo, u32 reg_hi, + u8 *bar, u64 *offset, u8 *reg_type) { - map->block_offset = - ((u64)reg_hi << 32) | (reg_lo & CXL_REGLOC_ADDR_MASK); - map->barno = FIELD_GET(CXL_REGLOC_BIR_MASK, reg_lo); - map->reg_type = FIELD_GET(CXL_REGLOC_RBI_MASK, reg_lo); + *offset = ((u64)reg_hi << 32) | (reg_lo & CXL_REGLOC_ADDR_MASK); + *bar = FIELD_GET(CXL_REGLOC_BIR_MASK, reg_lo); + *reg_type = FIELD_GET(CXL_REGLOC_RBI_MASK, reg_lo); } /** - * cxl_find_regblock() - Locate register blocks by type - * @pdev: The CXL PCI device to enumerate. - * @type: Register Block Indicator id - * @map: Enumeration output, clobbered on error + * cxl_mem_setup_regs() - Setup necessary MMIO. + * @cxlm: The CXL memory device to communicate with. * - * Return: 0 if register block enumerated, negative error code otherwise + * Return: 0 if all necessary registers mapped. * - * A CXL DVSEC may point to one or more register blocks, search for them - * by @type. + * A memory device is required by spec to implement a certain set of MMIO + * regions. The purpose of this function is to enumerate and map those + * registers. */ -static int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, - struct cxl_register_map *map) +static int cxl_mem_setup_regs(struct cxl_mem *cxlm) { + struct pci_dev *pdev = cxlm->pdev; + struct device *dev = &pdev->dev; u32 regloc_size, regblocks; - int regloc, i; + void __iomem *base; + int regloc, i, n_maps; + struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES]; + int ret = 0; - regloc = pci_find_dvsec_capability(pdev, PCI_DVSEC_VENDOR_ID_CXL, - PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID); - if (!regloc) + regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID); + if (!regloc) { + dev_err(dev, "register location dvsec not found\n"); return -ENXIO; + } + if (pci_request_mem_regions(pdev, pci_name(pdev))) + return -ENODEV; + + /* Get the size of the Register Locator DVSEC */ pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, ®loc_size); regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size); regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET; regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8; - for (i = 0; i < regblocks; i++, regloc += 8) { + for (i = 0, n_maps = 0; i < regblocks; i++, regloc += 8) { u32 reg_lo, reg_hi; + u8 reg_type; + u64 offset; + u8 bar; pci_read_config_dword(pdev, regloc, ®_lo); pci_read_config_dword(pdev, regloc + 4, ®_hi); - cxl_decode_regblock(reg_lo, reg_hi, map); + cxl_decode_register_block(reg_lo, reg_hi, &bar, &offset, + ®_type); - if (map->reg_type == type) - return 0; + dev_dbg(dev, "Found register block in bar %u @ 0x%llx of type %u\n", + bar, offset, reg_type); + + /* Ignore unknown register block types */ + if (reg_type > CXL_REGLOC_RBI_MEMDEV) + continue; + + base = cxl_mem_map_regblock(cxlm, bar, offset); + if (!base) + return -ENOMEM; + + map = &maps[n_maps]; + map->barno = bar; + map->block_offset = offset; + map->reg_type = reg_type; + + ret = cxl_probe_regs(cxlm, base + offset, map); + + /* Always unmap the regblock regardless of probe success */ + cxl_mem_unmap_regblock(cxlm, base); + + if (ret) + return ret; + + n_maps++; } - return -ENODEV; + pci_release_mem_regions(pdev); + + for (i = 0; i < n_maps; i++) { + ret = cxl_map_regs(cxlm, &maps[i]); + if (ret) + break; + } + + return ret; } -static int cxl_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, - struct cxl_register_map *map) +static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out) { + u32 remaining = size; + u32 offset = 0; + + while (remaining) { + u32 xfer_size = min_t(u32, remaining, cxlm->payload_size); + struct cxl_mbox_get_log { + uuid_t uuid; + __le32 offset; + __le32 length; + } __packed log = { + .uuid = *uuid, + .offset = cpu_to_le32(offset), + .length = cpu_to_le32(xfer_size) + }; + int rc; + + rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_LOG, &log, + sizeof(log), out, xfer_size); + if (rc < 0) + return rc; + + out += xfer_size; + remaining -= xfer_size; + offset += xfer_size; + } + + return 0; +} + +/** + * cxl_walk_cel() - Walk through the Command Effects Log. + * @cxlm: Device. + * @size: Length of the Command Effects Log. + * @cel: CEL + * + * Iterate over each entry in the CEL and determine if the driver supports the + * command. If so, the command is enabled for the device and can be used later. + */ +static void cxl_walk_cel(struct cxl_mem *cxlm, size_t size, u8 *cel) +{ + struct cel_entry { + __le16 opcode; + __le16 effect; + } __packed * cel_entry; + const int cel_entries = size / sizeof(*cel_entry); + int i; + + cel_entry = (struct cel_entry *)cel; + + for (i = 0; i < cel_entries; i++) { + u16 opcode = le16_to_cpu(cel_entry[i].opcode); + struct cxl_mem_command *cmd = cxl_mem_find_command(opcode); + + if (!cmd) { + dev_dbg(&cxlm->pdev->dev, + "Opcode 0x%04x unsupported by driver", opcode); + continue; + } + + set_bit(cmd->info.id, cxlm->enabled_cmds); + } +} + +struct cxl_mbox_get_supported_logs { + __le16 entries; + u8 rsvd[6]; + struct gsl_entry { + uuid_t uuid; + __le32 size; + } __packed entry[]; +} __packed; + +static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm) +{ + struct cxl_mbox_get_supported_logs *ret; int rc; - rc = cxl_find_regblock(pdev, type, map); + ret = kvmalloc(cxlm->payload_size, GFP_KERNEL); + if (!ret) + return ERR_PTR(-ENOMEM); + + rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_SUPPORTED_LOGS, NULL, + 0, ret, cxlm->payload_size); + if (rc < 0) { + kvfree(ret); + return ERR_PTR(rc); + } + + return ret; +} + +/** + * cxl_mem_get_partition_info - Get partition info + * @cxlm: The device to act on + * @active_volatile_bytes: returned active volatile capacity + * @active_persistent_bytes: returned active persistent capacity + * @next_volatile_bytes: return next volatile capacity + * @next_persistent_bytes: return next persistent capacity + * + * Retrieve the current partition info for the device specified. If not 0, the + * 'next' values are pending and take affect on next cold reset. + * + * Return: 0 if no error: or the result of the mailbox command. + * + * See CXL @8.2.9.5.2.1 Get Partition Info + */ +static int cxl_mem_get_partition_info(struct cxl_mem *cxlm, + u64 *active_volatile_bytes, + u64 *active_persistent_bytes, + u64 *next_volatile_bytes, + u64 *next_persistent_bytes) +{ + struct cxl_mbox_get_partition_info { + __le64 active_volatile_cap; + __le64 active_persistent_cap; + __le64 next_volatile_cap; + __le64 next_persistent_cap; + } __packed pi; + int rc; + + rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO, + NULL, 0, &pi, sizeof(pi)); if (rc) return rc; - rc = cxl_map_regblock(pdev, map); - if (rc) - return rc; + *active_volatile_bytes = le64_to_cpu(pi.active_volatile_cap); + *active_persistent_bytes = le64_to_cpu(pi.active_persistent_cap); + *next_volatile_bytes = le64_to_cpu(pi.next_volatile_cap); + *next_persistent_bytes = le64_to_cpu(pi.next_volatile_cap); - rc = cxl_probe_regs(pdev, map); - cxl_unmap_regblock(pdev, map); + *active_volatile_bytes *= CXL_CAPACITY_MULTIPLIER; + *active_persistent_bytes *= CXL_CAPACITY_MULTIPLIER; + *next_volatile_bytes *= CXL_CAPACITY_MULTIPLIER; + *next_persistent_bytes *= CXL_CAPACITY_MULTIPLIER; + return 0; +} + +/** + * cxl_mem_enumerate_cmds() - Enumerate commands for a device. + * @cxlm: The device. + * + * Returns 0 if enumerate completed successfully. + * + * CXL devices have optional support for certain commands. This function will + * determine the set of supported commands for the hardware and update the + * enabled_cmds bitmap in the @cxlm. + */ +static int cxl_mem_enumerate_cmds(struct cxl_mem *cxlm) +{ + struct cxl_mbox_get_supported_logs *gsl; + struct device *dev = &cxlm->pdev->dev; + struct cxl_mem_command *cmd; + int i, rc; + + gsl = cxl_get_gsl(cxlm); + if (IS_ERR(gsl)) + return PTR_ERR(gsl); + + rc = -ENOENT; + for (i = 0; i < le16_to_cpu(gsl->entries); i++) { + u32 size = le32_to_cpu(gsl->entry[i].size); + uuid_t uuid = gsl->entry[i].uuid; + u8 *log; + + dev_dbg(dev, "Found LOG type %pU of size %d", &uuid, size); + + if (!uuid_equal(&uuid, &log_uuid[CEL_UUID])) + continue; + + log = kvmalloc(size, GFP_KERNEL); + if (!log) { + rc = -ENOMEM; + goto out; + } + + rc = cxl_xfer_log(cxlm, &uuid, size, log); + if (rc) { + kvfree(log); + goto out; + } + + cxl_walk_cel(cxlm, size, log); + kvfree(log); + + /* In case CEL was bogus, enable some default commands. */ + cxl_for_each_cmd(cmd) + if (cmd->flags & CXL_CMD_FLAG_FORCE_ENABLE) + set_bit(cmd->info.id, cxlm->enabled_cmds); + + /* Found the required CEL */ + rc = 0; + } + +out: + kvfree(gsl); return rc; } -static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +/** + * cxl_mem_identify() - Send the IDENTIFY command to the device. + * @cxlm: The device to identify. + * + * Return: 0 if identify was executed successfully. + * + * This will dispatch the identify command to the device and on success populate + * structures to be exported to sysfs. + */ +static int cxl_mem_identify(struct cxl_mem *cxlm) { - struct cxl_register_map map; - struct cxl_memdev *cxlmd; - struct cxl_dev_state *cxlds; + /* See CXL 2.0 Table 175 Identify Memory Device Output Payload */ + struct cxl_mbox_identify { + char fw_revision[0x10]; + __le64 total_capacity; + __le64 volatile_capacity; + __le64 persistent_capacity; + __le64 partition_align; + __le16 info_event_log_size; + __le16 warning_event_log_size; + __le16 failure_event_log_size; + __le16 fatal_event_log_size; + __le32 lsa_size; + u8 poison_list_max_mer[3]; + __le16 inject_poison_limit; + u8 poison_caps; + u8 qos_telemetry_caps; + } __packed id; int rc; - /* - * Double check the anonymous union trickery in struct cxl_regs - * FIXME switch to struct_group() - */ - BUILD_BUG_ON(offsetof(struct cxl_regs, memdev) != - offsetof(struct cxl_regs, device_regs.memdev)); + rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_IDENTIFY, NULL, 0, &id, + sizeof(id)); + if (rc < 0) + return rc; + + cxlm->total_bytes = le64_to_cpu(id.total_capacity); + cxlm->total_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->volatile_only_bytes = le64_to_cpu(id.volatile_capacity); + cxlm->volatile_only_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->persistent_only_bytes = le64_to_cpu(id.persistent_capacity); + cxlm->persistent_only_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->partition_align_bytes = le64_to_cpu(id.partition_align); + cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER; + + dev_dbg(&cxlm->pdev->dev, "Identify Memory Device\n" + " total_bytes = %#llx\n" + " volatile_only_bytes = %#llx\n" + " persistent_only_bytes = %#llx\n" + " partition_align_bytes = %#llx\n", + cxlm->total_bytes, + cxlm->volatile_only_bytes, + cxlm->persistent_only_bytes, + cxlm->partition_align_bytes); + + cxlm->lsa_size = le32_to_cpu(id.lsa_size); + memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision)); + + return 0; +} + +static int cxl_mem_create_range_info(struct cxl_mem *cxlm) +{ + int rc; + + if (cxlm->partition_align_bytes == 0) { + cxlm->ram_range.start = 0; + cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; + cxlm->pmem_range.start = cxlm->volatile_only_bytes; + cxlm->pmem_range.end = cxlm->volatile_only_bytes + + cxlm->persistent_only_bytes - 1; + return 0; + } + + rc = cxl_mem_get_partition_info(cxlm, + &cxlm->active_volatile_bytes, + &cxlm->active_persistent_bytes, + &cxlm->next_volatile_bytes, + &cxlm->next_persistent_bytes); + if (rc < 0) { + dev_err(&cxlm->pdev->dev, "Failed to query partition information\n"); + return rc; + } + + dev_dbg(&cxlm->pdev->dev, "Get Partition Info\n" + " active_volatile_bytes = %#llx\n" + " active_persistent_bytes = %#llx\n" + " next_volatile_bytes = %#llx\n" + " next_persistent_bytes = %#llx\n", + cxlm->active_volatile_bytes, + cxlm->active_persistent_bytes, + cxlm->next_volatile_bytes, + cxlm->next_persistent_bytes); + + cxlm->ram_range.start = 0; + cxlm->ram_range.end = cxlm->active_volatile_bytes - 1; + + cxlm->pmem_range.start = cxlm->active_volatile_bytes; + cxlm->pmem_range.end = cxlm->active_volatile_bytes + + cxlm->active_persistent_bytes - 1; + + return 0; +} + +static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct cxl_memdev *cxlmd; + struct cxl_mem *cxlm; + int rc; rc = pcim_enable_device(pdev); if (rc) return rc; - cxlds = cxl_dev_state_create(&pdev->dev); - if (IS_ERR(cxlds)) - return PTR_ERR(cxlds); + cxlm = cxl_mem_create(pdev); + if (IS_ERR(cxlm)) + return PTR_ERR(cxlm); - rc = cxl_setup_regs(pdev, CXL_REGLOC_RBI_MEMDEV, &map); + rc = cxl_mem_setup_regs(cxlm); if (rc) return rc; - rc = cxl_map_regs(cxlds, &map); + rc = cxl_mem_setup_mailbox(cxlm); if (rc) return rc; - rc = cxl_pci_setup_mailbox(cxlds); + rc = cxl_mem_enumerate_cmds(cxlm); if (rc) return rc; - rc = cxl_enumerate_cmds(cxlds); + rc = cxl_mem_identify(cxlm); if (rc) return rc; - rc = cxl_dev_state_identify(cxlds); + rc = cxl_mem_create_range_info(cxlm); if (rc) return rc; - rc = cxl_mem_create_range_info(cxlds); - if (rc) - return rc; - - cxlmd = devm_cxl_add_memdev(cxlds); + cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); - if (range_len(&cxlds->pmem_range) && IS_ENABLED(CONFIG_CXL_PMEM)) + if (range_len(&cxlm->pmem_range) && IS_ENABLED(CONFIG_CXL_PMEM)) rc = devm_cxl_add_nvdimm(&pdev->dev, cxlmd); return rc; @@ -534,15 +1528,43 @@ static const struct pci_device_id cxl_mem_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, cxl_mem_pci_tbl); -static struct pci_driver cxl_pci_driver = { +static struct pci_driver cxl_mem_driver = { .name = KBUILD_MODNAME, .id_table = cxl_mem_pci_tbl, - .probe = cxl_pci_probe, + .probe = cxl_mem_probe, .driver = { .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, }; +static __init int cxl_mem_init(void) +{ + struct dentry *mbox_debugfs; + int rc; + + /* Double check the anonymous union trickery in struct cxl_regs */ + BUILD_BUG_ON(offsetof(struct cxl_regs, memdev) != + offsetof(struct cxl_regs, device_regs.memdev)); + + rc = pci_register_driver(&cxl_mem_driver); + if (rc) + return rc; + + cxl_debugfs = debugfs_create_dir("cxl", NULL); + mbox_debugfs = debugfs_create_dir("mbox", cxl_debugfs); + debugfs_create_bool("raw_allow_all", 0600, mbox_debugfs, + &cxl_raw_allow_all); + + return 0; +} + +static __exit void cxl_mem_exit(void) +{ + debugfs_remove_recursive(cxl_debugfs); + pci_unregister_driver(&cxl_mem_driver); +} + MODULE_LICENSE("GPL v2"); -module_pci_driver(cxl_pci_driver); +module_init(cxl_mem_init); +module_exit(cxl_mem_exit); MODULE_IMPORT_NS(CXL); diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h index 7d3e4bf06b..8c1a588138 100644 --- a/drivers/cxl/pci.h +++ b/drivers/cxl/pci.h @@ -20,15 +20,13 @@ #define CXL_REGLOC_BIR_MASK GENMASK(2, 0) /* Register Block Identifier (RBI) */ -enum cxl_regloc_type { - CXL_REGLOC_RBI_EMPTY = 0, - CXL_REGLOC_RBI_COMPONENT, - CXL_REGLOC_RBI_VIRT, - CXL_REGLOC_RBI_MEMDEV, - CXL_REGLOC_RBI_TYPES -}; - #define CXL_REGLOC_RBI_MASK GENMASK(15, 8) +#define CXL_REGLOC_RBI_EMPTY 0 +#define CXL_REGLOC_RBI_COMPONENT 1 +#define CXL_REGLOC_RBI_VIRT 2 +#define CXL_REGLOC_RBI_MEMDEV 3 +#define CXL_REGLOC_RBI_TYPES CXL_REGLOC_RBI_MEMDEV + 1 + #define CXL_REGLOC_ADDR_MASK GENMASK(31, 16) #endif /* __CXL_PCI_H__ */ diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index b65a272a2d..2bb2f9a049 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright(c) 2021 Intel Corporation. All rights reserved. */ #include -#include #include #include #include @@ -17,55 +16,48 @@ */ static struct workqueue_struct *cxl_pmem_wq; -static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); - -static void clear_exclusive(void *cxlds) -{ - clear_exclusive_cxl_commands(cxlds, exclusive_cmds); -} - static void unregister_nvdimm(void *nvdimm) { nvdimm_delete(nvdimm); } +static int match_nvdimm_bridge(struct device *dev, const void *data) +{ + return strcmp(dev_name(dev), "nvdimm-bridge") == 0; +} + +static struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(void) +{ + struct device *dev; + + dev = bus_find_device(&cxl_bus_type, NULL, NULL, match_nvdimm_bridge); + if (!dev) + return NULL; + return to_cxl_nvdimm_bridge(dev); +} + static int cxl_nvdimm_probe(struct device *dev) { struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); - struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; - unsigned long flags = 0, cmd_mask = 0; - struct cxl_dev_state *cxlds = cxlmd->cxlds; struct cxl_nvdimm_bridge *cxl_nvb; + unsigned long flags = 0; struct nvdimm *nvdimm; - int rc; + int rc = -ENXIO; - cxl_nvb = cxl_find_nvdimm_bridge(cxl_nvd); + cxl_nvb = cxl_find_nvdimm_bridge(); if (!cxl_nvb) return -ENXIO; device_lock(&cxl_nvb->dev); - if (!cxl_nvb->nvdimm_bus) { - rc = -ENXIO; - goto out; - } - - set_exclusive_cxl_commands(cxlds, exclusive_cmds); - rc = devm_add_action_or_reset(dev, clear_exclusive, cxlds); - if (rc) + if (!cxl_nvb->nvdimm_bus) goto out; set_bit(NDD_LABELING, &flags); - set_bit(ND_CMD_GET_CONFIG_SIZE, &cmd_mask); - set_bit(ND_CMD_GET_CONFIG_DATA, &cmd_mask); - set_bit(ND_CMD_SET_CONFIG_DATA, &cmd_mask); - nvdimm = nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags, - cmd_mask, 0, NULL); - if (!nvdimm) { - rc = -ENOMEM; + nvdimm = nvdimm_create(cxl_nvb->nvdimm_bus, cxl_nvd, NULL, flags, 0, 0, + NULL); + if (!nvdimm) goto out; - } - dev_set_drvdata(dev, nvdimm); rc = devm_add_action_or_reset(dev, unregister_nvdimm, nvdimm); out: device_unlock(&cxl_nvb->dev); @@ -80,119 +72,11 @@ static struct cxl_driver cxl_nvdimm_driver = { .id = CXL_DEVICE_NVDIMM, }; -static int cxl_pmem_get_config_size(struct cxl_dev_state *cxlds, - struct nd_cmd_get_config_size *cmd, - unsigned int buf_len) -{ - if (sizeof(*cmd) > buf_len) - return -EINVAL; - - *cmd = (struct nd_cmd_get_config_size) { - .config_size = cxlds->lsa_size, - .max_xfer = cxlds->payload_size, - }; - - return 0; -} - -static int cxl_pmem_get_config_data(struct cxl_dev_state *cxlds, - struct nd_cmd_get_config_data_hdr *cmd, - unsigned int buf_len) -{ - struct cxl_mbox_get_lsa get_lsa; - int rc; - - if (sizeof(*cmd) > buf_len) - return -EINVAL; - if (struct_size(cmd, out_buf, cmd->in_length) > buf_len) - return -EINVAL; - - get_lsa = (struct cxl_mbox_get_lsa) { - .offset = cmd->in_offset, - .length = cmd->in_length, - }; - - rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_GET_LSA, &get_lsa, - sizeof(get_lsa), cmd->out_buf, cmd->in_length); - cmd->status = 0; - - return rc; -} - -static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds, - struct nd_cmd_set_config_hdr *cmd, - unsigned int buf_len) -{ - struct cxl_mbox_set_lsa *set_lsa; - int rc; - - if (sizeof(*cmd) > buf_len) - return -EINVAL; - - /* 4-byte status follows the input data in the payload */ - if (struct_size(cmd, in_buf, cmd->in_length) + 4 > buf_len) - return -EINVAL; - - set_lsa = - kvzalloc(struct_size(set_lsa, data, cmd->in_length), GFP_KERNEL); - if (!set_lsa) - return -ENOMEM; - - *set_lsa = (struct cxl_mbox_set_lsa) { - .offset = cmd->in_offset, - }; - memcpy(set_lsa->data, cmd->in_buf, cmd->in_length); - - rc = cxl_mbox_send_cmd(cxlds, CXL_MBOX_OP_SET_LSA, set_lsa, - struct_size(set_lsa, data, cmd->in_length), - NULL, 0); - - /* - * Set "firmware" status (4-packed bytes at the end of the input - * payload. - */ - put_unaligned(0, (u32 *) &cmd->in_buf[cmd->in_length]); - kvfree(set_lsa); - - return rc; -} - -static int cxl_pmem_nvdimm_ctl(struct nvdimm *nvdimm, unsigned int cmd, - void *buf, unsigned int buf_len) -{ - struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); - unsigned long cmd_mask = nvdimm_cmd_mask(nvdimm); - struct cxl_memdev *cxlmd = cxl_nvd->cxlmd; - struct cxl_dev_state *cxlds = cxlmd->cxlds; - - if (!test_bit(cmd, &cmd_mask)) - return -ENOTTY; - - switch (cmd) { - case ND_CMD_GET_CONFIG_SIZE: - return cxl_pmem_get_config_size(cxlds, buf, buf_len); - case ND_CMD_GET_CONFIG_DATA: - return cxl_pmem_get_config_data(cxlds, buf, buf_len); - case ND_CMD_SET_CONFIG_DATA: - return cxl_pmem_set_config_data(cxlds, buf, buf_len); - default: - return -ENOTTY; - } -} - static int cxl_pmem_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc) { - /* - * No firmware response to translate, let the transport error - * code take precedence. - */ - *cmd_rc = 0; - - if (!nvdimm) - return -ENOTTY; - return cxl_pmem_nvdimm_ctl(nvdimm, cmd, buf, buf_len); + return -ENOTTY; } static bool online_nvdimm_bus(struct cxl_nvdimm_bridge *cxl_nvb) @@ -315,39 +199,10 @@ static struct cxl_driver cxl_nvdimm_bridge_driver = { .id = CXL_DEVICE_NVDIMM_BRIDGE, }; -/* - * Return all bridges to the CXL_NVB_NEW state to invalidate any - * ->state_work referring to the now destroyed cxl_pmem_wq. - */ -static int cxl_nvdimm_bridge_reset(struct device *dev, void *data) -{ - struct cxl_nvdimm_bridge *cxl_nvb; - - if (!is_cxl_nvdimm_bridge(dev)) - return 0; - - cxl_nvb = to_cxl_nvdimm_bridge(dev); - device_lock(dev); - cxl_nvb->state = CXL_NVB_NEW; - device_unlock(dev); - - return 0; -} - -static void destroy_cxl_pmem_wq(void) -{ - destroy_workqueue(cxl_pmem_wq); - bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_nvdimm_bridge_reset); -} - static __init int cxl_pmem_init(void) { int rc; - set_bit(CXL_MEM_COMMAND_ID_SET_PARTITION_INFO, exclusive_cmds); - set_bit(CXL_MEM_COMMAND_ID_SET_SHUTDOWN_STATE, exclusive_cmds); - set_bit(CXL_MEM_COMMAND_ID_SET_LSA, exclusive_cmds); - cxl_pmem_wq = alloc_ordered_workqueue("cxl_pmem", 0); if (!cxl_pmem_wq) return -ENXIO; @@ -365,7 +220,7 @@ static __init int cxl_pmem_init(void) err_nvdimm: cxl_driver_unregister(&cxl_nvdimm_bridge_driver); err_bridge: - destroy_cxl_pmem_wq(); + destroy_workqueue(cxl_pmem_wq); return rc; } @@ -373,7 +228,7 @@ static __exit void cxl_pmem_exit(void) { cxl_driver_unregister(&cxl_nvdimm_driver); cxl_driver_unregister(&cxl_nvdimm_bridge_driver); - destroy_cxl_pmem_wq(); + destroy_workqueue(cxl_pmem_wq); } MODULE_LICENSE("GPL v2"); diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig index 5fdf269a82..d2834c2cfa 100644 --- a/drivers/dax/Kconfig +++ b/drivers/dax/Kconfig @@ -1,4 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only +config DAX_DRIVER + select DAX + bool + menuconfig DAX tristate "DAX: direct access to differentiated memory" select SRCU @@ -66,4 +70,13 @@ config DEV_DAX_KMEM Say N if unsure. +config DEV_DAX_PMEM_COMPAT + tristate "PMEM DAX: support the deprecated /sys/class/dax interface" + depends on m && DEV_DAX_PMEM=m + default DEV_DAX_PMEM + help + Older versions of the libdaxctl library expect to find all + device-dax instances under /sys/class/dax. If libdaxctl in + your distribution is older than v58 say M, otherwise say N. + endif diff --git a/drivers/dax/Makefile b/drivers/dax/Makefile index 90a56ca3b3..9d4ba672d3 100644 --- a/drivers/dax/Makefile +++ b/drivers/dax/Makefile @@ -2,11 +2,10 @@ obj-$(CONFIG_DAX) += dax.o obj-$(CONFIG_DEV_DAX) += device_dax.o obj-$(CONFIG_DEV_DAX_KMEM) += kmem.o -obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o dax-y := super.o dax-y += bus.o device_dax-y := device.o -dax_pmem-y := pmem.o +obj-y += pmem/ obj-y += hmem/ diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 1dad813ee4..6cc4da4c71 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -10,6 +10,8 @@ #include "dax-private.h" #include "bus.h" +static struct class *dax_class; + static DEFINE_MUTEX(dax_bus_lock); #define DAX_NAME_LEN 30 @@ -127,35 +129,11 @@ ATTRIBUTE_GROUPS(dax_drv); static int dax_bus_match(struct device *dev, struct device_driver *drv); -/* - * Static dax regions are regions created by an external subsystem - * nvdimm where a single range is assigned. Its boundaries are by the external - * subsystem and are usually limited to one physical memory range. For example, - * for PMEM it is usually defined by NVDIMM Namespace boundaries (i.e. a - * single contiguous range) - * - * On dynamic dax regions, the assigned region can be partitioned by dax core - * into multiple subdivisions. A subdivision is represented into one - * /dev/daxN.M device composed by one or more potentially discontiguous ranges. - * - * When allocating a dax region, drivers must set whether it's static - * (IORESOURCE_DAX_STATIC). On static dax devices, the @pgmap is pre-assigned - * to dax core when calling devm_create_dev_dax(), whereas in dynamic dax - * devices it is NULL but afterwards allocated by dax core on device ->probe(). - * Care is needed to make sure that dynamic dax devices are torn down with a - * cleared @pgmap field (see kill_dev_dax()). - */ static bool is_static(struct dax_region *dax_region) { return (dax_region->res.flags & IORESOURCE_DAX_STATIC) != 0; } -bool static_dev_dax(struct dev_dax *dev_dax) -{ - return is_static(dev_dax->region); -} -EXPORT_SYMBOL_GPL(static_dev_dax); - static u64 dev_dax_size(struct dev_dax *dev_dax) { u64 size = 0; @@ -385,14 +363,6 @@ void kill_dev_dax(struct dev_dax *dev_dax) kill_dax(dax_dev); unmap_mapping_range(inode->i_mapping, 0, 0, 1); - - /* - * Dynamic dax region have the pgmap allocated via dev_kzalloc() - * and thus freed by devm. Clear the pgmap to not have stale pgmap - * ranges on probe() from previous reconfigurations of region devices. - */ - if (!static_dev_dax(dev_dax)) - dev_dax->pgmap = NULL; } EXPORT_SYMBOL_GPL(kill_dev_dax); @@ -1353,17 +1323,14 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) } /* - * No dax_operations since there is no access to this device outside of - * mmap of the resulting character device. + * No 'host' or dax_operations since there is no access to this + * device outside of mmap of the resulting character device. */ - dax_dev = alloc_dax(dev_dax, NULL); + dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC); if (IS_ERR(dax_dev)) { rc = PTR_ERR(dax_dev); goto err_alloc_dax; } - set_dax_synchronous(dax_dev); - set_dax_nocache(dax_dev); - set_dax_nomc(dax_dev); /* a device_dax instance is dead while the driver is not attached */ kill_dax(dax_dev); @@ -1376,7 +1343,10 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data) inode = dax_inode(dax_dev); dev->devt = inode->i_rdev; - dev->bus = &dax_bus_type; + if (data->subsys == DEV_DAX_BUS) + dev->bus = &dax_bus_type; + else + dev->class = dax_class; dev->parent = parent; dev->type = &dev_dax_type; @@ -1475,10 +1445,22 @@ EXPORT_SYMBOL_GPL(dax_driver_unregister); int __init dax_bus_init(void) { - return bus_register(&dax_bus_type); + int rc; + + if (IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT)) { + dax_class = class_create(THIS_MODULE, "dax"); + if (IS_ERR(dax_class)) + return PTR_ERR(dax_class); + } + + rc = bus_register(&dax_bus_type); + if (rc) + class_destroy(dax_class); + return rc; } void __exit dax_bus_exit(void) { bus_unregister(&dax_bus_type); + class_destroy(dax_class); } diff --git a/drivers/dax/bus.h b/drivers/dax/bus.h index fbb940293d..1e946ad778 100644 --- a/drivers/dax/bus.h +++ b/drivers/dax/bus.h @@ -16,15 +16,24 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id, struct range *range, int target_node, unsigned int align, unsigned long flags); +enum dev_dax_subsys { + DEV_DAX_BUS = 0, /* zeroed dev_dax_data picks this by default */ + DEV_DAX_CLASS, +}; + struct dev_dax_data { struct dax_region *dax_region; struct dev_pagemap *pgmap; + enum dev_dax_subsys subsys; resource_size_t size; int id; }; struct dev_dax *devm_create_dev_dax(struct dev_dax_data *data); +/* to be deleted when DEV_DAX_CLASS is removed */ +struct dev_dax *__dax_pmem_probe(struct device *dev, enum dev_dax_subsys subsys); + struct dax_device_driver { struct device_driver drv; struct list_head ids; @@ -39,7 +48,10 @@ int __dax_driver_register(struct dax_device_driver *dax_drv, __dax_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) void dax_driver_unregister(struct dax_device_driver *dax_drv); void kill_dev_dax(struct dev_dax *dev_dax); -bool static_dev_dax(struct dev_dax *dev_dax); + +#if IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT) +int dev_dax_probe(struct dev_dax *dev_dax); +#endif /* * While run_dax() is potentially a generic operation that could be diff --git a/drivers/dax/device.c b/drivers/dax/device.c index d33a0613ed..dd8222a428 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -73,39 +73,11 @@ __weak phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, return -1; } -static void dax_set_mapping(struct vm_fault *vmf, pfn_t pfn, - unsigned long fault_size) -{ - unsigned long i, nr_pages = fault_size / PAGE_SIZE; - struct file *filp = vmf->vma->vm_file; - struct dev_dax *dev_dax = filp->private_data; - pgoff_t pgoff; - - /* mapping is only set on the head */ - if (dev_dax->pgmap->vmemmap_shift) - nr_pages = 1; - - pgoff = linear_page_index(vmf->vma, - ALIGN(vmf->address, fault_size)); - - for (i = 0; i < nr_pages; i++) { - struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i); - - page = compound_head(page); - if (page->mapping) - continue; - - page->mapping = filp->f_mapping; - page->index = pgoff + i; - } -} - static vm_fault_t __dev_dax_pte_fault(struct dev_dax *dev_dax, - struct vm_fault *vmf) + struct vm_fault *vmf, pfn_t *pfn) { struct device *dev = &dev_dax->dev; phys_addr_t phys; - pfn_t pfn; unsigned int fault_size = PAGE_SIZE; if (check_vma(dev_dax, vmf->vma, __func__)) @@ -126,21 +98,18 @@ static vm_fault_t __dev_dax_pte_fault(struct dev_dax *dev_dax, return VM_FAULT_SIGBUS; } - pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); + *pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); - dax_set_mapping(vmf, pfn, fault_size); - - return vmf_insert_mixed(vmf->vma, vmf->address, pfn); + return vmf_insert_mixed(vmf->vma, vmf->address, *pfn); } static vm_fault_t __dev_dax_pmd_fault(struct dev_dax *dev_dax, - struct vm_fault *vmf) + struct vm_fault *vmf, pfn_t *pfn) { unsigned long pmd_addr = vmf->address & PMD_MASK; struct device *dev = &dev_dax->dev; phys_addr_t phys; pgoff_t pgoff; - pfn_t pfn; unsigned int fault_size = PMD_SIZE; if (check_vma(dev_dax, vmf->vma, __func__)) @@ -169,22 +138,19 @@ static vm_fault_t __dev_dax_pmd_fault(struct dev_dax *dev_dax, return VM_FAULT_SIGBUS; } - pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); + *pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); - dax_set_mapping(vmf, pfn, fault_size); - - return vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE); + return vmf_insert_pfn_pmd(vmf, *pfn, vmf->flags & FAULT_FLAG_WRITE); } #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax, - struct vm_fault *vmf) + struct vm_fault *vmf, pfn_t *pfn) { unsigned long pud_addr = vmf->address & PUD_MASK; struct device *dev = &dev_dax->dev; phys_addr_t phys; pgoff_t pgoff; - pfn_t pfn; unsigned int fault_size = PUD_SIZE; @@ -214,15 +180,13 @@ static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax, return VM_FAULT_SIGBUS; } - pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); + *pfn = phys_to_pfn_t(phys, PFN_DEV|PFN_MAP); - dax_set_mapping(vmf, pfn, fault_size); - - return vmf_insert_pfn_pud(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE); + return vmf_insert_pfn_pud(vmf, *pfn, vmf->flags & FAULT_FLAG_WRITE); } #else static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax, - struct vm_fault *vmf) + struct vm_fault *vmf, pfn_t *pfn) { return VM_FAULT_FALLBACK; } @@ -232,8 +196,10 @@ static vm_fault_t dev_dax_huge_fault(struct vm_fault *vmf, enum page_entry_size pe_size) { struct file *filp = vmf->vma->vm_file; + unsigned long fault_size; vm_fault_t rc = VM_FAULT_SIGBUS; int id; + pfn_t pfn; struct dev_dax *dev_dax = filp->private_data; dev_dbg(&dev_dax->dev, "%s: %s (%#lx - %#lx) size = %d\n", current->comm, @@ -243,18 +209,43 @@ static vm_fault_t dev_dax_huge_fault(struct vm_fault *vmf, id = dax_read_lock(); switch (pe_size) { case PE_SIZE_PTE: - rc = __dev_dax_pte_fault(dev_dax, vmf); + fault_size = PAGE_SIZE; + rc = __dev_dax_pte_fault(dev_dax, vmf, &pfn); break; case PE_SIZE_PMD: - rc = __dev_dax_pmd_fault(dev_dax, vmf); + fault_size = PMD_SIZE; + rc = __dev_dax_pmd_fault(dev_dax, vmf, &pfn); break; case PE_SIZE_PUD: - rc = __dev_dax_pud_fault(dev_dax, vmf); + fault_size = PUD_SIZE; + rc = __dev_dax_pud_fault(dev_dax, vmf, &pfn); break; default: rc = VM_FAULT_SIGBUS; } + if (rc == VM_FAULT_NOPAGE) { + unsigned long i; + pgoff_t pgoff; + + /* + * In the device-dax case the only possibility for a + * VM_FAULT_NOPAGE result is when device-dax capacity is + * mapped. No need to consider the zero page, or racing + * conflicting mappings. + */ + pgoff = linear_page_index(vmf->vma, vmf->address + & ~(fault_size - 1)); + for (i = 0; i < fault_size / PAGE_SIZE; i++) { + struct page *page; + + page = pfn_to_page(pfn_t_to_pfn(pfn) + i); + if (page->mapping) + continue; + page->mapping = filp->f_mapping; + page->index = pgoff + i; + } + } dax_read_unlock(id); return rc; @@ -407,34 +398,17 @@ int dev_dax_probe(struct dev_dax *dev_dax) void *addr; int rc, i; - if (static_dev_dax(dev_dax)) { - if (dev_dax->nr_range > 1) { - dev_warn(dev, - "static pgmap / multi-range device conflict\n"); - return -EINVAL; - } + pgmap = dev_dax->pgmap; + if (dev_WARN_ONCE(dev, pgmap && dev_dax->nr_range > 1, + "static pgmap / multi-range device conflict\n")) + return -EINVAL; - pgmap = dev_dax->pgmap; - } else { - if (dev_dax->pgmap) { - dev_warn(dev, - "dynamic-dax with pre-populated page map\n"); - return -EINVAL; - } - - pgmap = devm_kzalloc(dev, - struct_size(pgmap, ranges, dev_dax->nr_range - 1), - GFP_KERNEL); + if (!pgmap) { + pgmap = devm_kzalloc(dev, sizeof(*pgmap) + sizeof(struct range) + * (dev_dax->nr_range - 1), GFP_KERNEL); if (!pgmap) return -ENOMEM; - pgmap->nr_range = dev_dax->nr_range; - dev_dax->pgmap = pgmap; - - for (i = 0; i < dev_dax->nr_range; i++) { - struct range *range = &dev_dax->ranges[i].range; - pgmap->ranges[i] = *range; - } } for (i = 0; i < dev_dax->nr_range; i++) { @@ -446,12 +420,12 @@ int dev_dax_probe(struct dev_dax *dev_dax) i, range->start, range->end); return -EBUSY; } + /* don't update the range for static pgmap */ + if (!dev_dax->pgmap) + pgmap->ranges[i] = *range; } pgmap->type = MEMORY_DEVICE_GENERIC; - if (dev_dax->align > PAGE_SIZE) - pgmap->vmemmap_shift = - order_base_2(dev_dax->align >> PAGE_SHIFT); addr = devm_memremap_pages(dev, pgmap); if (IS_ERR(addr)) return PTR_ERR(addr); @@ -459,7 +433,11 @@ int dev_dax_probe(struct dev_dax *dev_dax) inode = dax_inode(dax_dev); cdev = inode->i_cdev; cdev_init(cdev, &dax_fops); - cdev->owner = dev->driver->owner; + if (dev->class) { + /* for the CONFIG_DEV_DAX_PMEM_COMPAT case */ + cdev->owner = dev->parent->driver->owner; + } else + cdev->owner = dev->driver->owner; cdev_set_parent(cdev, &dev->kobj); rc = cdev_add(cdev, dev->devt, 1); if (rc) diff --git a/drivers/dax/pmem/Makefile b/drivers/dax/pmem/Makefile index 191c31f0d4..010269f61d 100644 --- a/drivers/dax/pmem/Makefile +++ b/drivers/dax/pmem/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o +obj-$(CONFIG_DEV_DAX_PMEM_COMPAT) += dax_pmem_compat.o dax_pmem-y := pmem.o dax_pmem_core-y := core.o diff --git a/drivers/dax/pmem/pmem.c b/drivers/dax/pmem/pmem.c index dfe91a2990..0ae4238a0e 100644 --- a/drivers/dax/pmem/pmem.c +++ b/drivers/dax/pmem/pmem.c @@ -7,4 +7,34 @@ #include #include "../bus.h" +static int dax_pmem_probe(struct device *dev) +{ + return PTR_ERR_OR_ZERO(__dax_pmem_probe(dev, DEV_DAX_BUS)); +} +static struct nd_device_driver dax_pmem_driver = { + .probe = dax_pmem_probe, + .drv = { + .name = "dax_pmem", + }, + .type = ND_DRIVER_DAX_PMEM, +}; + +static int __init dax_pmem_init(void) +{ + return nd_driver_register(&dax_pmem_driver); +} +module_init(dax_pmem_init); + +static void __exit dax_pmem_exit(void) +{ + driver_unregister(&dax_pmem_driver.drv); +} +module_exit(dax_pmem_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Intel Corporation"); +#if !IS_ENABLED(CONFIG_DEV_DAX_PMEM_COMPAT) +/* For compat builds, don't load this module by default */ +MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DAX_PMEM); +#endif diff --git a/drivers/dax/super.c b/drivers/dax/super.c index e3029389d8..fc89e91bee 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -19,12 +21,15 @@ * struct dax_device - anchor object for dax services * @inode: core vfs * @cdev: optional character interface for "device dax" + * @host: optional name for lookups where the device path is not available * @private: dax driver private data * @flags: state and boolean properties */ struct dax_device { + struct hlist_node list; struct inode inode; struct cdev cdev; + const char *host; void *private; unsigned long flags; const struct dax_operations *ops; @@ -37,6 +42,10 @@ static DEFINE_IDA(dax_minor_ida); static struct kmem_cache *dax_cache __read_mostly; static struct super_block *dax_superblock __read_mostly; +#define DAX_HASH_SIZE (PAGE_SIZE / sizeof(struct hlist_head)) +static struct hlist_head dax_host_list[DAX_HASH_SIZE]; +static DEFINE_SPINLOCK(dax_host_lock); + int dax_read_lock(void) { return srcu_read_lock(&dax_srcu); @@ -49,54 +58,169 @@ void dax_read_unlock(int id) } EXPORT_SYMBOL_GPL(dax_read_unlock); -#if defined(CONFIG_BLOCK) && defined(CONFIG_FS_DAX) -#include - -static DEFINE_XARRAY(dax_hosts); - -int dax_add_host(struct dax_device *dax_dev, struct gendisk *disk) +static int dax_host_hash(const char *host) { - return xa_insert(&dax_hosts, (unsigned long)disk, dax_dev, GFP_KERNEL); + return hashlen_hash(hashlen_string("DAX", host)) % DAX_HASH_SIZE; } -EXPORT_SYMBOL_GPL(dax_add_host); - -void dax_remove_host(struct gendisk *disk) -{ - xa_erase(&dax_hosts, (unsigned long)disk); -} -EXPORT_SYMBOL_GPL(dax_remove_host); /** - * fs_dax_get_by_bdev() - temporary lookup mechanism for filesystem-dax - * @bdev: block device to find a dax_device for - * @start_off: returns the byte offset into the dax_device that @bdev starts + * dax_get_by_host() - temporary lookup mechanism for filesystem-dax + * @host: alternate name for the device registered by a dax driver */ -struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev, u64 *start_off) +static struct dax_device *dax_get_by_host(const char *host) { - struct dax_device *dax_dev; - u64 part_size; - int id; + struct dax_device *dax_dev, *found = NULL; + int hash, id; + if (!host) + return NULL; + + hash = dax_host_hash(host); + + id = dax_read_lock(); + spin_lock(&dax_host_lock); + hlist_for_each_entry(dax_dev, &dax_host_list[hash], list) { + if (!dax_alive(dax_dev) + || strcmp(host, dax_dev->host) != 0) + continue; + + if (igrab(&dax_dev->inode)) + found = dax_dev; + break; + } + spin_unlock(&dax_host_lock); + dax_read_unlock(id); + + return found; +} + +#ifdef CONFIG_BLOCK +#include + +int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size, + pgoff_t *pgoff) +{ + sector_t start_sect = bdev ? get_start_sect(bdev) : 0; + phys_addr_t phys_off = (start_sect + sector) * 512; + + if (pgoff) + *pgoff = PHYS_PFN(phys_off); + if (phys_off % PAGE_SIZE || size % PAGE_SIZE) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL(bdev_dax_pgoff); + +#if IS_ENABLED(CONFIG_FS_DAX) +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev) +{ if (!blk_queue_dax(bdev->bd_disk->queue)) return NULL; + return dax_get_by_host(bdev->bd_disk->disk_name); +} +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev); - *start_off = get_start_sect(bdev) * SECTOR_SIZE; - part_size = bdev_nr_sectors(bdev) * SECTOR_SIZE; - if (*start_off % PAGE_SIZE || part_size % PAGE_SIZE) { +bool generic_fsdax_supported(struct dax_device *dax_dev, + struct block_device *bdev, int blocksize, sector_t start, + sector_t sectors) +{ + bool dax_enabled = false; + pgoff_t pgoff, pgoff_end; + void *kaddr, *end_kaddr; + pfn_t pfn, end_pfn; + sector_t last_page; + long len, len2; + int err, id; + + if (blocksize != PAGE_SIZE) { + pr_info("%pg: error: unsupported blocksize for dax\n", bdev); + return false; + } + + if (!dax_dev) { + pr_debug("%pg: error: dax unsupported by block device\n", bdev); + return false; + } + + err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff); + if (err) { pr_info("%pg: error: unaligned partition for dax\n", bdev); - return NULL; + return false; + } + + last_page = PFN_DOWN((start + sectors - 1) * 512) * PAGE_SIZE / 512; + err = bdev_dax_pgoff(bdev, last_page, PAGE_SIZE, &pgoff_end); + if (err) { + pr_info("%pg: error: unaligned partition for dax\n", bdev); + return false; } id = dax_read_lock(); - dax_dev = xa_load(&dax_hosts, (unsigned long)bdev->bd_disk); - if (!dax_dev || !dax_alive(dax_dev) || !igrab(&dax_dev->inode)) - dax_dev = NULL; + len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn); + len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn); + + if (len < 1 || len2 < 1) { + pr_info("%pg: error: dax access failed (%ld)\n", + bdev, len < 1 ? len : len2); + dax_read_unlock(id); + return false; + } + + if (IS_ENABLED(CONFIG_FS_DAX_LIMITED) && pfn_t_special(pfn)) { + /* + * An arch that has enabled the pmem api should also + * have its drivers support pfn_t_devmap() + * + * This is a developer warning and should not trigger in + * production. dax_flush() will crash since it depends + * on being able to do (page_address(pfn_to_page())). + */ + WARN_ON(IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API)); + dax_enabled = true; + } else if (pfn_t_devmap(pfn) && pfn_t_devmap(end_pfn)) { + struct dev_pagemap *pgmap, *end_pgmap; + + pgmap = get_dev_pagemap(pfn_t_to_pfn(pfn), NULL); + end_pgmap = get_dev_pagemap(pfn_t_to_pfn(end_pfn), NULL); + if (pgmap && pgmap == end_pgmap && pgmap->type == MEMORY_DEVICE_FS_DAX + && pfn_t_to_page(pfn)->pgmap == pgmap + && pfn_t_to_page(end_pfn)->pgmap == pgmap + && pfn_t_to_pfn(pfn) == PHYS_PFN(__pa(kaddr)) + && pfn_t_to_pfn(end_pfn) == PHYS_PFN(__pa(end_kaddr))) + dax_enabled = true; + put_dev_pagemap(pgmap); + put_dev_pagemap(end_pgmap); + + } dax_read_unlock(id); - return dax_dev; + if (!dax_enabled) { + pr_info("%pg: error: dax support not enabled\n", bdev); + return false; + } + return true; } -EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev); -#endif /* CONFIG_BLOCK && CONFIG_FS_DAX */ +EXPORT_SYMBOL_GPL(generic_fsdax_supported); + +bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev, + int blocksize, sector_t start, sector_t len) +{ + bool ret = false; + int id; + + if (!dax_dev) + return false; + + id = dax_read_lock(); + if (dax_alive(dax_dev) && dax_dev->ops->dax_supported) + ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, + start, len); + dax_read_unlock(id); + return ret; +} +EXPORT_SYMBOL_GPL(dax_supported); +#endif /* CONFIG_FS_DAX */ +#endif /* CONFIG_BLOCK */ enum dax_device_flags { /* !alive + rcu grace period == no new operations / mappings */ @@ -105,12 +229,72 @@ enum dax_device_flags { DAXDEV_WRITE_CACHE, /* flag to check if device supports synchronous flush */ DAXDEV_SYNC, - /* do not leave the caches dirty after writes */ - DAXDEV_NOCACHE, - /* handle CPU fetch exceptions during reads */ - DAXDEV_NOMC, }; +static ssize_t write_cache_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dax_device *dax_dev = dax_get_by_host(dev_name(dev)); + ssize_t rc; + + WARN_ON_ONCE(!dax_dev); + if (!dax_dev) + return -ENXIO; + + rc = sprintf(buf, "%d\n", !!dax_write_cache_enabled(dax_dev)); + put_dax(dax_dev); + return rc; +} + +static ssize_t write_cache_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + bool write_cache; + int rc = strtobool(buf, &write_cache); + struct dax_device *dax_dev = dax_get_by_host(dev_name(dev)); + + WARN_ON_ONCE(!dax_dev); + if (!dax_dev) + return -ENXIO; + + if (rc) + len = rc; + else + dax_write_cache(dax_dev, write_cache); + + put_dax(dax_dev); + return len; +} +static DEVICE_ATTR_RW(write_cache); + +static umode_t dax_visible(struct kobject *kobj, struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, typeof(*dev), kobj); + struct dax_device *dax_dev = dax_get_by_host(dev_name(dev)); + + WARN_ON_ONCE(!dax_dev); + if (!dax_dev) + return 0; + +#ifndef CONFIG_ARCH_HAS_PMEM_API + if (a == &dev_attr_write_cache.attr) + return 0; +#endif + return a->mode; +} + +static struct attribute *dax_attributes[] = { + &dev_attr_write_cache.attr, + NULL, +}; + +struct attribute_group dax_attribute_group = { + .name = "dax", + .attrs = dax_attributes, + .is_visible = dax_visible, +}; +EXPORT_SYMBOL_GPL(dax_attribute_group); + /** * dax_direct_access() - translate a device pgoff to an absolute pfn * @dax_dev: a dax_device instance representing the logical memory range @@ -150,15 +334,9 @@ size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, if (!dax_alive(dax_dev)) return 0; - /* - * The userspace address for the memory copy has already been validated - * via access_ok() in vfs_write, so use the 'no check' version to bypass - * the HARDENED_USERCOPY overhead. - */ - if (test_bit(DAXDEV_NOCACHE, &dax_dev->flags)) - return _copy_from_iter_flushcache(addr, bytes, i); - return _copy_from_iter(addr, bytes, i); + return dax_dev->ops->copy_from_iter(dax_dev, pgoff, addr, bytes, i); } +EXPORT_SYMBOL_GPL(dax_copy_from_iter); size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i) @@ -166,15 +344,9 @@ size_t dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, if (!dax_alive(dax_dev)) return 0; - /* - * The userspace address for the memory copy has already been validated - * via access_ok() in vfs_red, so use the 'no check' version to bypass - * the HARDENED_USERCOPY overhead. - */ - if (test_bit(DAXDEV_NOMC, &dax_dev->flags)) - return _copy_mc_to_iter(addr, bytes, i); - return _copy_to_iter(addr, bytes, i); + return dax_dev->ops->copy_to_iter(dax_dev, pgoff, addr, bytes, i); } +EXPORT_SYMBOL_GPL(dax_copy_to_iter); int dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff, size_t nr_pages) @@ -224,29 +396,17 @@ bool dax_write_cache_enabled(struct dax_device *dax_dev) } EXPORT_SYMBOL_GPL(dax_write_cache_enabled); -bool dax_synchronous(struct dax_device *dax_dev) +bool __dax_synchronous(struct dax_device *dax_dev) { return test_bit(DAXDEV_SYNC, &dax_dev->flags); } -EXPORT_SYMBOL_GPL(dax_synchronous); +EXPORT_SYMBOL_GPL(__dax_synchronous); -void set_dax_synchronous(struct dax_device *dax_dev) +void __set_dax_synchronous(struct dax_device *dax_dev) { set_bit(DAXDEV_SYNC, &dax_dev->flags); } -EXPORT_SYMBOL_GPL(set_dax_synchronous); - -void set_dax_nocache(struct dax_device *dax_dev) -{ - set_bit(DAXDEV_NOCACHE, &dax_dev->flags); -} -EXPORT_SYMBOL_GPL(set_dax_nocache); - -void set_dax_nomc(struct dax_device *dax_dev) -{ - set_bit(DAXDEV_NOMC, &dax_dev->flags); -} -EXPORT_SYMBOL_GPL(set_dax_nomc); +EXPORT_SYMBOL_GPL(__set_dax_synchronous); bool dax_alive(struct dax_device *dax_dev) { @@ -267,7 +427,12 @@ void kill_dax(struct dax_device *dax_dev) return; clear_bit(DAXDEV_ALIVE, &dax_dev->flags); + synchronize_srcu(&dax_srcu); + + spin_lock(&dax_host_lock); + hlist_del_init(&dax_dev->list); + spin_unlock(&dax_host_lock); } EXPORT_SYMBOL_GPL(kill_dax); @@ -299,6 +464,8 @@ static struct dax_device *to_dax_dev(struct inode *inode) static void dax_free_inode(struct inode *inode) { struct dax_device *dax_dev = to_dax_dev(inode); + kfree(dax_dev->host); + dax_dev->host = NULL; if (inode->i_rdev) ida_simple_remove(&dax_minor_ida, iminor(inode)); kmem_cache_free(dax_cache, dax_dev); @@ -373,30 +540,65 @@ static struct dax_device *dax_dev_get(dev_t devt) return dax_dev; } -struct dax_device *alloc_dax(void *private, const struct dax_operations *ops) +static void dax_add_host(struct dax_device *dax_dev, const char *host) +{ + int hash; + + /* + * Unconditionally init dax_dev since it's coming from a + * non-zeroed slab cache + */ + INIT_HLIST_NODE(&dax_dev->list); + dax_dev->host = host; + if (!host) + return; + + hash = dax_host_hash(host); + spin_lock(&dax_host_lock); + hlist_add_head(&dax_dev->list, &dax_host_list[hash]); + spin_unlock(&dax_host_lock); +} + +struct dax_device *alloc_dax(void *private, const char *__host, + const struct dax_operations *ops, unsigned long flags) { struct dax_device *dax_dev; + const char *host; dev_t devt; int minor; - if (WARN_ON_ONCE(ops && !ops->zero_page_range)) + if (ops && !ops->zero_page_range) { + pr_debug("%s: error: device does not provide dax" + " operation zero_page_range()\n", + __host ? __host : "Unknown"); return ERR_PTR(-EINVAL); + } + + host = kstrdup(__host, GFP_KERNEL); + if (__host && !host) + return ERR_PTR(-ENOMEM); minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL); if (minor < 0) - return ERR_PTR(-ENOMEM); + goto err_minor; devt = MKDEV(MAJOR(dax_devt), minor); dax_dev = dax_dev_get(devt); if (!dax_dev) goto err_dev; + dax_add_host(dax_dev, host); dax_dev->ops = ops; dax_dev->private = private; + if (flags & DAXDEV_F_SYNC) + set_dax_synchronous(dax_dev); + return dax_dev; err_dev: ida_simple_remove(&dax_minor_ida, minor); + err_minor: + kfree(host); return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(alloc_dax); diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 511805dbeb..40d81f23ca 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-resv.o + dma-resv.o seqno-fence.o obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_DMABUF_HEAPS) += heaps/ obj-$(CONFIG_SYNC_FILE) += sync_file.o @@ -11,7 +11,6 @@ obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o dmabuf_selftests-y := \ selftest.o \ st-dma-fence.o \ - st-dma-fence-chain.o \ - st-dma-resv.o + st-dma-fence-chain.o obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/dma-buf-sysfs-stats.c index 2bba0babcb..053baadcad 100644 --- a/drivers/dma-buf/dma-buf-sysfs-stats.c +++ b/drivers/dma-buf/dma-buf-sysfs-stats.c @@ -132,7 +132,7 @@ void dma_buf_stats_teardown(struct dma_buf *dmabuf) /* Statistics files do not need to send uevents. */ -static int dmabuf_sysfs_uevent_filter(struct kobject *kobj) +static int dmabuf_sysfs_uevent_filter(struct kset *kset, struct kobject *kobj) { return 0; } diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 602b12d747..61e20ae7b0 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -67,9 +67,12 @@ static void dma_buf_release(struct dentry *dentry) BUG_ON(dmabuf->vmapping_counter); /* - * If you hit this BUG() it could mean: - * * There's a file reference imbalance in dma_buf_poll / dma_buf_poll_cb or somewhere else - * * dmabuf->cb_in/out.active are non-0 despite no pending fence callback + * Any fences that a dma-buf poll can wait on should be signaled + * before releasing dma-buf. This is the responsibility of each + * driver that uses the reservation objects. + * + * If you hit this BUG() it means someone dropped their ref to the + * dma-buf while still having pending operation to the buffer. */ BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); @@ -197,7 +200,6 @@ static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb) { struct dma_buf_poll_cb_t *dcb = (struct dma_buf_poll_cb_t *)cb; - struct dma_buf *dmabuf = container_of(dcb->poll, struct dma_buf, poll); unsigned long flags; spin_lock_irqsave(&dcb->poll->lock, flags); @@ -205,18 +207,21 @@ static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb) dcb->active = 0; spin_unlock_irqrestore(&dcb->poll->lock, flags); dma_fence_put(fence); - /* Paired with get_file in dma_buf_poll */ - fput(dmabuf->file); } -static bool dma_buf_poll_add_cb(struct dma_resv *resv, bool write, +static bool dma_buf_poll_shared(struct dma_resv *resv, struct dma_buf_poll_cb_t *dcb) { - struct dma_resv_iter cursor; + struct dma_resv_list *fobj = dma_resv_shared_list(resv); struct dma_fence *fence; - int r; + int i, r; - dma_resv_for_each_fence(&cursor, resv, write, fence) { + if (!fobj) + return false; + + for (i = 0; i < fobj->shared_count; ++i) { + fence = rcu_dereference_protected(fobj->shared[i], + dma_resv_held(resv)); dma_fence_get(fence); r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); if (!r) @@ -227,6 +232,24 @@ static bool dma_buf_poll_add_cb(struct dma_resv *resv, bool write, return false; } +static bool dma_buf_poll_excl(struct dma_resv *resv, + struct dma_buf_poll_cb_t *dcb) +{ + struct dma_fence *fence = dma_resv_excl_fence(resv); + int r; + + if (!fence) + return false; + + dma_fence_get(fence); + r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); + if (!r) + return true; + dma_fence_put(fence); + + return false; +} + static __poll_t dma_buf_poll(struct file *file, poll_table *poll) { struct dma_buf *dmabuf; @@ -259,10 +282,8 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) spin_unlock_irq(&dmabuf->poll.lock); if (events & EPOLLOUT) { - /* Paired with fput in dma_buf_poll_cb */ - get_file(dmabuf->file); - - if (!dma_buf_poll_add_cb(resv, true, dcb)) + if (!dma_buf_poll_shared(resv, dcb) && + !dma_buf_poll_excl(resv, dcb)) /* No callback queued, wake up any other waiters */ dma_buf_poll_cb(NULL, &dcb->cb); else @@ -282,10 +303,7 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) spin_unlock_irq(&dmabuf->poll.lock); if (events & EPOLLIN) { - /* Paired with fput in dma_buf_poll_cb */ - get_file(dmabuf->file); - - if (!dma_buf_poll_add_cb(resv, false, dcb)) + if (!dma_buf_poll_excl(resv, dcb)) /* No callback queued, wake up any other waiters */ dma_buf_poll_cb(NULL, &dcb->cb); else @@ -299,8 +317,10 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) /** * dma_buf_set_name - Set a name to a specific dma_buf to track the usage. - * It could support changing the name of the dma-buf if the same - * piece of memory is used for multiple purpose between different devices. + * The name of the dma-buf buffer can only be set when the dma-buf is not + * attached to any devices. It could theoritically support changing the + * name of the dma-buf if the same piece of memory is used for multiple + * purpose between different devices. * * @dmabuf: [in] dmabuf buffer that will be renamed. * @buf: [in] A piece of userspace memory that contains the name of @@ -313,16 +333,25 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) { char *name = strndup_user(buf, DMA_BUF_NAME_LEN); + long ret = 0; if (IS_ERR(name)) return PTR_ERR(name); + dma_resv_lock(dmabuf->resv, NULL); + if (!list_empty(&dmabuf->attachments)) { + ret = -EBUSY; + kfree(name); + goto out_unlock; + } spin_lock(&dmabuf->name_lock); kfree(dmabuf->name); dmabuf->name = name; spin_unlock(&dmabuf->name_lock); - return 0; +out_unlock: + dma_resv_unlock(dmabuf->resv); + return ret; } static long dma_buf_ioctl(struct file *file, @@ -570,7 +599,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) module_put(exp_info->owner); return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(dma_buf_export, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_export); /** * dma_buf_fd - returns a file descriptor for the given struct dma_buf @@ -594,7 +623,7 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) return fd; } -EXPORT_SYMBOL_NS_GPL(dma_buf_fd, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_fd); /** * dma_buf_get - returns the struct dma_buf related to an fd @@ -620,7 +649,7 @@ struct dma_buf *dma_buf_get(int fd) return file->private_data; } -EXPORT_SYMBOL_NS_GPL(dma_buf_get, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_get); /** * dma_buf_put - decreases refcount of the buffer @@ -639,7 +668,7 @@ void dma_buf_put(struct dma_buf *dmabuf) fput(dmabuf->file); } -EXPORT_SYMBOL_NS_GPL(dma_buf_put, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_put); static void mangle_sg_table(struct sg_table *sg_table) { @@ -770,7 +799,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, dma_buf_detach(dmabuf, attach); return ERR_PTR(ret); } -EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_dynamic_attach); /** * dma_buf_attach - Wrapper for dma_buf_dynamic_attach @@ -785,7 +814,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, { return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL); } -EXPORT_SYMBOL_NS_GPL(dma_buf_attach, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_attach); static void __unmap_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sg_table, @@ -831,7 +860,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) kfree(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_detach, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_detach); /** * dma_buf_pin - Lock down the DMA-buf @@ -861,7 +890,7 @@ int dma_buf_pin(struct dma_buf_attachment *attach) return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_pin, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_pin); /** * dma_buf_unpin - Unpin a DMA-buf @@ -882,7 +911,7 @@ void dma_buf_unpin(struct dma_buf_attachment *attach) if (dmabuf->ops->unpin) dmabuf->ops->unpin(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_unpin); /** * dma_buf_map_attachment - Returns the scatterlist table of the attachment; @@ -972,7 +1001,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, #endif /* CONFIG_DMA_API_DEBUG */ return sg_table; } -EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_map_attachment); /** * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might @@ -1008,7 +1037,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, !IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) dma_buf_unpin(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); /** * dma_buf_move_notify - notify attachments that DMA-buf is moving @@ -1028,7 +1057,7 @@ void dma_buf_move_notify(struct dma_buf *dmabuf) if (attach->importer_ops) attach->importer_ops->move_notify(attach); } -EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_move_notify); /** * DOC: cpu access @@ -1047,8 +1076,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_move_notify, DMA_BUF); * * Interfaces:: * - * void \*dma_buf_vmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map) - * void dma_buf_vunmap(struct dma_buf \*dmabuf, struct dma_buf_map \*map) + * void \*dma_buf_vmap(struct dma_buf \*dmabuf) + * void dma_buf_vunmap(struct dma_buf \*dmabuf, void \*vaddr) * * The vmap call can fail if there is no vmap support in the exporter, or if * it runs out of vmalloc space. Note that the dma-buf layer keeps a reference @@ -1172,7 +1201,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); /** * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the @@ -1200,7 +1229,7 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf, return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); /** @@ -1242,7 +1271,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, return dmabuf->ops->mmap(dmabuf, vma); } -EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_mmap); /** * dma_buf_vmap - Create virtual mapping for the buffer object into kernel @@ -1296,7 +1325,7 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) mutex_unlock(&dmabuf->lock); return ret; } -EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_vmap); /** * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap. @@ -1320,14 +1349,17 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map) } mutex_unlock(&dmabuf->lock); } -EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, DMA_BUF); +EXPORT_SYMBOL_GPL(dma_buf_vunmap); #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { struct dma_buf *buf_obj; struct dma_buf_attachment *attach_obj; - int count = 0, attach_count; + struct dma_resv *robj; + struct dma_resv_list *fobj; + struct dma_fence *fence; + int count = 0, attach_count, shared_count, i; size_t size = 0; int ret; @@ -1346,8 +1378,6 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) if (ret) goto error_unlock; - - spin_lock(&buf_obj->name_lock); seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n", buf_obj->size, buf_obj->file->f_flags, buf_obj->file->f_mode, @@ -1355,9 +1385,26 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) buf_obj->exp_name, file_inode(buf_obj->file)->i_ino, buf_obj->name ?: ""); - spin_unlock(&buf_obj->name_lock); - dma_resv_describe(buf_obj->resv, s); + robj = buf_obj->resv; + fence = dma_resv_excl_fence(robj); + if (fence) + seq_printf(s, "\tExclusive fence: %s %s %ssignalled\n", + fence->ops->get_driver_name(fence), + fence->ops->get_timeline_name(fence), + dma_fence_is_signaled(fence) ? "" : "un"); + + fobj = rcu_dereference_protected(robj->fence, + dma_resv_held(robj)); + shared_count = fobj ? fobj->shared_count : 0; + for (i = 0; i < shared_count; i++) { + fence = rcu_dereference_protected(fobj->shared[i], + dma_resv_held(robj)); + seq_printf(s, "\tShared fence: %s %s %ssignalled\n", + fence->ops->get_driver_name(fence), + fence->ops->get_timeline_name(fence), + dma_fence_is_signaled(fence) ? "" : "un"); + } seq_puts(s, "\tAttached Devices:\n"); attach_count = 0; diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 066400ed88..ce0f5eff57 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -15,7 +15,6 @@ #include #include #include -#include #define CREATE_TRACE_POINTS #include @@ -617,17 +616,20 @@ EXPORT_SYMBOL(dma_fence_enable_sw_signaling); * @cb: the callback to register * @func: the function to call * - * Add a software callback to the fence. The caller should keep a reference to - * the fence. - * * @cb will be initialized by dma_fence_add_callback(), no initialization * by the caller is required. Any number of callbacks can be registered * to a fence, but a callback can only be registered to one fence at a time. * - * If fence is already signaled, this function will return -ENOENT (and + * Note that the callback can be called from an atomic context. If + * fence is already signaled, this function will return -ENOENT (and * *not* call the callback). * - * Note that the callback can be called from an atomic context or irq context. + * Add a software callback to the fence. Same restrictions apply to + * refcount as it does to dma_fence_wait(), however the caller doesn't need to + * keep a refcount to fence afterward dma_fence_add_callback() has returned: + * when software access is enabled, the creator of the fence is required to keep + * the fence alive until after it signals with dma_fence_signal(). The callback + * itself can be called from irq context. * * Returns 0 in case of success, -ENOENT if the fence is already signaled * and -EINVAL in case of error. @@ -908,22 +910,6 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, } EXPORT_SYMBOL(dma_fence_wait_any_timeout); -/** - * dma_fence_describe - Dump fence describtion into seq_file - * @fence: the 6fence to describe - * @seq: the seq_file to put the textual description into - * - * Dump a textual description of the fence and it's state into the seq_file. - */ -void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq) -{ - seq_printf(seq, "%s %s seq %llu %ssignalled\n", - fence->ops->get_driver_name(fence), - fence->ops->get_timeline_name(fence), fence->seqno, - dma_fence_is_signaled(fence) ? "" : "un"); -} -EXPORT_SYMBOL(dma_fence_describe); - /** * dma_fence_init - Initialize a custom fence. * @fence: the fence to initialize diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 4deea75c0b..e744fd87c6 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -38,7 +38,6 @@ #include #include #include -#include /** * DOC: Reservation Object Overview @@ -49,8 +48,6 @@ * write operations) or N shared fences (read operations). The RCU * mechanism is used to protect read access to fences from locked * write-side updates. - * - * See struct dma_resv for more details. */ DEFINE_WD_CLASS(reservation_ww_class); @@ -140,11 +137,7 @@ EXPORT_SYMBOL(dma_resv_fini); * @num_fences: number of fences we want to add * * Should be called before dma_resv_add_shared_fence(). Must - * be called with @obj locked through dma_resv_lock(). - * - * Note that the preallocated slots need to be re-reserved if @obj is unlocked - * at any time before calling dma_resv_add_shared_fence(). This is validated - * when CONFIG_DEBUG_MUTEXES is enabled. + * be called with obj->lock held. * * RETURNS * Zero for success, or -errno @@ -241,10 +234,8 @@ EXPORT_SYMBOL(dma_resv_reset_shared_max); * @obj: the reservation object * @fence: the shared fence to add * - * Add a fence to a shared slot, @obj must be locked with dma_resv_lock(), and + * Add a fence to a shared slot, obj->lock must be held, and * dma_resv_reserve_shared() has been called. - * - * See also &dma_resv.fence for a discussion of the semantics. */ void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence) { @@ -287,11 +278,9 @@ EXPORT_SYMBOL(dma_resv_add_shared_fence); /** * dma_resv_add_excl_fence - Add an exclusive fence. * @obj: the reservation object - * @fence: the exclusive fence to add + * @fence: the shared fence to add * - * Add a fence to the exclusive slot. @obj must be locked with dma_resv_lock(). - * Note that this function replaces all fences attached to @obj, see also - * &dma_resv.fence_excl for a discussion of the semantics. + * Add a fence to the exclusive slot. The obj->lock must be held. */ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) { @@ -305,7 +294,8 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) if (old) i = old->shared_count; - dma_fence_get(fence); + if (fence) + dma_fence_get(fence); write_seqcount_begin(&obj->seq); /* write_seqcount_begin provides the necessary memory barrier */ @@ -323,161 +313,6 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) } EXPORT_SYMBOL(dma_resv_add_excl_fence); -/** - * dma_resv_iter_restart_unlocked - restart the unlocked iterator - * @cursor: The dma_resv_iter object to restart - * - * Restart the unlocked iteration by initializing the cursor object. - */ -static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor) -{ - cursor->seq = read_seqcount_begin(&cursor->obj->seq); - cursor->index = -1; - cursor->shared_count = 0; - if (cursor->all_fences) { - cursor->fences = dma_resv_shared_list(cursor->obj); - if (cursor->fences) - cursor->shared_count = cursor->fences->shared_count; - } else { - cursor->fences = NULL; - } - cursor->is_restarted = true; -} - -/** - * dma_resv_iter_walk_unlocked - walk over fences in a dma_resv obj - * @cursor: cursor to record the current position - * - * Return all the fences in the dma_resv object which are not yet signaled. - * The returned fence has an extra local reference so will stay alive. - * If a concurrent modify is detected the whole iteration is started over again. - */ -static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor) -{ - struct dma_resv *obj = cursor->obj; - - do { - /* Drop the reference from the previous round */ - dma_fence_put(cursor->fence); - - if (cursor->index == -1) { - cursor->fence = dma_resv_excl_fence(obj); - cursor->index++; - if (!cursor->fence) - continue; - - } else if (!cursor->fences || - cursor->index >= cursor->shared_count) { - cursor->fence = NULL; - break; - - } else { - struct dma_resv_list *fences = cursor->fences; - unsigned int idx = cursor->index++; - - cursor->fence = rcu_dereference(fences->shared[idx]); - } - cursor->fence = dma_fence_get_rcu(cursor->fence); - if (!cursor->fence || !dma_fence_is_signaled(cursor->fence)) - break; - } while (true); -} - -/** - * dma_resv_iter_first_unlocked - first fence in an unlocked dma_resv obj. - * @cursor: the cursor with the current position - * - * Returns the first fence from an unlocked dma_resv obj. - */ -struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor) -{ - rcu_read_lock(); - do { - dma_resv_iter_restart_unlocked(cursor); - dma_resv_iter_walk_unlocked(cursor); - } while (read_seqcount_retry(&cursor->obj->seq, cursor->seq)); - rcu_read_unlock(); - - return cursor->fence; -} -EXPORT_SYMBOL(dma_resv_iter_first_unlocked); - -/** - * dma_resv_iter_next_unlocked - next fence in an unlocked dma_resv obj. - * @cursor: the cursor with the current position - * - * Returns the next fence from an unlocked dma_resv obj. - */ -struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor) -{ - bool restart; - - rcu_read_lock(); - cursor->is_restarted = false; - restart = read_seqcount_retry(&cursor->obj->seq, cursor->seq); - do { - if (restart) - dma_resv_iter_restart_unlocked(cursor); - dma_resv_iter_walk_unlocked(cursor); - restart = true; - } while (read_seqcount_retry(&cursor->obj->seq, cursor->seq)); - rcu_read_unlock(); - - return cursor->fence; -} -EXPORT_SYMBOL(dma_resv_iter_next_unlocked); - -/** - * dma_resv_iter_first - first fence from a locked dma_resv object - * @cursor: cursor to record the current position - * - * Return the first fence in the dma_resv object while holding the - * &dma_resv.lock. - */ -struct dma_fence *dma_resv_iter_first(struct dma_resv_iter *cursor) -{ - struct dma_fence *fence; - - dma_resv_assert_held(cursor->obj); - - cursor->index = 0; - if (cursor->all_fences) - cursor->fences = dma_resv_shared_list(cursor->obj); - else - cursor->fences = NULL; - - fence = dma_resv_excl_fence(cursor->obj); - if (!fence) - fence = dma_resv_iter_next(cursor); - - cursor->is_restarted = true; - return fence; -} -EXPORT_SYMBOL_GPL(dma_resv_iter_first); - -/** - * dma_resv_iter_next - next fence from a locked dma_resv object - * @cursor: cursor to record the current position - * - * Return the next fences from the dma_resv object while holding the - * &dma_resv.lock. - */ -struct dma_fence *dma_resv_iter_next(struct dma_resv_iter *cursor) -{ - unsigned int idx; - - dma_resv_assert_held(cursor->obj); - - cursor->is_restarted = false; - if (!cursor->fences || cursor->index >= cursor->fences->shared_count) - return NULL; - - idx = cursor->index++; - return rcu_dereference_protected(cursor->fences->shared[idx], - dma_resv_held(cursor->obj)); -} -EXPORT_SYMBOL_GPL(dma_resv_iter_next); - /** * dma_resv_copy_fences - Copy all fences from src to dst. * @dst: the destination reservation object @@ -487,52 +322,74 @@ EXPORT_SYMBOL_GPL(dma_resv_iter_next); */ int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src) { - struct dma_resv_iter cursor; - struct dma_resv_list *list; - struct dma_fence *f, *excl; + struct dma_resv_list *src_list, *dst_list; + struct dma_fence *old, *new; + unsigned int i; dma_resv_assert_held(dst); - list = NULL; - excl = NULL; + rcu_read_lock(); + src_list = dma_resv_shared_list(src); - dma_resv_iter_begin(&cursor, src, true); - dma_resv_for_each_fence_unlocked(&cursor, f) { +retry: + if (src_list) { + unsigned int shared_count = src_list->shared_count; - if (dma_resv_iter_is_restarted(&cursor)) { - dma_resv_list_free(list); - dma_fence_put(excl); + rcu_read_unlock(); - if (cursor.shared_count) { - list = dma_resv_list_alloc(cursor.shared_count); - if (!list) { - dma_resv_iter_end(&cursor); - return -ENOMEM; - } + dst_list = dma_resv_list_alloc(shared_count); + if (!dst_list) + return -ENOMEM; - list->shared_count = 0; - - } else { - list = NULL; - } - excl = NULL; + rcu_read_lock(); + src_list = dma_resv_shared_list(src); + if (!src_list || src_list->shared_count > shared_count) { + kfree(dst_list); + goto retry; } - dma_fence_get(f); - if (dma_resv_iter_is_exclusive(&cursor)) - excl = f; - else - RCU_INIT_POINTER(list->shared[list->shared_count++], f); + dst_list->shared_count = 0; + for (i = 0; i < src_list->shared_count; ++i) { + struct dma_fence __rcu **dst; + struct dma_fence *fence; + + fence = rcu_dereference(src_list->shared[i]); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, + &fence->flags)) + continue; + + if (!dma_fence_get_rcu(fence)) { + dma_resv_list_free(dst_list); + src_list = dma_resv_shared_list(src); + goto retry; + } + + if (dma_fence_is_signaled(fence)) { + dma_fence_put(fence); + continue; + } + + dst = &dst_list->shared[dst_list->shared_count++]; + rcu_assign_pointer(*dst, fence); + } + } else { + dst_list = NULL; } - dma_resv_iter_end(&cursor); + + new = dma_fence_get_rcu_safe(&src->fence_excl); + rcu_read_unlock(); + + src_list = dma_resv_shared_list(dst); + old = dma_resv_excl_fence(dst); write_seqcount_begin(&dst->seq); - excl = rcu_replace_pointer(dst->fence_excl, excl, dma_resv_held(dst)); - list = rcu_replace_pointer(dst->fence, list, dma_resv_held(dst)); + /* write_seqcount_begin provides the necessary memory barrier */ + RCU_INIT_POINTER(dst->fence_excl, new); + RCU_INIT_POINTER(dst->fence, dst_list); write_seqcount_end(&dst->seq); - dma_resv_list_free(list); - dma_fence_put(excl); + dma_resv_list_free(src_list); + dma_fence_put(old); return 0; } @@ -542,61 +399,99 @@ EXPORT_SYMBOL(dma_resv_copy_fences); * dma_resv_get_fences - Get an object's shared and exclusive * fences without update side lock held * @obj: the reservation object - * @fence_excl: the returned exclusive fence (or NULL) - * @shared_count: the number of shared fences returned - * @shared: the array of shared fence ptrs returned (array is krealloc'd to + * @pfence_excl: the returned exclusive fence (or NULL) + * @pshared_count: the number of shared fences returned + * @pshared: the array of shared fence ptrs returned (array is krealloc'd to * the required size, and must be freed by caller) * * Retrieve all fences from the reservation object. If the pointer for the * exclusive fence is not specified the fence is put into the array of the * shared fences as well. Returns either zero or -ENOMEM. */ -int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl, - unsigned int *shared_count, struct dma_fence ***shared) +int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **pfence_excl, + unsigned int *pshared_count, + struct dma_fence ***pshared) { - struct dma_resv_iter cursor; - struct dma_fence *fence; + struct dma_fence **shared = NULL; + struct dma_fence *fence_excl; + unsigned int shared_count; + int ret = 1; - *shared_count = 0; - *shared = NULL; + do { + struct dma_resv_list *fobj; + unsigned int i, seq; + size_t sz = 0; - if (fence_excl) - *fence_excl = NULL; + shared_count = i = 0; - dma_resv_iter_begin(&cursor, obj, true); - dma_resv_for_each_fence_unlocked(&cursor, fence) { + rcu_read_lock(); + seq = read_seqcount_begin(&obj->seq); - if (dma_resv_iter_is_restarted(&cursor)) { - unsigned int count; + fence_excl = dma_resv_excl_fence(obj); + if (fence_excl && !dma_fence_get_rcu(fence_excl)) + goto unlock; - while (*shared_count) - dma_fence_put((*shared)[--(*shared_count)]); + fobj = dma_resv_shared_list(obj); + if (fobj) + sz += sizeof(*shared) * fobj->shared_max; - if (fence_excl) - dma_fence_put(*fence_excl); + if (!pfence_excl && fence_excl) + sz += sizeof(*shared); - count = cursor.shared_count; - count += fence_excl ? 0 : 1; + if (sz) { + struct dma_fence **nshared; - /* Eventually re-allocate the array */ - *shared = krealloc_array(*shared, count, - sizeof(void *), - GFP_KERNEL); - if (count && !*shared) { - dma_resv_iter_end(&cursor); - return -ENOMEM; + nshared = krealloc(shared, sz, + GFP_NOWAIT | __GFP_NOWARN); + if (!nshared) { + rcu_read_unlock(); + + dma_fence_put(fence_excl); + fence_excl = NULL; + + nshared = krealloc(shared, sz, GFP_KERNEL); + if (nshared) { + shared = nshared; + continue; + } + + ret = -ENOMEM; + break; + } + shared = nshared; + shared_count = fobj ? fobj->shared_count : 0; + for (i = 0; i < shared_count; ++i) { + shared[i] = rcu_dereference(fobj->shared[i]); + if (!dma_fence_get_rcu(shared[i])) + break; } } - dma_fence_get(fence); - if (dma_resv_iter_is_exclusive(&cursor) && fence_excl) - *fence_excl = fence; - else - (*shared)[(*shared_count)++] = fence; - } - dma_resv_iter_end(&cursor); + if (i != shared_count || read_seqcount_retry(&obj->seq, seq)) { + while (i--) + dma_fence_put(shared[i]); + dma_fence_put(fence_excl); + goto unlock; + } - return 0; + ret = 0; +unlock: + rcu_read_unlock(); + } while (ret); + + if (pfence_excl) + *pfence_excl = fence_excl; + else if (fence_excl) + shared[shared_count++] = fence_excl; + + if (!shared_count) { + kfree(shared); + shared = NULL; + } + + *pshared_count = shared_count; + *pshared = shared; + return ret; } EXPORT_SYMBOL_GPL(dma_resv_get_fences); @@ -618,25 +513,94 @@ long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr, unsigned long timeout) { long ret = timeout ? timeout : 1; - struct dma_resv_iter cursor; + unsigned int seq, shared_count; struct dma_fence *fence; + int i; - dma_resv_iter_begin(&cursor, obj, wait_all); - dma_resv_for_each_fence_unlocked(&cursor, fence) { +retry: + shared_count = 0; + seq = read_seqcount_begin(&obj->seq); + rcu_read_lock(); + i = -1; - ret = dma_fence_wait_timeout(fence, intr, ret); - if (ret <= 0) { - dma_resv_iter_end(&cursor); - return ret; + fence = dma_resv_excl_fence(obj); + if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { + if (!dma_fence_get_rcu(fence)) + goto unlock_retry; + + if (dma_fence_is_signaled(fence)) { + dma_fence_put(fence); + fence = NULL; + } + + } else { + fence = NULL; + } + + if (wait_all) { + struct dma_resv_list *fobj = dma_resv_shared_list(obj); + + if (fobj) + shared_count = fobj->shared_count; + + for (i = 0; !fence && i < shared_count; ++i) { + struct dma_fence *lfence; + + lfence = rcu_dereference(fobj->shared[i]); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, + &lfence->flags)) + continue; + + if (!dma_fence_get_rcu(lfence)) + goto unlock_retry; + + if (dma_fence_is_signaled(lfence)) { + dma_fence_put(lfence); + continue; + } + + fence = lfence; + break; } } - dma_resv_iter_end(&cursor); + rcu_read_unlock(); + if (fence) { + if (read_seqcount_retry(&obj->seq, seq)) { + dma_fence_put(fence); + goto retry; + } + + ret = dma_fence_wait_timeout(fence, intr, ret); + dma_fence_put(fence); + if (ret > 0 && wait_all && (i + 1 < shared_count)) + goto retry; + } return ret; + +unlock_retry: + rcu_read_unlock(); + goto retry; } EXPORT_SYMBOL_GPL(dma_resv_wait_timeout); +static inline int dma_resv_test_signaled_single(struct dma_fence *passed_fence) +{ + struct dma_fence *fence, *lfence = passed_fence; + int ret = 1; + + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &lfence->flags)) { + fence = dma_fence_get_rcu(lfence); + if (!fence) + return -1; + + ret = !!dma_fence_is_signaled(fence); + dma_fence_put(fence); + } + return ret; +} + /** * dma_resv_test_signaled - Test if a reservation object's fences have been * signaled. @@ -645,49 +609,52 @@ EXPORT_SYMBOL_GPL(dma_resv_wait_timeout); * fence * * Callers are not required to hold specific locks, but maybe hold - * dma_resv_lock() already. - * + * dma_resv_lock() already * RETURNS - * - * True if all fences signaled, else false. + * true if all fences signaled, else false */ bool dma_resv_test_signaled(struct dma_resv *obj, bool test_all) { - struct dma_resv_iter cursor; struct dma_fence *fence; + unsigned int seq; + int ret; - dma_resv_iter_begin(&cursor, obj, test_all); - dma_resv_for_each_fence_unlocked(&cursor, fence) { - dma_resv_iter_end(&cursor); - return false; + rcu_read_lock(); +retry: + ret = true; + seq = read_seqcount_begin(&obj->seq); + + if (test_all) { + struct dma_resv_list *fobj = dma_resv_shared_list(obj); + unsigned int i, shared_count; + + shared_count = fobj ? fobj->shared_count : 0; + for (i = 0; i < shared_count; ++i) { + fence = rcu_dereference(fobj->shared[i]); + ret = dma_resv_test_signaled_single(fence); + if (ret < 0) + goto retry; + else if (!ret) + break; + } } - dma_resv_iter_end(&cursor); - return true; + + fence = dma_resv_excl_fence(obj); + if (ret && fence) { + ret = dma_resv_test_signaled_single(fence); + if (ret < 0) + goto retry; + + } + + if (read_seqcount_retry(&obj->seq, seq)) + goto retry; + + rcu_read_unlock(); + return ret; } EXPORT_SYMBOL_GPL(dma_resv_test_signaled); -/** - * dma_resv_describe - Dump description of the resv object into seq_file - * @obj: the reservation object - * @seq: the seq_file to dump the description into - * - * Dump a textual description of the fences inside an dma_resv object into the - * seq_file. - */ -void dma_resv_describe(struct dma_resv *obj, struct seq_file *seq) -{ - struct dma_resv_iter cursor; - struct dma_fence *fence; - - dma_resv_for_each_fence(&cursor, obj, true, fence) { - seq_printf(seq, "\t%s fence:", - dma_resv_iter_is_exclusive(&cursor) ? - "Exclusive" : "Shared"); - dma_fence_describe(fence, seq); - } -} -EXPORT_SYMBOL_GPL(dma_resv_describe); - #if IS_ENABLED(CONFIG_LOCKDEP) static int __init dma_resv_lockdep(void) { diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index ab7fd896d2..8660508f36 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -40,12 +40,11 @@ struct dma_heap_attachment { bool mapped; }; -#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP) -#define MID_ORDER_GFP (LOW_ORDER_GFP | __GFP_NOWARN) #define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \ | __GFP_NORETRY) & ~__GFP_RECLAIM) \ | __GFP_COMP) -static gfp_t order_flags[] = {HIGH_ORDER_GFP, MID_ORDER_GFP, LOW_ORDER_GFP}; +#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP) +static gfp_t order_flags[] = {HIGH_ORDER_GFP, LOW_ORDER_GFP, LOW_ORDER_GFP}; /* * The selection of the orders used for allocation (1MB, 64K, 4K) is designed * to match with the sizes often found in IOMMUs. Using order 4 pages instead diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 97d73aaa31..bc8cea67bf 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -12,4 +12,3 @@ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ selftest(dma_fence, dma_fence) selftest(dma_fence_chain, dma_fence_chain) -selftest(dma_resv, dma_resv) diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index aab87c9b35..c69d40ae56 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -23,7 +23,7 @@ config EXTCON_ADC_JACK config EXTCON_AXP288 tristate "X-Power AXP288 EXTCON support" - depends on MFD_AXP20X && USB_SUPPORT && X86 && ACPI && IOSF_MBI + depends on MFD_AXP20X && USB_SUPPORT && X86 && ACPI select USB_ROLE_SWITCH help Say Y here to enable support for USB peripheral detection diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c index 7c6d5857ff..fdb31954cf 100644 --- a/drivers/extcon/extcon-axp288.c +++ b/drivers/extcon/extcon-axp288.c @@ -24,7 +24,6 @@ #include #include -#include /* Power source status register */ #define PS_STAT_VBUS_TRIGGER BIT(0) @@ -216,10 +215,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) unsigned int cable = info->previous_cable; bool vbus_attach = false; - ret = iosf_mbi_block_punit_i2c_access(); - if (ret < 0) - return ret; - vbus_attach = axp288_get_vbus_attach(info); if (!vbus_attach) goto no_vbus; @@ -258,8 +253,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) } no_vbus: - iosf_mbi_unblock_punit_i2c_access(); - extcon_set_state_sync(info->edev, info->previous_cable, false); if (info->previous_cable == EXTCON_CHG_USB_SDP) extcon_set_state_sync(info->edev, EXTCON_USB, false); @@ -282,8 +275,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) return 0; dev_det_ret: - iosf_mbi_unblock_punit_i2c_access(); - if (ret < 0) dev_err(info->dev, "failed to detect BC Mod\n"); @@ -314,23 +305,13 @@ static irqreturn_t axp288_extcon_isr(int irq, void *data) return IRQ_HANDLED; } -static int axp288_extcon_enable(struct axp288_extcon_info *info) +static void axp288_extcon_enable(struct axp288_extcon_info *info) { - int ret = 0; - - ret = iosf_mbi_block_punit_i2c_access(); - if (ret < 0) - return ret; - regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, BC_GLOBAL_RUN, 0); /* Enable the charger detection logic */ regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, BC_GLOBAL_RUN, BC_GLOBAL_RUN); - - iosf_mbi_unblock_punit_i2c_access(); - - return ret; } static void axp288_put_role_sw(void *data) @@ -403,16 +384,10 @@ static int axp288_extcon_probe(struct platform_device *pdev) } } - ret = iosf_mbi_block_punit_i2c_access(); - if (ret < 0) - return ret; - info->vbus_attach = axp288_get_vbus_attach(info); axp288_extcon_log_rsi(info); - iosf_mbi_unblock_punit_i2c_access(); - /* Initialize extcon device */ info->edev = devm_extcon_dev_allocate(&pdev->dev, axp288_extcon_cables); @@ -466,9 +441,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) } /* Start charger cable type detection */ - ret = axp288_extcon_enable(info); - if (ret < 0) - return ret; + axp288_extcon_enable(info); device_init_wakeup(dev, true); platform_set_drvdata(pdev, info); diff --git a/drivers/extcon/extcon-max3355.c b/drivers/extcon/extcon-max3355.c index d7795607f6..fa01926c09 100644 --- a/drivers/extcon/extcon-max3355.c +++ b/drivers/extcon/extcon-max3355.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/drivers/extcon/extcon-usb-gpio.c b/drivers/extcon/extcon-usb-gpio.c index f2b65d9673..f06be6d4e2 100644 --- a/drivers/extcon/extcon-usb-gpio.c +++ b/drivers/extcon/extcon-usb-gpio.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* +/** * drivers/extcon/extcon-usb-gpio.c - USB GPIO extcon driver * * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com @@ -7,17 +7,18 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include #include #include -#include #define USB_GPIO_DEBOUNCE_MS 20 /* ms */ diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c index 6ba3d89b10..805af73b41 100644 --- a/drivers/extcon/extcon-usbc-tusb320.c +++ b/drivers/extcon/extcon-usbc-tusb320.c @@ -19,42 +19,15 @@ #define TUSB320_REG9_ATTACHED_STATE_MASK 0x3 #define TUSB320_REG9_CABLE_DIRECTION BIT(5) #define TUSB320_REG9_INTERRUPT_STATUS BIT(4) - -#define TUSB320_REGA 0xa -#define TUSB320L_REGA_DISABLE_TERM BIT(0) -#define TUSB320_REGA_I2C_SOFT_RESET BIT(3) -#define TUSB320_REGA_MODE_SELECT_SHIFT 4 -#define TUSB320_REGA_MODE_SELECT_MASK 0x3 - -#define TUSB320L_REGA0_REVISION 0xa0 - -enum tusb320_attached_state { - TUSB320_ATTACHED_STATE_NONE, - TUSB320_ATTACHED_STATE_DFP, - TUSB320_ATTACHED_STATE_UFP, - TUSB320_ATTACHED_STATE_ACC, -}; - -enum tusb320_mode { - TUSB320_MODE_PORT, - TUSB320_MODE_UFP, - TUSB320_MODE_DFP, - TUSB320_MODE_DRP, -}; - -struct tusb320_priv; - -struct tusb320_ops { - int (*set_mode)(struct tusb320_priv *priv, enum tusb320_mode mode); - int (*get_revision)(struct tusb320_priv *priv, unsigned int *revision); -}; +#define TUSB320_ATTACHED_STATE_NONE 0x0 +#define TUSB320_ATTACHED_STATE_DFP 0x1 +#define TUSB320_ATTACHED_STATE_UFP 0x2 +#define TUSB320_ATTACHED_STATE_ACC 0x3 struct tusb320_priv { struct device *dev; struct regmap *regmap; struct extcon_dev *edev; - struct tusb320_ops *ops; - enum tusb320_attached_state state; }; static const char * const tusb_attached_states[] = { @@ -89,101 +62,6 @@ static int tusb320_check_signature(struct tusb320_priv *priv) return 0; } -static int tusb320_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode) -{ - int ret; - - /* Mode cannot be changed while cable is attached */ - if (priv->state != TUSB320_ATTACHED_STATE_NONE) - return -EBUSY; - - /* Write mode */ - ret = regmap_write_bits(priv->regmap, TUSB320_REGA, - TUSB320_REGA_MODE_SELECT_MASK << TUSB320_REGA_MODE_SELECT_SHIFT, - mode << TUSB320_REGA_MODE_SELECT_SHIFT); - if (ret) { - dev_err(priv->dev, "failed to write mode: %d\n", ret); - return ret; - } - - return 0; -} - -static int tusb320l_set_mode(struct tusb320_priv *priv, enum tusb320_mode mode) -{ - int ret; - - /* Disable CC state machine */ - ret = regmap_write_bits(priv->regmap, TUSB320_REGA, - TUSB320L_REGA_DISABLE_TERM, 1); - if (ret) { - dev_err(priv->dev, - "failed to disable CC state machine: %d\n", ret); - return ret; - } - - /* Write mode */ - ret = regmap_write_bits(priv->regmap, TUSB320_REGA, - TUSB320_REGA_MODE_SELECT_MASK << TUSB320_REGA_MODE_SELECT_SHIFT, - mode << TUSB320_REGA_MODE_SELECT_SHIFT); - if (ret) { - dev_err(priv->dev, "failed to write mode: %d\n", ret); - goto err; - } - - msleep(5); -err: - /* Re-enable CC state machine */ - ret = regmap_write_bits(priv->regmap, TUSB320_REGA, - TUSB320L_REGA_DISABLE_TERM, 0); - if (ret) - dev_err(priv->dev, - "failed to re-enable CC state machine: %d\n", ret); - - return ret; -} - -static int tusb320_reset(struct tusb320_priv *priv) -{ - int ret; - - /* Set mode to default (follow PORT pin) */ - ret = priv->ops->set_mode(priv, TUSB320_MODE_PORT); - if (ret && ret != -EBUSY) { - dev_err(priv->dev, - "failed to set mode to PORT: %d\n", ret); - return ret; - } - - /* Perform soft reset */ - ret = regmap_write_bits(priv->regmap, TUSB320_REGA, - TUSB320_REGA_I2C_SOFT_RESET, 1); - if (ret) { - dev_err(priv->dev, - "failed to write soft reset bit: %d\n", ret); - return ret; - } - - /* Wait for chip to go through reset */ - msleep(95); - - return 0; -} - -static int tusb320l_get_revision(struct tusb320_priv *priv, unsigned int *revision) -{ - return regmap_read(priv->regmap, TUSB320L_REGA0_REVISION, revision); -} - -static struct tusb320_ops tusb320_ops = { - .set_mode = tusb320_set_mode, -}; - -static struct tusb320_ops tusb320l_ops = { - .set_mode = tusb320l_set_mode, - .get_revision = tusb320l_get_revision, -}; - static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) { struct tusb320_priv *priv = dev_id; @@ -218,8 +96,6 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) extcon_sync(priv->edev, EXTCON_USB); extcon_sync(priv->edev, EXTCON_USB_HOST); - priv->state = state; - regmap_write(priv->regmap, TUSB320_REG9, reg); return IRQ_HANDLED; @@ -234,8 +110,6 @@ static int tusb320_extcon_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tusb320_priv *priv; - const void *match_data; - unsigned int revision; int ret; priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); @@ -251,27 +125,12 @@ static int tusb320_extcon_probe(struct i2c_client *client, if (ret) return ret; - match_data = device_get_match_data(&client->dev); - if (!match_data) - return -EINVAL; - - priv->ops = (struct tusb320_ops*)match_data; - priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); if (IS_ERR(priv->edev)) { dev_err(priv->dev, "failed to allocate extcon device\n"); return PTR_ERR(priv->edev); } - if (priv->ops->get_revision) { - ret = priv->ops->get_revision(priv, &revision); - if (ret) - dev_warn(priv->dev, - "failed to read revision register: %d\n", ret); - else - dev_info(priv->dev, "chip revision %d\n", revision); - } - ret = devm_extcon_dev_register(priv->dev, priv->edev); if (ret < 0) { dev_err(priv->dev, "failed to register extcon device\n"); @@ -286,17 +145,6 @@ static int tusb320_extcon_probe(struct i2c_client *client, /* update initial state */ tusb320_irq_handler(client->irq, priv); - /* Reset chip to its default state */ - ret = tusb320_reset(priv); - if (ret) - dev_warn(priv->dev, "failed to reset chip: %d\n", ret); - else - /* - * State and polarity might change after a reset, so update - * them again and make sure the interrupt status bit is cleared. - */ - tusb320_irq_handler(client->irq, priv); - ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, tusb320_irq_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, @@ -306,8 +154,7 @@ static int tusb320_extcon_probe(struct i2c_client *client, } static const struct of_device_id tusb320_extcon_dt_match[] = { - { .compatible = "ti,tusb320", .data = &tusb320_ops, }, - { .compatible = "ti,tusb320l", .data = &tusb320l_ops, }, + { .compatible = "ti,tusb320", }, { } }; MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index a09e704fd0..e7a9561a82 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -576,7 +576,19 @@ EXPORT_SYMBOL_GPL(extcon_set_state); */ int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, bool state) { - int ret; + int ret, index; + unsigned long flags; + + index = find_cable_index_by_id(edev, id); + if (index < 0) + return index; + + /* Check whether the external connector's state is changed. */ + spin_lock_irqsave(&edev->lock, flags); + ret = is_extcon_changed(edev, index, state); + spin_unlock_irqrestore(&edev->lock, flags); + if (!ret) + return 0; ret = extcon_set_state(edev, id, state); if (ret < 0) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 75cb91055c..cda7d7162c 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -295,7 +295,6 @@ config TURRIS_MOX_RWTM source "drivers/firmware/arm_ffa/Kconfig" source "drivers/firmware/broadcom/Kconfig" -source "drivers/firmware/cirrus/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" source "drivers/firmware/imx/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 4e58cb474a..5ced0673d9 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o obj-y += arm_ffa/ obj-y += arm_scmi/ obj-y += broadcom/ -obj-y += cirrus/ obj-y += meson/ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ obj-$(CONFIG_EFI) += efi/ diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 14f900047a..c9fb56afbc 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -167,27 +167,6 @@ struct ffa_drv_info { static struct ffa_drv_info *drv_info; -/* - * The driver must be able to support all the versions from the earliest - * supported FFA_MIN_VERSION to the latest supported FFA_DRIVER_VERSION. - * The specification states that if firmware supports a FFA implementation - * that is incompatible with and at a greater version number than specified - * by the caller(FFA_DRIVER_VERSION passed as parameter to FFA_VERSION), - * it must return the NOT_SUPPORTED error code. - */ -static u32 ffa_compatible_version_find(u32 version) -{ - u16 major = MAJOR_VERSION(version), minor = MINOR_VERSION(version); - u16 drv_major = MAJOR_VERSION(FFA_DRIVER_VERSION); - u16 drv_minor = MINOR_VERSION(FFA_DRIVER_VERSION); - - if ((major < drv_major) || (major == drv_major && minor <= drv_minor)) - return version; - - pr_info("Firmware version higher than driver version, downgrading\n"); - return FFA_DRIVER_VERSION; -} - static int ffa_version_check(u32 *version) { ffa_value_t ver; @@ -201,20 +180,15 @@ static int ffa_version_check(u32 *version) return -EOPNOTSUPP; } - if (ver.a0 < FFA_MIN_VERSION) { - pr_err("Incompatible v%d.%d! Earliest supported v%d.%d\n", - MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0), - MAJOR_VERSION(FFA_MIN_VERSION), - MINOR_VERSION(FFA_MIN_VERSION)); + if (ver.a0 < FFA_MIN_VERSION || ver.a0 > FFA_DRIVER_VERSION) { + pr_err("Incompatible version %d.%d found\n", + MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0)); return -EINVAL; } - pr_info("Driver version %d.%d\n", MAJOR_VERSION(FFA_DRIVER_VERSION), - MINOR_VERSION(FFA_DRIVER_VERSION)); - pr_info("Firmware version %d.%d found\n", MAJOR_VERSION(ver.a0), + *version = ver.a0; + pr_info("Version %d.%d found\n", MAJOR_VERSION(ver.a0), MINOR_VERSION(ver.a0)); - *version = ffa_compatible_version_find(ver.a0); - return 0; } @@ -612,22 +586,6 @@ ffa_memory_share(struct ffa_device *dev, struct ffa_mem_ops_args *args) return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args); } -static int -ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args) -{ - /* Note that upon a successful MEM_LEND request the caller - * must ensure that the memory region specified is not accessed - * until a successful MEM_RECALIM call has been made. - * On systems with a hypervisor present this will been enforced, - * however on systems without a hypervisor the responsibility - * falls to the calling kernel driver to prevent access. - */ - if (dev->mode_32bit) - return ffa_memory_ops(FFA_MEM_LEND, args); - - return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args); -} - static const struct ffa_dev_ops ffa_ops = { .api_version_get = ffa_api_version_get, .partition_info_get = ffa_partition_info_get, @@ -635,7 +593,6 @@ static const struct ffa_dev_ops ffa_ops = { .sync_send_receive = ffa_sync_send_receive, .memory_reclaim = ffa_memory_reclaim, .memory_share = ffa_memory_share, - .memory_lend = ffa_memory_lend, }; const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index b406b3f78f..d76bab3aaa 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2112,7 +2112,7 @@ static void __exit scmi_driver_exit(void) } module_exit(scmi_driver_exit); -MODULE_ALIAS("platform: arm-scmi"); +MODULE_ALIAS("platform:arm-scmi"); MODULE_AUTHOR("Sudeep Holla "); MODULE_DESCRIPTION("ARM SCMI protocol driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index 3a353776bd..8b8127fa89 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c @@ -302,12 +302,12 @@ static struct attribute *dmi_sysfs_sel_attrs[] = { &dmi_sysfs_attr_sel_per_log_type_descriptor_length.attr, NULL, }; -ATTRIBUTE_GROUPS(dmi_sysfs_sel); + static struct kobj_type dmi_system_event_log_ktype = { .release = dmi_entry_free, .sysfs_ops = &dmi_sysfs_specialize_attr_ops, - .default_groups = dmi_sysfs_sel_groups, + .default_attrs = dmi_sysfs_sel_attrs, }; typedef u8 (*sel_io_reader)(const struct dmi_system_event_log *sel, @@ -518,7 +518,6 @@ static struct attribute *dmi_sysfs_entry_attrs[] = { &dmi_sysfs_attr_entry_position.attr, NULL, }; -ATTRIBUTE_GROUPS(dmi_sysfs_entry); static ssize_t dmi_entry_raw_read_helper(struct dmi_sysfs_entry *entry, const struct dmi_header *dh, @@ -566,7 +565,7 @@ static void dmi_sysfs_entry_release(struct kobject *kobj) static struct kobj_type dmi_sysfs_entry_ktype = { .release = dmi_sysfs_entry_release, .sysfs_ops = &dmi_sysfs_attr_ops, - .default_groups = dmi_sysfs_entry_groups, + .default_attrs = dmi_sysfs_entry_attrs, }; static struct kset *dmi_kset; diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 69353dd0ea..14d0970a71 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -574,6 +574,14 @@ static EDD_DEVICE_ATTR(interface, 0444, edd_show_interface, edd_has_edd30); static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30); static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_mbr_signature, edd_has_mbr_signature); + +/* These are default attributes that are added for every edd + * device discovered. There are none. + */ +static struct attribute * def_attrs[] = { + NULL, +}; + /* These attributes are conditional and only added for some devices. */ static struct edd_attribute * edd_attrs[] = { &edd_attr_raw_data, @@ -611,6 +619,7 @@ static void edd_release(struct kobject * kobj) static struct kobj_type edd_ktype = { .release = edd_release, .sysfs_ops = &edd_attr_ops, + .default_attrs = def_attrs, }; static struct kset *edd_kset; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 7de3f5b6e8..9fa86288b7 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -66,7 +66,7 @@ struct mm_struct efi_mm = { struct workqueue_struct *efi_rts_wq; -static bool disable_runtime = IS_ENABLED(CONFIG_PREEMPT_RT); +static bool disable_runtime; static int __init setup_noefi(char *arg) { disable_runtime = true; @@ -97,9 +97,6 @@ static int __init parse_efi_cmdline(char *str) if (parse_option_str(str, "noruntime")) disable_runtime = true; - if (parse_option_str(str, "runtime")) - disable_runtime = false; - if (parse_option_str(str, "nosoftreserve")) set_bit(EFI_MEM_NO_SOFT_RESERVE, &efi.flags); diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index ea0bc39dc9..e6b16b3a17 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -352,12 +352,11 @@ static struct attribute *def_attrs[] = { &efivar_attr_raw_var.attr, NULL, }; -ATTRIBUTE_GROUPS(def); static struct kobj_type efivar_ktype = { .release = efivar_release, .sysfs_ops = &efivar_attr_ops, - .default_groups = def_groups, + .default_attrs = def_attrs, }; static ssize_t efivar_create(struct file *filp, struct kobject *kobj, diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index 2a2f52b017..d591527214 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -146,8 +146,6 @@ static struct attribute *esre1_attrs[] = { &esre_last_attempt_status.attr, NULL }; -ATTRIBUTE_GROUPS(esre1); - static void esre_release(struct kobject *kobj) { struct esre_entry *entry = to_entry(kobj); @@ -159,7 +157,7 @@ static void esre_release(struct kobject *kobj) static struct kobj_type esre1_ktype = { .release = esre_release, .sysfs_ops = &esre_attr_ops, - .default_groups = esre1_groups, + .default_attrs = esre1_attrs, }; diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3d972061c1..d489bdc645 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -20,10 +20,10 @@ bool efi_nochunk; bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); +bool efi_noinitrd; int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; bool efi_novamap; -static bool efi_noinitrd; static bool efi_nosoftreserve; static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA); @@ -625,47 +625,6 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, load_addr, load_size); } -static const struct { - efi_tcg2_event_t event_data; - efi_tcg2_tagged_event_t tagged_event; - u8 tagged_event_data[]; -} initrd_tcg2_event = { - { - sizeof(initrd_tcg2_event) + sizeof("Linux initrd"), - { - sizeof(initrd_tcg2_event.event_data.event_header), - EFI_TCG2_EVENT_HEADER_VERSION, - 9, - EV_EVENT_TAG, - }, - }, - { - INITRD_EVENT_TAG_ID, - sizeof("Linux initrd"), - }, - { "Linux initrd" }, -}; - -static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) -{ - efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; - efi_tcg2_protocol_t *tcg2 = NULL; - efi_status_t status; - - efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); - if (tcg2) { - status = efi_call_proto(tcg2, hash_log_extend_event, - 0, load_addr, load_size, - &initrd_tcg2_event.event_data); - if (status != EFI_SUCCESS) - efi_warn("Failed to measure initrd data: 0x%lx\n", - status); - else - efi_info("Measured initrd data into PCR %d\n", - initrd_tcg2_event.event_data.event_header.pcr_index); - } -} - /** * efi_load_initrd() - Load initial RAM disk * @image: EFI loaded image protocol @@ -684,25 +643,17 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, { efi_status_t status; - if (efi_noinitrd) { - *load_addr = *load_size = 0; - status = EFI_SUCCESS; - } else { - status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); - if (status == EFI_SUCCESS) { - efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); - if (*load_size > 0) - efi_measure_initrd(*load_addr, *load_size); - } else if (status == EFI_NOT_FOUND) { - status = efi_load_initrd_cmdline(image, load_addr, load_size, - soft_limit, hard_limit); - if (status == EFI_SUCCESS && *load_size > 0) - efi_info("Loaded initrd from command line option\n"); - } - if (status != EFI_SUCCESS) { - efi_err("Failed to load initrd: 0x%lx\n", status); - *load_addr = *load_size = 0; - } + if (!load_addr || !load_size) + return EFI_INVALID_PARAMETER; + + status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); + if (status == EFI_SUCCESS) { + efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); + } else if (status == EFI_NOT_FOUND) { + status = efi_load_initrd_cmdline(image, load_addr, load_size, + soft_limit, hard_limit); + if (status == EFI_SUCCESS && *load_size > 0) + efi_info("Loaded initrd from command line option\n"); } return status; diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index da93864d7a..26e69788f2 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -40,8 +40,6 @@ #ifdef CONFIG_ARM64 # define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64 -#elif defined(CONFIG_RISCV) -# define EFI_RT_VIRTUAL_LIMIT TASK_SIZE_MIN #else # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE #endif @@ -136,6 +134,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, enum efi_secureboot_mode secure_boot; struct screen_info *si; efi_properties_table_t *prop_tbl; + unsigned long max_addr; efi_system_table = sys_table_arg; @@ -241,8 +240,13 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, if (!fdt_addr) efi_info("Generating empty DTB\n"); - efi_load_initrd(image, &initrd_addr, &initrd_size, ULONG_MAX, - efi_get_max_initrd_addr(image_addr)); + if (!efi_noinitrd) { + max_addr = efi_get_max_initrd_addr(image_addr); + status = efi_load_initrd(image, &initrd_addr, &initrd_size, + ULONG_MAX, max_addr); + if (status != EFI_SUCCESS) + efi_err("Failed to load initrd!\n"); + } efi_random_get_seed(); diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index edb77b0621..cde0a2ef50 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -31,6 +31,7 @@ extern bool efi_nochunk; extern bool efi_nokaslr; +extern bool efi_noinitrd; extern int efi_loglevel; extern bool efi_novamap; @@ -666,29 +667,6 @@ union apple_properties_protocol { typedef u32 efi_tcg2_event_log_format; -#define INITRD_EVENT_TAG_ID 0x8F3B22ECU -#define EV_EVENT_TAG 0x00000006U -#define EFI_TCG2_EVENT_HEADER_VERSION 0x1 - -struct efi_tcg2_event { - u32 event_size; - struct { - u32 header_size; - u16 header_version; - u32 pcr_index; - u32 event_type; - } __packed event_header; - /* u8[] event follows here */ -} __packed; - -struct efi_tcg2_tagged_event { - u32 tagged_event_id; - u32 tagged_event_data_size; - /* u8 tagged event data follows here */ -} __packed; - -typedef struct efi_tcg2_event efi_tcg2_event_t; -typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; typedef union efi_tcg2_protocol efi_tcg2_protocol_t; union efi_tcg2_protocol { @@ -699,11 +677,7 @@ union efi_tcg2_protocol { efi_physical_addr_t *, efi_physical_addr_t *, efi_bool_t *); - efi_status_t (__efiapi *hash_log_extend_event)(efi_tcg2_protocol_t *, - u64, - efi_physical_addr_t, - u64, - const efi_tcg2_event_t *); + void *hash_log_extend_event; void *submit_command; void *get_active_pcr_banks; void *set_active_pcr_banks; diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c index 380e4e2513..9c46084344 100644 --- a/drivers/firmware/efi/libstub/riscv-stub.c +++ b/drivers/firmware/efi/libstub/riscv-stub.c @@ -25,7 +25,7 @@ typedef void __noreturn (*jump_kernel_func)(unsigned int, unsigned long); static u32 hartid; -static u32 get_boot_hartid_from_fdt(void) +static int get_boot_hartid_from_fdt(void) { const void *fdt; int chosen_node, len; @@ -33,23 +33,26 @@ static u32 get_boot_hartid_from_fdt(void) fdt = get_efi_config_table(DEVICE_TREE_GUID); if (!fdt) - return U32_MAX; + return -EINVAL; chosen_node = fdt_path_offset(fdt, "/chosen"); if (chosen_node < 0) - return U32_MAX; + return -EINVAL; prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); if (!prop || len != sizeof(u32)) - return U32_MAX; + return -EINVAL; - return fdt32_to_cpu(*prop); + hartid = fdt32_to_cpu(*prop); + return 0; } efi_status_t check_platform_features(void) { - hartid = get_boot_hartid_from_fdt(); - if (hartid == U32_MAX) { + int ret; + + ret = get_boot_hartid_from_fdt(); + if (ret) { efi_err("/chosen/boot-hartid missing or invalid!\n"); return EFI_UNSUPPORTED; } diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 01ddd4502e..f14c4ff583 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -673,7 +673,6 @@ unsigned long efi_main(efi_handle_t handle, unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long buffer_start, buffer_end; struct setup_header *hdr = &boot_params->hdr; - unsigned long addr, size; efi_status_t status; efi_system_table = sys_table_arg; @@ -762,15 +761,22 @@ unsigned long efi_main(efi_handle_t handle, * arguments will be processed only if image is not NULL, which will be * the case only if we were loaded via the PE entry point. */ - status = efi_load_initrd(image, &addr, &size, hdr->initrd_addr_max, - ULONG_MAX); - if (status != EFI_SUCCESS) - goto fail; - if (size > 0) { - efi_set_u64_split(addr, &hdr->ramdisk_image, - &boot_params->ext_ramdisk_image); - efi_set_u64_split(size, &hdr->ramdisk_size, - &boot_params->ext_ramdisk_size); + if (!efi_noinitrd) { + unsigned long addr, size; + + status = efi_load_initrd(image, &addr, &size, + hdr->initrd_addr_max, ULONG_MAX); + + if (status != EFI_SUCCESS) { + efi_err("Failed to load initrd!\n"); + goto fail; + } + if (size > 0) { + efi_set_u64_split(addr, &hdr->ramdisk_image, + &boot_params->ext_ramdisk_image); + efi_set_u64_split(size, &hdr->ramdisk_size, + &boot_params->ext_ramdisk_size); + } } /* diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c index 4df55a55da..2ff1883dc7 100644 --- a/drivers/firmware/efi/memmap.c +++ b/drivers/firmware/efi/memmap.c @@ -35,7 +35,7 @@ void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags) if (slab_is_available()) memblock_free_late(phys, size); else - memblock_phys_free(phys, size); + memblock_free(phys, size); } else if (flags & EFI_MEMMAP_SLAB) { struct page *p = pfn_to_page(PHYS_PFN(phys)); unsigned int order = get_order(size); diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c index 92a3d45a79..ad9ddefc9d 100644 --- a/drivers/firmware/efi/runtime-map.c +++ b/drivers/firmware/efi/runtime-map.c @@ -79,7 +79,6 @@ static struct attribute *def_attrs[] = { &map_attribute_attr.attr, NULL }; -ATTRIBUTE_GROUPS(def); static const struct sysfs_ops map_attr_ops = { .show = map_attr_show, @@ -95,7 +94,7 @@ static void map_release(struct kobject *kobj) static struct kobj_type __refdata map_ktype = { .sysfs_ops = &map_attr_ops, - .default_groups = def_groups, + .default_attrs = def_attrs, .release = map_release, }; diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index abdc8a6a39..cae590bd08 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -742,6 +742,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, { const struct efivar_operations *ops; efi_status_t status; + unsigned long varsize; if (!__efivars) return -EINVAL; @@ -764,15 +765,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, return efivar_entry_set_nonblocking(name, vendor, attributes, size, data); + varsize = size + ucs2_strsize(name, 1024); if (!block) { if (down_trylock(&efivars_lock)) return -EBUSY; + status = check_var_size_nonblocking(attributes, varsize); } else { if (down_interruptible(&efivars_lock)) return -EINTR; + status = check_var_size(attributes, varsize); } - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { up(&efivars_lock); return -ENOSPC; diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 8e59be3782..24945e2da7 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -69,7 +69,6 @@ static struct attribute *def_attrs[] = { &memmap_type_attr.attr, NULL }; -ATTRIBUTE_GROUPS(def); static const struct sysfs_ops memmap_attr_ops = { .show = memmap_attr_show, @@ -119,7 +118,7 @@ static void __meminit release_firmware_map_entry(struct kobject *kobj) static struct kobj_type __refdata memmap_ktype = { .release = release_firmware_map_entry, .sysfs_ops = &memmap_attr_ops, - .default_groups = def_groups, + .default_attrs = def_attrs, }; /* diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 7db8066b19..27a64de919 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -1348,10 +1348,6 @@ static const struct of_device_id qcom_scm_dt_match[] = { SCM_HAS_IFACE_CLK | SCM_HAS_BUS_CLK) }, - { .compatible = "qcom,scm-msm8953", .data = (void *)(SCM_HAS_CORE_CLK | - SCM_HAS_IFACE_CLK | - SCM_HAS_BUS_CLK) - }, { .compatible = "qcom,scm-msm8974", .data = (void *)(SCM_HAS_CORE_CLK | SCM_HAS_IFACE_CLK | SCM_HAS_BUS_CLK) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index a69399a6b7..f08e056ed0 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -389,12 +389,11 @@ static void fw_cfg_sysfs_cache_cleanup(void) list_for_each_entry_safe(entry, next, &fw_cfg_entry_cache, list) { fw_cfg_sysfs_cache_delist(entry); - kobject_del(&entry->kobj); kobject_put(&entry->kobj); } } -/* per-entry attributes and show methods */ +/* default_attrs: per-entry attributes and show methods */ #define FW_CFG_SYSFS_ATTR(_attr) \ struct fw_cfg_sysfs_attribute fw_cfg_sysfs_attr_##_attr = { \ @@ -427,7 +426,6 @@ static struct attribute *fw_cfg_sysfs_entry_attrs[] = { &fw_cfg_sysfs_attr_name.attr, NULL, }; -ATTRIBUTE_GROUPS(fw_cfg_sysfs_entry); /* sysfs_ops: find fw_cfg_[entry, attribute] and call appropriate show method */ static ssize_t fw_cfg_sysfs_attr_show(struct kobject *kobj, struct attribute *a, @@ -453,7 +451,7 @@ static void fw_cfg_sysfs_release_entry(struct kobject *kobj) /* kobj_type: ties together all properties required to register an entry */ static struct kobj_type fw_cfg_sysfs_entry_ktype = { - .default_groups = fw_cfg_sysfs_entry_groups, + .default_attrs = fw_cfg_sysfs_entry_attrs, .sysfs_ops = &fw_cfg_sysfs_attr_ops, .release = fw_cfg_sysfs_release_entry, }; diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 29c0a616b3..2a7687911c 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -520,7 +520,7 @@ static int svc_normal_to_secure_thread(void *data) * physical address of memory block reserved by secure monitor software at * secure world. * - * svc_normal_to_secure_shm_thread() terminates directly since it is a + * svc_normal_to_secure_shm_thread() calls do_exit() directly since it is a * standlone thread for which no one will call kthread_stop() or return when * 'kthread_should_stop()' is true. */ @@ -544,7 +544,7 @@ static int svc_normal_to_secure_shm_thread(void *data) } complete(&sh_mem->sync_complete); - return 0; + do_exit(0); } /** diff --git a/drivers/firmware/tegra/bpmp-debugfs.c b/drivers/firmware/tegra/bpmp-debugfs.c index fd89899aee..3e9fa4b543 100644 --- a/drivers/firmware/tegra/bpmp-debugfs.c +++ b/drivers/firmware/tegra/bpmp-debugfs.c @@ -74,37 +74,28 @@ static void seqbuf_seek(struct seqbuf *seqbuf, ssize_t offset) static const char *get_filename(struct tegra_bpmp *bpmp, const struct file *file, char *buf, int size) { - const char *root_path, *filename = NULL; - char *root_path_buf; + char root_path_buf[512]; + const char *root_path; + const char *filename; size_t root_len; - size_t root_path_buf_len = 512; - - root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL); - if (!root_path_buf) - goto out; root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf, - root_path_buf_len); + sizeof(root_path_buf)); if (IS_ERR(root_path)) - goto out; + return NULL; root_len = strlen(root_path); filename = dentry_path(file->f_path.dentry, buf, size); - if (IS_ERR(filename)) { - filename = NULL; - goto out; - } + if (IS_ERR(filename)) + return NULL; - if (strlen(filename) < root_len || strncmp(filename, root_path, root_len)) { - filename = NULL; - goto out; - } + if (strlen(filename) < root_len || + strncmp(filename, root_path, root_len)) + return NULL; filename += root_len; -out: - kfree(root_path_buf); return filename; } diff --git a/drivers/firmware/tegra/bpmp-tegra210.c b/drivers/firmware/tegra/bpmp-tegra210.c index c9c830f658..c32754055c 100644 --- a/drivers/firmware/tegra/bpmp-tegra210.c +++ b/drivers/firmware/tegra/bpmp-tegra210.c @@ -162,6 +162,7 @@ static int tegra210_bpmp_init(struct tegra_bpmp *bpmp) { struct platform_device *pdev = to_platform_device(bpmp->dev); struct tegra210_bpmp *priv; + struct resource *res; unsigned int i; int err; @@ -171,11 +172,13 @@ static int tegra210_bpmp_init(struct tegra_bpmp *bpmp) bpmp->priv = priv; - priv->atomics = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->atomics = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->atomics)) return PTR_ERR(priv->atomics); - priv->arb_sema = devm_platform_ioremap_resource(pdev, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + priv->arb_sema = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->arb_sema)) return PTR_ERR(priv->arb_sema); diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 5ae2040b8b..235c7e7869 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1759,7 +1759,7 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, desc->num = resp->range_num; desc->start_sec = resp->range_start_sec; desc->num_sec = resp->range_num_sec; - } + }; fail: ti_sci_put_one_xfer(&info->minfo, xfer); diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 450c5f6a1c..a3cadbaf3c 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -23,24 +23,14 @@ #include #include -#include #include "zynqmp-debug.h" /* Max HashMap Order for PM API feature check (1<<7 = 128) */ #define PM_API_FEATURE_CHECK_MAX_ORDER 7 -/* CRL registers and bitfields */ -#define CRL_APB_BASE 0xFF5E0000U -/* BOOT_PIN_CTRL- Used to control the mode pins after boot */ -#define CRL_APB_BOOT_PIN_CTRL (CRL_APB_BASE + (0x250U)) -/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */ -#define CRL_APB_BOOTPIN_CTRL_MASK 0xF0FU - static bool feature_check_enabled; static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER); -static struct platform_device *em_dev; - /** * struct pm_api_feature_data - PM API Feature data * @pm_api_id: PM API Id, used as key to index into hashmap @@ -163,7 +153,7 @@ static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2, * * Return: Returns status, either success or error+reason */ -int zynqmp_pm_feature(const u32 api_id) +static int zynqmp_pm_feature(u32 api_id) { int ret; u32 ret_payload[PAYLOAD_ARG_CNT]; @@ -200,7 +190,6 @@ int zynqmp_pm_feature(const u32 api_id) return ret; } -EXPORT_SYMBOL_GPL(zynqmp_pm_feature); /** * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer @@ -658,23 +647,6 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) } EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); -/** - * zynqmp_pm_ospi_mux_select() - OSPI Mux selection - * - * @dev_id: Device Id of the OSPI device. - * @select: OSPI Mux select value. - * - * This function select the OSPI Mux. - * - * Return: Returns status, either success or error+reason - */ -int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select) -{ - return zynqmp_pm_invoke_fn(PM_IOCTL, dev_id, IOCTL_OSPI_MUX_SELECT, - select, 0, NULL); -} -EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select); - /** * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) * @index: GGS register index @@ -953,45 +925,6 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, } EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config); -/** - * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status - * @ps_mode: Returned output value of ps_mode - * - * This API function is to be used for notify the power management controller - * to read bootpin status. - * - * Return: status, either success or error+reason - */ -unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode) -{ - unsigned int ret; - u32 ret_payload[PAYLOAD_ARG_CNT]; - - ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0, - 0, 0, ret_payload); - - *ps_mode = ret_payload[1]; - - return ret; -} -EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read); - -/** - * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin - * @ps_mode: Value to be written to the bootpin ctrl register - * - * This API function is to be used for notify the power management controller - * to configure bootpin. - * - * Return: Returns status, either success or error+reason - */ -int zynqmp_pm_bootmode_write(u32 ps_mode) -{ - return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL, - CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL); -} -EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write); - /** * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller * master has initialized its own power management @@ -1120,29 +1053,6 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out) } EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine); -/** - * zynqmp_pm_register_notifier() - PM API for register a subsystem - * to be notified about specific - * event/error. - * @node: Node ID to which the event is related. - * @event: Event Mask of Error events for which wants to get notified. - * @wake: Wake subsystem upon capturing the event if value 1 - * @enable: Enable the registration for value 1, disable for value 0 - * - * This function is used to register/un-register for particular node-event - * combination in firmware. - * - * Return: Returns status, either success or error+reason - */ - -int zynqmp_pm_register_notifier(const u32 node, const u32 event, - const u32 wake, const u32 enable) -{ - return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, node, event, - wake, enable, NULL); -} -EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier); - /** * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart * @type: Shutdown or restart? 0 for shutdown, 1 for restart @@ -1461,10 +1371,7 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) return ret; /* Check PM API version number */ - ret = zynqmp_pm_get_api_version(&pm_api_version); - if (ret) - return ret; - + zynqmp_pm_get_api_version(&pm_api_version); if (pm_api_version < ZYNQMP_PM_VERSION) { panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n", __func__, @@ -1498,15 +1405,6 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) zynqmp_pm_api_debugfs_init(); - np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); - if (np) { - em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", - -1, NULL, 0); - if (IS_ERR(em_dev)) - dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n"); - } - of_node_put(np); - return of_platform_populate(dev->of_node, NULL, NULL, dev); } @@ -1524,8 +1422,6 @@ static int zynqmp_firmware_remove(struct platform_device *pdev) kfree(feature_data); } - platform_device_unregister(em_dev); - return 0; } diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 4ffb9da537..ccf4546eff 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c @@ -652,15 +652,19 @@ static int altera_cvp_probe(struct pci_dev *pdev, snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s", ALTERA_CVP_MGR_NAME, pci_name(pdev)); - mgr = fpga_mgr_register(&pdev->dev, conf->mgr_name, - &altera_cvp_ops, conf); - if (IS_ERR(mgr)) { - ret = PTR_ERR(mgr); + mgr = devm_fpga_mgr_create(&pdev->dev, conf->mgr_name, + &altera_cvp_ops, conf); + if (!mgr) { + ret = -ENOMEM; goto err_unmap; } pci_set_drvdata(pdev, mgr); + ret = fpga_mgr_register(mgr); + if (ret) + goto err_unmap; + return 0; err_unmap: diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c index ff3a646fd9..a78e49c63c 100644 --- a/drivers/fpga/altera-fpga2sdram.c +++ b/drivers/fpga/altera-fpga2sdram.c @@ -121,13 +121,17 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev) /* Get f2s bridge configuration saved in handoff register */ regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask); - br = fpga_bridge_register(dev, F2S_BRIDGE_NAME, - &altera_fpga2sdram_br_ops, priv); - if (IS_ERR(br)) - return PTR_ERR(br); + br = devm_fpga_bridge_create(dev, F2S_BRIDGE_NAME, + &altera_fpga2sdram_br_ops, priv); + if (!br) + return -ENOMEM; platform_set_drvdata(pdev, br); + ret = fpga_bridge_register(br); + if (ret) + return ret; + dev_info(dev, "driver initialized with handoff %08x\n", priv->mask); if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) { diff --git a/drivers/fpga/altera-freeze-bridge.c b/drivers/fpga/altera-freeze-bridge.c index 445f4b0111..7d22a44d65 100644 --- a/drivers/fpga/altera-freeze-bridge.c +++ b/drivers/fpga/altera-freeze-bridge.c @@ -246,14 +246,14 @@ static int altera_freeze_br_probe(struct platform_device *pdev) priv->base_addr = base_addr; - br = fpga_bridge_register(dev, FREEZE_BRIDGE_NAME, - &altera_freeze_br_br_ops, priv); - if (IS_ERR(br)) - return PTR_ERR(br); + br = devm_fpga_bridge_create(dev, FREEZE_BRIDGE_NAME, + &altera_freeze_br_br_ops, priv); + if (!br) + return -ENOMEM; platform_set_drvdata(pdev, br); - return 0; + return fpga_bridge_register(br); } static int altera_freeze_br_remove(struct platform_device *pdev) diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c index aa758426c2..77b95f2518 100644 --- a/drivers/fpga/altera-hps2fpga.c +++ b/drivers/fpga/altera-hps2fpga.c @@ -180,15 +180,19 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev) } } - br = fpga_bridge_register(dev, priv->name, - &altera_hps2fpga_br_ops, priv); - if (IS_ERR(br)) { - ret = PTR_ERR(br); + br = devm_fpga_bridge_create(dev, priv->name, + &altera_hps2fpga_br_ops, priv); + if (!br) { + ret = -ENOMEM; goto err; } platform_set_drvdata(pdev, br); + ret = fpga_bridge_register(br); + if (ret) + goto err; + return 0; err: diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c index be0667968d..dfdf21ed34 100644 --- a/drivers/fpga/altera-pr-ip-core.c +++ b/drivers/fpga/altera-pr-ip-core.c @@ -191,8 +191,11 @@ int alt_pr_register(struct device *dev, void __iomem *reg_base) (val & ALT_PR_CSR_STATUS_MSK) >> ALT_PR_CSR_STATUS_SFT, (int)(val & ALT_PR_CSR_PR_START)); - mgr = devm_fpga_mgr_register(dev, dev_name(dev), &alt_pr_ops, priv); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, dev_name(dev), &alt_pr_ops, priv); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } EXPORT_SYMBOL_GPL(alt_pr_register); diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c index 5e1e009dba..23bfd4d1ad 100644 --- a/drivers/fpga/altera-ps-spi.c +++ b/drivers/fpga/altera-ps-spi.c @@ -302,9 +302,12 @@ static int altera_ps_probe(struct spi_device *spi) snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s", dev_driver_string(&spi->dev), dev_name(&spi->dev)); - mgr = devm_fpga_mgr_register(&spi->dev, conf->mgr_name, - &altera_ps_ops, conf); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(&spi->dev, conf->mgr_name, + &altera_ps_ops, conf); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(&spi->dev, mgr); } static const struct spi_device_id altera_ps_spi_ids[] = { diff --git a/drivers/fpga/dfl-fme-br.c b/drivers/fpga/dfl-fme-br.c index 808d1f4d76..3ff9f3a687 100644 --- a/drivers/fpga/dfl-fme-br.c +++ b/drivers/fpga/dfl-fme-br.c @@ -68,14 +68,14 @@ static int fme_br_probe(struct platform_device *pdev) priv->pdata = dev_get_platdata(dev); - br = fpga_bridge_register(dev, "DFL FPGA FME Bridge", - &fme_bridge_ops, priv); - if (IS_ERR(br)) - return PTR_ERR(br); + br = devm_fpga_bridge_create(dev, "DFL FPGA FME Bridge", + &fme_bridge_ops, priv); + if (!br) + return -ENOMEM; platform_set_drvdata(pdev, br); - return 0; + return fpga_bridge_register(br); } static int fme_br_remove(struct platform_device *pdev) diff --git a/drivers/fpga/dfl-fme-mgr.c b/drivers/fpga/dfl-fme-mgr.c index af0785783b..313420405d 100644 --- a/drivers/fpga/dfl-fme-mgr.c +++ b/drivers/fpga/dfl-fme-mgr.c @@ -276,7 +276,7 @@ static void fme_mgr_get_compat_id(void __iomem *fme_pr, static int fme_mgr_probe(struct platform_device *pdev) { struct dfl_fme_mgr_pdata *pdata = dev_get_platdata(&pdev->dev); - struct fpga_manager_info info = { 0 }; + struct fpga_compat_id *compat_id; struct device *dev = &pdev->dev; struct fme_mgr_priv *priv; struct fpga_manager *mgr; @@ -296,16 +296,20 @@ static int fme_mgr_probe(struct platform_device *pdev) return PTR_ERR(priv->ioaddr); } - info.name = "DFL FME FPGA Manager"; - info.mops = &fme_mgr_ops; - info.priv = priv; - info.compat_id = devm_kzalloc(dev, sizeof(*info.compat_id), GFP_KERNEL); - if (!info.compat_id) + compat_id = devm_kzalloc(dev, sizeof(*compat_id), GFP_KERNEL); + if (!compat_id) return -ENOMEM; - fme_mgr_get_compat_id(priv->ioaddr, info.compat_id); - mgr = devm_fpga_mgr_register_full(dev, &info); - return PTR_ERR_OR_ZERO(mgr); + fme_mgr_get_compat_id(priv->ioaddr, compat_id); + + mgr = devm_fpga_mgr_create(dev, "DFL FME FPGA Manager", + &fme_mgr_ops, priv); + if (!mgr) + return -ENOMEM; + + mgr->compat_id = compat_id; + + return devm_fpga_mgr_register(dev, mgr); } static struct platform_driver fme_mgr_driver = { diff --git a/drivers/fpga/dfl-fme-region.c b/drivers/fpga/dfl-fme-region.c index 4aebde0a7f..1eeb42af10 100644 --- a/drivers/fpga/dfl-fme-region.c +++ b/drivers/fpga/dfl-fme-region.c @@ -30,7 +30,6 @@ static int fme_region_get_bridges(struct fpga_region *region) static int fme_region_probe(struct platform_device *pdev) { struct dfl_fme_region_pdata *pdata = dev_get_platdata(&pdev->dev); - struct fpga_region_info info = { 0 }; struct device *dev = &pdev->dev; struct fpga_region *region; struct fpga_manager *mgr; @@ -40,18 +39,20 @@ static int fme_region_probe(struct platform_device *pdev) if (IS_ERR(mgr)) return -EPROBE_DEFER; - info.mgr = mgr; - info.compat_id = mgr->compat_id; - info.get_bridges = fme_region_get_bridges; - info.priv = pdata; - region = fpga_region_register_full(dev, &info); - if (IS_ERR(region)) { - ret = PTR_ERR(region); + region = devm_fpga_region_create(dev, mgr, fme_region_get_bridges); + if (!region) { + ret = -ENOMEM; goto eprobe_mgr_put; } + region->priv = pdata; + region->compat_id = mgr->compat_id; platform_set_drvdata(pdev, region); + ret = fpga_region_register(region); + if (ret) + goto eprobe_mgr_put; + dev_dbg(dev, "DFL FME FPGA Region probed\n"); return 0; diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 599bb21d86..f86666cf2c 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -1407,15 +1407,19 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info) if (!cdev) return ERR_PTR(-ENOMEM); + cdev->region = devm_fpga_region_create(info->dev, NULL, NULL); + if (!cdev->region) { + ret = -ENOMEM; + goto free_cdev_exit; + } + cdev->parent = info->dev; mutex_init(&cdev->lock); INIT_LIST_HEAD(&cdev->port_dev_list); - cdev->region = fpga_region_register(info->dev, NULL, NULL); - if (IS_ERR(cdev->region)) { - ret = PTR_ERR(cdev->region); + ret = fpga_region_register(cdev->region); + if (ret) goto free_cdev_exit; - } /* create and init build info for enumeration */ binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL); diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 16f2b164a1..798f556706 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -312,41 +312,36 @@ static struct attribute *fpga_bridge_attrs[] = { ATTRIBUTE_GROUPS(fpga_bridge); /** - * fpga_bridge_register - create and register an FPGA Bridge device + * fpga_bridge_create - create and initialize a struct fpga_bridge * @parent: FPGA bridge device from pdev * @name: FPGA bridge name * @br_ops: pointer to structure of fpga bridge ops * @priv: FPGA bridge private data * - * Return: struct fpga_bridge pointer or ERR_PTR() + * The caller of this function is responsible for freeing the bridge with + * fpga_bridge_free(). Using devm_fpga_bridge_create() instead is recommended. + * + * Return: struct fpga_bridge or NULL */ -struct fpga_bridge * -fpga_bridge_register(struct device *parent, const char *name, - const struct fpga_bridge_ops *br_ops, - void *priv) +struct fpga_bridge *fpga_bridge_create(struct device *parent, const char *name, + const struct fpga_bridge_ops *br_ops, + void *priv) { struct fpga_bridge *bridge; int id, ret; - if (!br_ops) { - dev_err(parent, "Attempt to register without fpga_bridge_ops\n"); - return ERR_PTR(-EINVAL); - } - if (!name || !strlen(name)) { dev_err(parent, "Attempt to register with no name!\n"); - return ERR_PTR(-EINVAL); + return NULL; } bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); if (!bridge) - return ERR_PTR(-ENOMEM); + return NULL; id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - ret = id; + if (id < 0) goto error_kfree; - } mutex_init(&bridge->mutex); INIT_LIST_HEAD(&bridge->node); @@ -355,23 +350,17 @@ fpga_bridge_register(struct device *parent, const char *name, bridge->br_ops = br_ops; bridge->priv = priv; + device_initialize(&bridge->dev); bridge->dev.groups = br_ops->groups; bridge->dev.class = fpga_bridge_class; bridge->dev.parent = parent; bridge->dev.of_node = parent->of_node; bridge->dev.id = id; - of_platform_populate(bridge->dev.of_node, NULL, NULL, &bridge->dev); ret = dev_set_name(&bridge->dev, "br%d", id); if (ret) goto error_device; - ret = device_register(&bridge->dev); - if (ret) { - put_device(&bridge->dev); - return ERR_PTR(ret); - } - return bridge; error_device: @@ -379,7 +368,88 @@ fpga_bridge_register(struct device *parent, const char *name, error_kfree: kfree(bridge); - return ERR_PTR(ret); + return NULL; +} +EXPORT_SYMBOL_GPL(fpga_bridge_create); + +/** + * fpga_bridge_free - free an fpga bridge created by fpga_bridge_create() + * @bridge: FPGA bridge struct + */ +void fpga_bridge_free(struct fpga_bridge *bridge) +{ + ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); + kfree(bridge); +} +EXPORT_SYMBOL_GPL(fpga_bridge_free); + +static void devm_fpga_bridge_release(struct device *dev, void *res) +{ + struct fpga_bridge *bridge = *(struct fpga_bridge **)res; + + fpga_bridge_free(bridge); +} + +/** + * devm_fpga_bridge_create - create and init a managed struct fpga_bridge + * @parent: FPGA bridge device from pdev + * @name: FPGA bridge name + * @br_ops: pointer to structure of fpga bridge ops + * @priv: FPGA bridge private data + * + * This function is intended for use in an FPGA bridge driver's probe function. + * After the bridge driver creates the struct with devm_fpga_bridge_create(), it + * should register the bridge with fpga_bridge_register(). The bridge driver's + * remove function should call fpga_bridge_unregister(). The bridge struct + * allocated with this function will be freed automatically on driver detach. + * This includes the case of a probe function returning error before calling + * fpga_bridge_register(), the struct will still get cleaned up. + * + * Return: struct fpga_bridge or NULL + */ +struct fpga_bridge +*devm_fpga_bridge_create(struct device *parent, const char *name, + const struct fpga_bridge_ops *br_ops, void *priv) +{ + struct fpga_bridge **ptr, *bridge; + + ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + bridge = fpga_bridge_create(parent, name, br_ops, priv); + if (!bridge) { + devres_free(ptr); + } else { + *ptr = bridge; + devres_add(parent, ptr); + } + + return bridge; +} +EXPORT_SYMBOL_GPL(devm_fpga_bridge_create); + +/** + * fpga_bridge_register - register an FPGA bridge + * + * @bridge: FPGA bridge struct + * + * Return: 0 for success, error code otherwise. + */ +int fpga_bridge_register(struct fpga_bridge *bridge) +{ + struct device *dev = &bridge->dev; + int ret; + + ret = device_add(dev); + if (ret) + return ret; + + of_platform_populate(dev->of_node, NULL, NULL, dev); + + dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name); + + return 0; } EXPORT_SYMBOL_GPL(fpga_bridge_register); @@ -405,10 +475,6 @@ EXPORT_SYMBOL_GPL(fpga_bridge_unregister); static void fpga_bridge_dev_release(struct device *dev) { - struct fpga_bridge *bridge = to_fpga_bridge(dev); - - ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); - kfree(bridge); } static int __init fpga_bridge_dev_init(void) diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index d49a9ce345..aa30889e23 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -592,49 +592,49 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) EXPORT_SYMBOL_GPL(fpga_mgr_unlock); /** - * fpga_mgr_register_full - create and register an FPGA Manager device + * fpga_mgr_create - create and initialize an FPGA manager struct * @parent: fpga manager device from pdev - * @info: parameters for fpga manager + * @name: fpga manager name + * @mops: pointer to structure of fpga manager ops + * @priv: fpga manager private data * - * The caller of this function is responsible for calling fpga_mgr_unregister(). - * Using devm_fpga_mgr_register_full() instead is recommended. + * The caller of this function is responsible for freeing the struct with + * fpga_mgr_free(). Using devm_fpga_mgr_create() instead is recommended. * - * Return: pointer to struct fpga_manager pointer or ERR_PTR() + * Return: pointer to struct fpga_manager or NULL */ -struct fpga_manager * -fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +struct fpga_manager *fpga_mgr_create(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, + void *priv) { - const struct fpga_manager_ops *mops = info->mops; struct fpga_manager *mgr; int id, ret; if (!mops) { dev_err(parent, "Attempt to register without fpga_manager_ops\n"); - return ERR_PTR(-EINVAL); + return NULL; } - if (!info->name || !strlen(info->name)) { + if (!name || !strlen(name)) { dev_err(parent, "Attempt to register with no name!\n"); - return ERR_PTR(-EINVAL); + return NULL; } mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); if (!mgr) - return ERR_PTR(-ENOMEM); + return NULL; id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - ret = id; + if (id < 0) goto error_kfree; - } mutex_init(&mgr->ref_mutex); - mgr->name = info->name; - mgr->mops = info->mops; - mgr->priv = info->priv; - mgr->compat_id = info->compat_id; + mgr->name = name; + mgr->mops = mops; + mgr->priv = priv; + device_initialize(&mgr->dev); mgr->dev.class = fpga_mgr_class; mgr->dev.groups = mops->groups; mgr->dev.parent = parent; @@ -645,19 +645,6 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in if (ret) goto error_device; - /* - * Initialize framework state by requesting low level driver read state - * from device. FPGA may be in reset mode or may have been programmed - * by bootloader or EEPROM. - */ - mgr->state = fpga_mgr_state(mgr); - - ret = device_register(&mgr->dev); - if (ret) { - put_device(&mgr->dev); - return ERR_PTR(ret); - } - return mgr; error_device: @@ -665,36 +652,96 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in error_kfree: kfree(mgr); - return ERR_PTR(ret); + return NULL; } -EXPORT_SYMBOL_GPL(fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(fpga_mgr_create); /** - * fpga_mgr_register - create and register an FPGA Manager device + * fpga_mgr_free - free an FPGA manager created with fpga_mgr_create() + * @mgr: fpga manager struct + */ +void fpga_mgr_free(struct fpga_manager *mgr) +{ + ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); + kfree(mgr); +} +EXPORT_SYMBOL_GPL(fpga_mgr_free); + +static void devm_fpga_mgr_release(struct device *dev, void *res) +{ + struct fpga_mgr_devres *dr = res; + + fpga_mgr_free(dr->mgr); +} + +/** + * devm_fpga_mgr_create - create and initialize a managed FPGA manager struct * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data * - * The caller of this function is responsible for calling fpga_mgr_unregister(). - * Using devm_fpga_mgr_register() instead is recommended. This simple - * version of the register function should be sufficient for most users. The - * fpga_mgr_register_full() function is available for users that need to pass - * additional, optional parameters. + * This function is intended for use in an FPGA manager driver's probe function. + * After the manager driver creates the manager struct with + * devm_fpga_mgr_create(), it should register it with fpga_mgr_register(). The + * manager driver's remove function should call fpga_mgr_unregister(). The + * manager struct allocated with this function will be freed automatically on + * driver detach. This includes the case of a probe function returning error + * before calling fpga_mgr_register(), the struct will still get cleaned up. * - * Return: pointer to struct fpga_manager pointer or ERR_PTR() + * Return: pointer to struct fpga_manager or NULL */ -struct fpga_manager * -fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) +struct fpga_manager *devm_fpga_mgr_create(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, + void *priv) { - struct fpga_manager_info info = { 0 }; + struct fpga_mgr_devres *dr; - info.name = name; - info.mops = mops; - info.priv = priv; + dr = devres_alloc(devm_fpga_mgr_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return NULL; - return fpga_mgr_register_full(parent, &info); + dr->mgr = fpga_mgr_create(parent, name, mops, priv); + if (!dr->mgr) { + devres_free(dr); + return NULL; + } + + devres_add(parent, dr); + + return dr->mgr; +} +EXPORT_SYMBOL_GPL(devm_fpga_mgr_create); + +/** + * fpga_mgr_register - register an FPGA manager + * @mgr: fpga manager struct + * + * Return: 0 on success, negative error code otherwise. + */ +int fpga_mgr_register(struct fpga_manager *mgr) +{ + int ret; + + /* + * Initialize framework state by requesting low level driver read state + * from device. FPGA may be in reset mode or may have been programmed + * by bootloader or EEPROM. + */ + mgr->state = fpga_mgr_state(mgr); + + ret = device_add(&mgr->dev); + if (ret) + goto error_device; + + dev_info(&mgr->dev, "%s registered\n", mgr->name); + + return 0; + +error_device: + ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); + + return ret; } EXPORT_SYMBOL_GPL(fpga_mgr_register); @@ -718,6 +765,14 @@ void fpga_mgr_unregister(struct fpga_manager *mgr) } EXPORT_SYMBOL_GPL(fpga_mgr_unregister); +static int fpga_mgr_devres_match(struct device *dev, void *res, + void *match_data) +{ + struct fpga_mgr_devres *dr = res; + + return match_data == dr->mgr; +} + static void devm_fpga_mgr_unregister(struct device *dev, void *res) { struct fpga_mgr_devres *dr = res; @@ -726,67 +781,45 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res) } /** - * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() - * @parent: fpga manager device from pdev - * @info: parameters for fpga manager + * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() + * @dev: managing device for this FPGA manager + * @mgr: fpga manager struct * - * This is the devres variant of fpga_mgr_register_full() for which the unregister + * This is the devres variant of fpga_mgr_register() for which the unregister * function will be called automatically when the managing device is detached. */ -struct fpga_manager * -devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +int devm_fpga_mgr_register(struct device *dev, struct fpga_manager *mgr) { struct fpga_mgr_devres *dr; - struct fpga_manager *mgr; + int ret; + + /* + * Make sure that the struct fpga_manager * that is passed in is + * managed itself. + */ + if (WARN_ON(!devres_find(dev, devm_fpga_mgr_release, + fpga_mgr_devres_match, mgr))) + return -EINVAL; dr = devres_alloc(devm_fpga_mgr_unregister, sizeof(*dr), GFP_KERNEL); if (!dr) - return ERR_PTR(-ENOMEM); + return -ENOMEM; - mgr = fpga_mgr_register_full(parent, info); - if (IS_ERR(mgr)) { + ret = fpga_mgr_register(mgr); + if (ret) { devres_free(dr); - return mgr; + return ret; } dr->mgr = mgr; - devres_add(parent, dr); + devres_add(dev, dr); - return mgr; -} -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); - -/** - * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() - * @parent: fpga manager device from pdev - * @name: fpga manager name - * @mops: pointer to structure of fpga manager ops - * @priv: fpga manager private data - * - * This is the devres variant of fpga_mgr_register() for which the - * unregister function will be called automatically when the managing - * device is detached. - */ -struct fpga_manager * -devm_fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) -{ - struct fpga_manager_info info = { 0 }; - - info.name = name; - info.mops = mops; - info.priv = priv; - - return devm_fpga_mgr_register_full(parent, &info); + return 0; } EXPORT_SYMBOL_GPL(devm_fpga_mgr_register); static void fpga_mgr_dev_release(struct device *dev) { - struct fpga_manager *mgr = to_fpga_manager(dev); - - ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); - kfree(mgr); } static int __init fpga_mgr_class_init(void) diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index b0ac18de48..a483871522 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -180,42 +180,39 @@ static struct attribute *fpga_region_attrs[] = { ATTRIBUTE_GROUPS(fpga_region); /** - * fpga_region_register_full - create and register an FPGA Region device + * fpga_region_create - alloc and init a struct fpga_region * @parent: device parent - * @info: parameters for FPGA Region + * @mgr: manager that programs this region + * @get_bridges: optional function to get bridges to a list * - * Return: struct fpga_region or ERR_PTR() + * The caller of this function is responsible for freeing the resulting region + * struct with fpga_region_free(). Using devm_fpga_region_create() instead is + * recommended. + * + * Return: struct fpga_region or NULL */ -struct fpga_region * -fpga_region_register_full(struct device *parent, const struct fpga_region_info *info) +struct fpga_region +*fpga_region_create(struct device *parent, + struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *)) { struct fpga_region *region; int id, ret = 0; - if (!info) { - dev_err(parent, - "Attempt to register without required info structure\n"); - return ERR_PTR(-EINVAL); - } - region = kzalloc(sizeof(*region), GFP_KERNEL); if (!region) - return ERR_PTR(-ENOMEM); + return NULL; id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); - if (id < 0) { - ret = id; + if (id < 0) goto err_free; - } - - region->mgr = info->mgr; - region->compat_id = info->compat_id; - region->priv = info->priv; - region->get_bridges = info->get_bridges; + region->mgr = mgr; + region->get_bridges = get_bridges; mutex_init(®ion->mutex); INIT_LIST_HEAD(®ion->bridge_list); + device_initialize(®ion->dev); region->dev.class = fpga_region_class; region->dev.parent = parent; region->dev.of_node = parent->of_node; @@ -225,12 +222,6 @@ fpga_region_register_full(struct device *parent, const struct fpga_region_info * if (ret) goto err_remove; - ret = device_register(®ion->dev); - if (ret) { - put_device(®ion->dev); - return ERR_PTR(ret); - } - return region; err_remove: @@ -238,32 +229,76 @@ fpga_region_register_full(struct device *parent, const struct fpga_region_info * err_free: kfree(region); - return ERR_PTR(ret); + return NULL; } -EXPORT_SYMBOL_GPL(fpga_region_register_full); +EXPORT_SYMBOL_GPL(fpga_region_create); /** - * fpga_region_register - create and register an FPGA Region device + * fpga_region_free - free an FPGA region created by fpga_region_create() + * @region: FPGA region + */ +void fpga_region_free(struct fpga_region *region) +{ + ida_simple_remove(&fpga_region_ida, region->dev.id); + kfree(region); +} +EXPORT_SYMBOL_GPL(fpga_region_free); + +static void devm_fpga_region_release(struct device *dev, void *res) +{ + struct fpga_region *region = *(struct fpga_region **)res; + + fpga_region_free(region); +} + +/** + * devm_fpga_region_create - create and initialize a managed FPGA region struct * @parent: device parent * @mgr: manager that programs this region * @get_bridges: optional function to get bridges to a list * - * This simple version of the register function should be sufficient for most users. - * The fpga_region_register_full() function is available for users that need to - * pass additional, optional parameters. + * This function is intended for use in an FPGA region driver's probe function. + * After the region driver creates the region struct with + * devm_fpga_region_create(), it should register it with fpga_region_register(). + * The region driver's remove function should call fpga_region_unregister(). + * The region struct allocated with this function will be freed automatically on + * driver detach. This includes the case of a probe function returning error + * before calling fpga_region_register(), the struct will still get cleaned up. * - * Return: struct fpga_region or ERR_PTR() + * Return: struct fpga_region or NULL */ -struct fpga_region * -fpga_region_register(struct device *parent, struct fpga_manager *mgr, - int (*get_bridges)(struct fpga_region *)) +struct fpga_region +*devm_fpga_region_create(struct device *parent, + struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *)) { - struct fpga_region_info info = { 0 }; + struct fpga_region **ptr, *region; - info.mgr = mgr; - info.get_bridges = get_bridges; + ptr = devres_alloc(devm_fpga_region_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; - return fpga_region_register_full(parent, &info); + region = fpga_region_create(parent, mgr, get_bridges); + if (!region) { + devres_free(ptr); + } else { + *ptr = region; + devres_add(parent, ptr); + } + + return region; +} +EXPORT_SYMBOL_GPL(devm_fpga_region_create); + +/** + * fpga_region_register - register an FPGA region + * @region: FPGA region + * + * Return: 0 or -errno + */ +int fpga_region_register(struct fpga_region *region) +{ + return device_add(®ion->dev); } EXPORT_SYMBOL_GPL(fpga_region_register); @@ -281,10 +316,6 @@ EXPORT_SYMBOL_GPL(fpga_region_unregister); static void fpga_region_dev_release(struct device *dev) { - struct fpga_region *region = to_fpga_region(dev); - - ida_simple_remove(&fpga_region_ida, region->dev.id); - kfree(region); } /** diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c index 7cbb3558b8..029d3cdb91 100644 --- a/drivers/fpga/ice40-spi.c +++ b/drivers/fpga/ice40-spi.c @@ -178,9 +178,12 @@ static int ice40_fpga_probe(struct spi_device *spi) return ret; } - mgr = devm_fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager", - &ice40_fpga_ops, priv); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, "Lattice iCE40 FPGA Manager", + &ice40_fpga_ops, priv); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } static const struct of_device_id ice40_fpga_of_match[] = { diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c index 905607992a..ea2ec3c681 100644 --- a/drivers/fpga/machxo2-spi.c +++ b/drivers/fpga/machxo2-spi.c @@ -370,9 +370,12 @@ static int machxo2_spi_probe(struct spi_device *spi) return -EINVAL; } - mgr = devm_fpga_mgr_register(dev, "Lattice MachXO2 SPI FPGA Manager", - &machxo2_ops, spi); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, "Lattice MachXO2 SPI FPGA Manager", + &machxo2_ops, spi); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } #ifdef CONFIG_OF diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 50b83057c0..e3c25576b6 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -405,12 +405,16 @@ static int of_fpga_region_probe(struct platform_device *pdev) if (IS_ERR(mgr)) return -EPROBE_DEFER; - region = fpga_region_register(dev, mgr, of_fpga_region_get_bridges); - if (IS_ERR(region)) { - ret = PTR_ERR(region); + region = devm_fpga_region_create(dev, mgr, of_fpga_region_get_bridges); + if (!region) { + ret = -ENOMEM; goto eprobe_mgr_put; } + ret = fpga_region_register(region); + if (ret) + goto eprobe_mgr_put; + of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev); platform_set_drvdata(pdev, region); @@ -444,7 +448,7 @@ static struct platform_driver of_fpga_region_driver = { }; /** - * of_fpga_region_init - init function for fpga_region class + * fpga_region_init - init function for fpga_region class * Creates the fpga_region class and registers a reconfig notifier. */ static int __init of_fpga_region_init(void) diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c index ac8e89b8a5..573d88bdf7 100644 --- a/drivers/fpga/socfpga-a10.c +++ b/drivers/fpga/socfpga-a10.c @@ -508,15 +508,19 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev) return -EBUSY; } - mgr = fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager", - &socfpga_a10_fpga_mgr_ops, priv); - if (IS_ERR(mgr)) { - clk_disable_unprepare(priv->clk); - return PTR_ERR(mgr); - } + mgr = devm_fpga_mgr_create(dev, "SoCFPGA Arria10 FPGA Manager", + &socfpga_a10_fpga_mgr_ops, priv); + if (!mgr) + return -ENOMEM; platform_set_drvdata(pdev, mgr); + ret = fpga_mgr_register(mgr); + if (ret) { + clk_disable_unprepare(priv->clk); + return ret; + } + return 0; } diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c index 7e0741f996..1f467173fc 100644 --- a/drivers/fpga/socfpga.c +++ b/drivers/fpga/socfpga.c @@ -571,9 +571,12 @@ static int socfpga_fpga_probe(struct platform_device *pdev) if (ret) return ret; - mgr = devm_fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager", - &socfpga_fpga_ops, priv); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager", + &socfpga_fpga_ops, priv); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } #ifdef CONFIG_OF diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index 357cea58ec..047fd7f237 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -419,16 +419,23 @@ static int s10_probe(struct platform_device *pdev) init_completion(&priv->status_return_completion); - mgr = fpga_mgr_register(dev, "Stratix10 SOC FPGA Manager", - &s10_ops, priv); - if (IS_ERR(mgr)) { + mgr = fpga_mgr_create(dev, "Stratix10 SOC FPGA Manager", + &s10_ops, priv); + if (!mgr) { + dev_err(dev, "unable to create FPGA manager\n"); + ret = -ENOMEM; + goto probe_err; + } + + ret = fpga_mgr_register(mgr); + if (ret) { dev_err(dev, "unable to register FPGA manager\n"); - ret = PTR_ERR(mgr); + fpga_mgr_free(mgr); goto probe_err; } platform_set_drvdata(pdev, mgr); - return 0; + return ret; probe_err: stratix10_svc_free_channel(priv->chan); @@ -441,6 +448,7 @@ static int s10_remove(struct platform_device *pdev) struct s10_priv *priv = mgr->priv; fpga_mgr_unregister(mgr); + fpga_mgr_free(mgr); stratix10_svc_free_channel(priv->chan); return 0; diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c index 8e6e9c840d..167abb0b08 100644 --- a/drivers/fpga/ts73xx-fpga.c +++ b/drivers/fpga/ts73xx-fpga.c @@ -116,9 +116,12 @@ static int ts73xx_fpga_probe(struct platform_device *pdev) if (IS_ERR(priv->io_base)) return PTR_ERR(priv->io_base); - mgr = devm_fpga_mgr_register(kdev, "TS-73xx FPGA Manager", - &ts73xx_fpga_ops, priv); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(kdev, "TS-73xx FPGA Manager", + &ts73xx_fpga_ops, priv); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(kdev, mgr); } static struct platform_driver ts73xx_fpga_driver = { diff --git a/drivers/fpga/versal-fpga.c b/drivers/fpga/versal-fpga.c index e1601b3a34..5b0dda304b 100644 --- a/drivers/fpga/versal-fpga.c +++ b/drivers/fpga/versal-fpga.c @@ -54,9 +54,12 @@ static int versal_fpga_probe(struct platform_device *pdev) return ret; } - mgr = devm_fpga_mgr_register(dev, "Xilinx Versal FPGA Manager", - &versal_fpga_ops, NULL); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, "Xilinx Versal FPGA Manager", + &versal_fpga_ops, NULL); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } static const struct of_device_id versal_fpga_of_match[] = { diff --git a/drivers/fpga/xilinx-pr-decoupler.c b/drivers/fpga/xilinx-pr-decoupler.c index 2d9c491f7b..e986ed47c4 100644 --- a/drivers/fpga/xilinx-pr-decoupler.c +++ b/drivers/fpga/xilinx-pr-decoupler.c @@ -140,17 +140,22 @@ static int xlnx_pr_decoupler_probe(struct platform_device *pdev) clk_disable(priv->clk); - br = fpga_bridge_register(&pdev->dev, priv->ipconfig->name, - &xlnx_pr_decoupler_br_ops, priv); - if (IS_ERR(br)) { - err = PTR_ERR(br); - dev_err(&pdev->dev, "unable to register %s", - priv->ipconfig->name); + br = devm_fpga_bridge_create(&pdev->dev, priv->ipconfig->name, + &xlnx_pr_decoupler_br_ops, priv); + if (!br) { + err = -ENOMEM; goto err_clk; } platform_set_drvdata(pdev, br); + err = fpga_bridge_register(br); + if (err) { + dev_err(&pdev->dev, "unable to register %s", + priv->ipconfig->name); + goto err_clk; + } + return 0; err_clk: diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c index e1a227e7ff..b6bcf1d923 100644 --- a/drivers/fpga/xilinx-spi.c +++ b/drivers/fpga/xilinx-spi.c @@ -247,10 +247,13 @@ static int xilinx_spi_probe(struct spi_device *spi) return dev_err_probe(&spi->dev, PTR_ERR(conf->done), "Failed to get DONE gpio\n"); - mgr = devm_fpga_mgr_register(&spi->dev, - "Xilinx Slave Serial FPGA Manager", - &xilinx_spi_ops, conf); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(&spi->dev, + "Xilinx Slave Serial FPGA Manager", + &xilinx_spi_ops, conf); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(&spi->dev, mgr); } #ifdef CONFIG_OF diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index 426aa34c6a..9b75bd4f93 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -609,16 +609,20 @@ static int zynq_fpga_probe(struct platform_device *pdev) clk_disable(priv->clk); - mgr = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", - &zynq_fpga_ops, priv); - if (IS_ERR(mgr)) { - dev_err(dev, "unable to register FPGA manager\n"); - clk_unprepare(priv->clk); - return PTR_ERR(mgr); - } + mgr = devm_fpga_mgr_create(dev, "Xilinx Zynq FPGA Manager", + &zynq_fpga_ops, priv); + if (!mgr) + return -ENOMEM; platform_set_drvdata(pdev, mgr); + err = fpga_mgr_register(mgr); + if (err) { + dev_err(dev, "unable to register FPGA manager\n"); + clk_unprepare(priv->clk); + return err; + } + return 0; } diff --git a/drivers/fpga/zynqmp-fpga.c b/drivers/fpga/zynqmp-fpga.c index c60f20949c..7d3d5650c3 100644 --- a/drivers/fpga/zynqmp-fpga.c +++ b/drivers/fpga/zynqmp-fpga.c @@ -95,9 +95,12 @@ static int zynqmp_fpga_probe(struct platform_device *pdev) priv->dev = dev; - mgr = devm_fpga_mgr_register(dev, "Xilinx ZynqMP FPGA Manager", - &zynqmp_fpga_ops, priv); - return PTR_ERR_OR_ZERO(mgr); + mgr = devm_fpga_mgr_create(dev, "Xilinx ZynqMP FPGA Manager", + &zynqmp_fpga_ops, priv); + if (!mgr) + return -ENOMEM; + + return devm_fpga_mgr_register(dev, mgr); } #ifdef CONFIG_OF diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index 7eaab1be0a..b223f0ef33 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,13 @@ #define OCC_P10_SRAM_MODE 0x58 /* Normal mode, OCB channel 2 */ +/* + * Assume we don't have much FFDC, if we do we'll overflow and + * fail the command. This needs to be big enough for simple + * commands as well. + */ +#define OCC_SBE_STATUS_WORDS 32 + #define OCC_TIMEOUT_MS 1000 #define OCC_CMD_IN_PRG_WAIT_MS 50 @@ -44,11 +50,6 @@ struct occ { struct device *sbefifo; char name[32]; int idx; - u8 sequence_number; - void *buffer; - void *client_buffer; - size_t client_buffer_size; - size_t client_response_size; enum versions version; struct miscdevice mdev; struct mutex occ_lock; @@ -140,7 +141,8 @@ static ssize_t occ_write(struct file *file, const char __user *buf, { struct occ_client *client = file->private_data; size_t rlen, data_length; - ssize_t rc; + u16 checksum = 0; + ssize_t rc, i; u8 *cmd; if (!client) @@ -154,6 +156,9 @@ static ssize_t occ_write(struct file *file, const char __user *buf, /* Construct the command */ cmd = client->buffer; + /* Sequence number (we could increment and compare with response) */ + cmd[0] = 1; + /* * Copy the user command (assume user data follows the occ command * format) @@ -173,7 +178,14 @@ static ssize_t occ_write(struct file *file, const char __user *buf, goto done; } - /* Submit command; 4 bytes before the data and 2 bytes after */ + /* Calculate checksum */ + for (i = 0; i < data_length + 4; ++i) + checksum += cmd[i]; + + cmd[data_length + 4] = checksum >> 8; + cmd[data_length + 5] = checksum & 0xFF; + + /* Submit command */ rlen = PAGE_SIZE; rc = fsi_occ_submit(client->occ->dev, cmd, data_length + 6, cmd, &rlen); @@ -211,22 +223,6 @@ static const struct file_operations occ_fops = { .release = occ_release, }; -static void occ_save_ffdc(struct occ *occ, __be32 *resp, size_t parsed_len, - size_t resp_len) -{ - if (resp_len > parsed_len) { - size_t dh = resp_len - parsed_len; - size_t ffdc_len = (dh - 1) * 4; /* SBE words are four bytes */ - __be32 *ffdc = &resp[parsed_len]; - - if (ffdc_len > occ->client_buffer_size) - ffdc_len = occ->client_buffer_size; - - memcpy(occ->client_buffer, ffdc, ffdc_len); - occ->client_response_size = ffdc_len; - } -} - static int occ_verify_checksum(struct occ *occ, struct occ_response *resp, u16 data_length) { @@ -255,10 +251,8 @@ static int occ_verify_checksum(struct occ *occ, struct occ_response *resp, static int occ_getsram(struct occ *occ, u32 offset, void *data, ssize_t len) { u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */ - size_t cmd_len, parsed_len, resp_data_len; - size_t resp_len = OCC_MAX_RESP_WORDS; - __be32 *resp = occ->buffer; - __be32 cmd[6]; + size_t cmd_len, resp_len, resp_data_len; + __be32 *resp, cmd[6]; int idx = 0, rc; /* @@ -285,22 +279,21 @@ static int occ_getsram(struct occ *occ, u32 offset, void *data, ssize_t len) cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_OCC_SRAM); cmd[4 + idx] = cpu_to_be32(data_len); + resp_len = (data_len >> 2) + OCC_SBE_STATUS_WORDS; + resp = kzalloc(resp_len << 2, GFP_KERNEL); + if (!resp) + return -ENOMEM; + rc = sbefifo_submit(occ->sbefifo, cmd, cmd_len, resp, &resp_len); if (rc) - return rc; + goto free; rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_GET_OCC_SRAM, - resp, resp_len, &parsed_len); - if (rc > 0) { - dev_err(occ->dev, "SRAM read returned failure status: %08x\n", - rc); - occ_save_ffdc(occ, resp, parsed_len, resp_len); - return -ECOMM; - } else if (rc) { - return rc; - } + resp, resp_len, &resp_len); + if (rc) + goto free; - resp_data_len = be32_to_cpu(resp[parsed_len - 1]); + resp_data_len = be32_to_cpu(resp[resp_len - 1]); if (resp_data_len != data_len) { dev_err(occ->dev, "SRAM read expected %d bytes got %zd\n", data_len, resp_data_len); @@ -309,21 +302,37 @@ static int occ_getsram(struct occ *occ, u32 offset, void *data, ssize_t len) memcpy(data, resp, len); } +free: + /* Convert positive SBEI status */ + if (rc > 0) { + dev_err(occ->dev, "SRAM read returned failure status: %08x\n", + rc); + rc = -EBADMSG; + } + + kfree(resp); return rc; } -static int occ_putsram(struct occ *occ, const void *data, ssize_t len, - u8 seq_no, u16 checksum) +static int occ_putsram(struct occ *occ, const void *data, ssize_t len) { + size_t cmd_len, buf_len, resp_len, resp_data_len; u32 data_len = ((len + 7) / 8) * 8; /* must be multiples of 8 B */ - size_t cmd_len, parsed_len, resp_data_len; - size_t resp_len = OCC_MAX_RESP_WORDS; - __be32 *buf = occ->buffer; - u8 *byte_buf; + __be32 *buf; int idx = 0, rc; cmd_len = (occ->version == occ_p10) ? 6 : 5; + + /* + * We use the same buffer for command and response, make + * sure it's big enough + */ + resp_len = OCC_SBE_STATUS_WORDS; cmd_len += data_len >> 2; + buf_len = max(cmd_len, resp_len); + buf = kzalloc(buf_len << 2, GFP_KERNEL); + if (!buf) + return -ENOMEM; /* * Magic sequence to do SBE putsram command. SBE will transfer @@ -349,33 +358,18 @@ static int occ_putsram(struct occ *occ, const void *data, ssize_t len, buf[4 + idx] = cpu_to_be32(data_len); memcpy(&buf[5 + idx], data, len); - byte_buf = (u8 *)&buf[5 + idx]; - /* - * Overwrite the first byte with our sequence number and the last two - * bytes with the checksum. - */ - byte_buf[0] = seq_no; - byte_buf[len - 2] = checksum >> 8; - byte_buf[len - 1] = checksum & 0xff; - rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len); if (rc) - return rc; + goto free; rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM, - buf, resp_len, &parsed_len); - if (rc > 0) { - dev_err(occ->dev, "SRAM write returned failure status: %08x\n", - rc); - occ_save_ffdc(occ, buf, parsed_len, resp_len); - return -ECOMM; - } else if (rc) { - return rc; - } + buf, resp_len, &resp_len); + if (rc) + goto free; - if (parsed_len != 1) { + if (resp_len != 1) { dev_err(occ->dev, "SRAM write response length invalid: %zd\n", - parsed_len); + resp_len); rc = -EBADMSG; } else { resp_data_len = be32_to_cpu(buf[0]); @@ -387,16 +381,27 @@ static int occ_putsram(struct occ *occ, const void *data, ssize_t len, } } +free: + /* Convert positive SBEI status */ + if (rc > 0) { + dev_err(occ->dev, "SRAM write returned failure status: %08x\n", + rc); + rc = -EBADMSG; + } + + kfree(buf); return rc; } static int occ_trigger_attn(struct occ *occ) { - __be32 *buf = occ->buffer; - size_t cmd_len, parsed_len, resp_data_len; - size_t resp_len = OCC_MAX_RESP_WORDS; + __be32 buf[OCC_SBE_STATUS_WORDS]; + size_t cmd_len, resp_len, resp_data_len; int idx = 0, rc; + BUILD_BUG_ON(OCC_SBE_STATUS_WORDS < 8); + resp_len = OCC_SBE_STATUS_WORDS; + switch (occ->version) { default: case occ_p9: @@ -421,22 +426,16 @@ static int occ_trigger_attn(struct occ *occ) rc = sbefifo_submit(occ->sbefifo, buf, cmd_len, buf, &resp_len); if (rc) - return rc; + goto error; rc = sbefifo_parse_status(occ->sbefifo, SBEFIFO_CMD_PUT_OCC_SRAM, - buf, resp_len, &parsed_len); - if (rc > 0) { - dev_err(occ->dev, "SRAM attn returned failure status: %08x\n", - rc); - occ_save_ffdc(occ, buf, parsed_len, resp_len); - return -ECOMM; - } else if (rc) { - return rc; - } + buf, resp_len, &resp_len); + if (rc) + goto error; - if (parsed_len != 1) { + if (resp_len != 1) { dev_err(occ->dev, "SRAM attn response length invalid: %zd\n", - parsed_len); + resp_len); rc = -EBADMSG; } else { resp_data_len = be32_to_cpu(buf[0]); @@ -448,6 +447,14 @@ static int occ_trigger_attn(struct occ *occ) } } + error: + /* Convert positive SBEI status */ + if (rc > 0) { + dev_err(occ->dev, "SRAM attn returned failure status: %08x\n", + rc); + rc = -EBADMSG; + } + return rc; } @@ -459,49 +466,24 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS); struct occ *occ = dev_get_drvdata(dev); struct occ_response *resp = response; - size_t user_resp_len = *resp_len; u8 seq_no; - u16 checksum = 0; u16 resp_data_length; - const u8 *byte_request = (const u8 *)request; unsigned long start; int rc; - size_t i; - - *resp_len = 0; if (!occ) return -ENODEV; - if (user_resp_len < 7) { - dev_dbg(dev, "Bad resplen %zd\n", user_resp_len); + if (*resp_len < 7) { + dev_dbg(dev, "Bad resplen %zd\n", *resp_len); return -EINVAL; } - /* Checksum the request, ignoring first byte (sequence number). */ - for (i = 1; i < req_len - 2; ++i) - checksum += byte_request[i]; - mutex_lock(&occ->occ_lock); - occ->client_buffer = response; - occ->client_buffer_size = user_resp_len; - occ->client_response_size = 0; - - /* - * Get a sequence number and update the counter. Avoid a sequence - * number of 0 which would pass the response check below even if the - * OCC response is uninitialized. Any sequence number the user is - * trying to send is overwritten since this function is the only common - * interface to the OCC and therefore the only place we can guarantee - * unique sequence numbers. - */ - seq_no = occ->sequence_number++; - if (!occ->sequence_number) - occ->sequence_number = 1; - checksum += seq_no; - - rc = occ_putsram(occ, request, req_len, seq_no, checksum); + /* Extract the seq_no from the command (first byte) */ + seq_no = *(const u8 *)request; + rc = occ_putsram(occ, request, req_len); if (rc) goto done; @@ -538,7 +520,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, resp_data_length = get_unaligned_be16(&resp->data_length); /* Message size is data length + 5 bytes header + 2 bytes checksum */ - if ((resp_data_length + 7) > user_resp_len) { + if ((resp_data_length + 7) > *resp_len) { rc = -EMSGSIZE; goto done; } @@ -554,11 +536,10 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, goto done; } - occ->client_response_size = resp_data_length + 7; + *resp_len = resp_data_length + 7; rc = occ_verify_checksum(occ, resp, resp_data_length); done: - *resp_len = occ->client_response_size; mutex_unlock(&occ->occ_lock); return rc; @@ -590,15 +571,9 @@ static int occ_probe(struct platform_device *pdev) if (!occ) return -ENOMEM; - /* SBE words are always four bytes */ - occ->buffer = kvmalloc(OCC_MAX_RESP_WORDS * 4, GFP_KERNEL); - if (!occ->buffer) - return -ENOMEM; - occ->version = (uintptr_t)of_device_get_match_data(dev); occ->dev = dev; occ->sbefifo = dev->parent; - occ->sequence_number = 1; mutex_init(&occ->occ_lock); if (dev->of_node) { @@ -630,7 +605,6 @@ static int occ_probe(struct platform_device *pdev) if (rc) { dev_err(dev, "failed to register miscdevice: %d\n", rc); ida_simple_remove(&occ_ida, occ->idx); - kvfree(occ->buffer); return rc; } @@ -646,8 +620,6 @@ static int occ_remove(struct platform_device *pdev) { struct occ *occ = platform_get_drvdata(pdev); - kvfree(occ->buffer); - misc_deregister(&occ->mdev); device_for_each_child(&pdev->dev, NULL, occ_unregister_child); diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index 52328adef6..84cb965bfe 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -124,7 +124,6 @@ struct sbefifo { bool broken; bool dead; bool async_ffdc; - bool timed_out; }; struct sbefifo_user { @@ -137,14 +136,6 @@ struct sbefifo_user { static DEFINE_MUTEX(sbefifo_ffdc_mutex); -static ssize_t timeout_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct sbefifo *sbefifo = container_of(dev, struct sbefifo, dev); - - return sysfs_emit(buf, "%d\n", sbefifo->timed_out ? 1 : 0); -} -static DEVICE_ATTR_RO(timeout); static void __sbefifo_dump_ffdc(struct device *dev, const __be32 *ffdc, size_t ffdc_sz, bool internal) @@ -471,14 +462,11 @@ static int sbefifo_wait(struct sbefifo *sbefifo, bool up, break; } if (!ready) { - sysfs_notify(&sbefifo->dev.kobj, NULL, dev_attr_timeout.attr.name); - sbefifo->timed_out = true; dev_err(dev, "%s FIFO Timeout ! status=%08x\n", up ? "UP" : "DOWN", sts); return -ETIMEDOUT; } dev_vdbg(dev, "End of wait status: %08x\n", sts); - sbefifo->timed_out = false; *status = sts; return 0; @@ -752,9 +740,7 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes); /* Perform the command */ - rc = mutex_lock_interruptible(&sbefifo->lock); - if (rc) - return rc; + mutex_lock(&sbefifo->lock); rc = __sbefifo_submit(sbefifo, command, cmd_len, &resp_iter); mutex_unlock(&sbefifo->lock); @@ -834,9 +820,7 @@ static ssize_t sbefifo_user_read(struct file *file, char __user *buf, iov_iter_init(&resp_iter, WRITE, &resp_iov, 1, len); /* Perform the command */ - rc = mutex_lock_interruptible(&sbefifo->lock); - if (rc) - goto bail; + mutex_lock(&sbefifo->lock); rc = __sbefifo_submit(sbefifo, user->pending_cmd, cmd_len, &resp_iter); mutex_unlock(&sbefifo->lock); if (rc < 0) @@ -891,9 +875,7 @@ static ssize_t sbefifo_user_write(struct file *file, const char __user *buf, user->pending_len = 0; /* Trigger reset request */ - rc = mutex_lock_interruptible(&sbefifo->lock); - if (rc) - goto bail; + mutex_lock(&sbefifo->lock); rc = sbefifo_request_reset(user->sbefifo); mutex_unlock(&sbefifo->lock); if (rc == 0) @@ -1011,8 +993,6 @@ static int sbefifo_probe(struct device *dev) child_name); } - device_create_file(&sbefifo->dev, &dev_attr_timeout); - return 0; err_free_minor: fsi_free_minor(sbefifo->dev.devt); @@ -1038,8 +1018,6 @@ static int sbefifo_remove(struct device *dev) dev_dbg(dev, "Removing sbefifo device...\n"); - device_remove_file(&sbefifo->dev, &dev_attr_timeout); - mutex_lock(&sbefifo->lock); sbefifo->dead = true; mutex_unlock(&sbefifo->lock); diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index d7fe265c28..bd12e3d57b 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -54,15 +54,4 @@ config GNSS_UBX_SERIAL If unsure, say N. -config GNSS_USB - tristate "USB GNSS receiver support" - depends on USB - help - Say Y here if you have a GNSS receiver which uses a USB interface. - - To compile this driver as a module, choose M here: the module will - be called gnss-usb. - - If unsure, say N. - endif # GNSS diff --git a/drivers/gnss/Makefile b/drivers/gnss/Makefile index bb2cbada34..451f11401e 100644 --- a/drivers/gnss/Makefile +++ b/drivers/gnss/Makefile @@ -17,6 +17,3 @@ gnss-sirf-y := sirf.o obj-$(CONFIG_GNSS_UBX_SERIAL) += gnss-ubx.o gnss-ubx-y := ubx.o - -obj-$(CONFIG_GNSS_USB) += gnss-usb.o -gnss-usb-y := usb.o diff --git a/drivers/gnss/mtk.c b/drivers/gnss/mtk.c index c62b1211f4..d1fc55560d 100644 --- a/drivers/gnss/mtk.c +++ b/drivers/gnss/mtk.c @@ -126,7 +126,7 @@ static void mtk_remove(struct serdev_device *serdev) if (data->vbackup) regulator_disable(data->vbackup); gnss_serial_free(gserial); -} +}; #ifdef CONFIG_OF static const struct of_device_id mtk_of_match[] = { diff --git a/drivers/gnss/serial.c b/drivers/gnss/serial.c index 5d8e9bfb24..def64b36d9 100644 --- a/drivers/gnss/serial.c +++ b/drivers/gnss/serial.c @@ -165,7 +165,7 @@ void gnss_serial_free(struct gnss_serial *gserial) { gnss_put_device(gserial->gdev); kfree(gserial); -} +}; EXPORT_SYMBOL_GPL(gnss_serial_free); int gnss_serial_register(struct gnss_serial *gserial) diff --git a/drivers/gnss/sirf.c b/drivers/gnss/sirf.c index bcb53ccfee..2ecb1d3e8e 100644 --- a/drivers/gnss/sirf.c +++ b/drivers/gnss/sirf.c @@ -551,7 +551,7 @@ static void sirf_remove(struct serdev_device *serdev) regulator_disable(data->vcc); gnss_put_device(data->gdev); -} +}; #ifdef CONFIG_OF static const struct of_device_id sirf_of_match[] = { diff --git a/drivers/gnss/ubx.c b/drivers/gnss/ubx.c index c951be202c..7b05bc4053 100644 --- a/drivers/gnss/ubx.c +++ b/drivers/gnss/ubx.c @@ -126,7 +126,7 @@ static void ubx_remove(struct serdev_device *serdev) if (data->v_bckp) regulator_disable(data->v_bckp); gnss_serial_free(gserial); -} +}; #ifdef CONFIG_OF static const struct of_device_id ubx_of_match[] = { diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1fa0f69a82..addea3aaa1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -15,7 +15,7 @@ menuconfig GPIOLIB bool "GPIO Support" help This enables GPIO support through the generic GPIO library. - You only need to enable this if you also want to enable + You only need to enable this, if you also want to enable one or more of the GPIO drivers below. If unsure, say N. @@ -140,8 +140,8 @@ config GPIO_AMDPT depends on ACPI select GPIO_GENERIC help - Driver for GPIO functionality on Promontory IOHub. - Requires ACPI ASL code to enumerate as a platform device. + driver for GPIO functionality on Promontory IOHub + Require ACPI ASL code to enumerate as a platform device. config GPIO_ASPEED tristate "Aspeed GPIO support" @@ -312,7 +312,7 @@ config GPIO_HISI help Say Y or M here to build support for the HiSilicon GPIO controller driver GPIO block. - This GPIO controller supports double-edge interrupt and multi-core + This GPIO controller support double-edge interrupt and multi-core concurrent access. config GPIO_HLWD @@ -332,7 +332,7 @@ config GPIO_ICH help Say yes here to support the GPIO functionality of a number of Intel ICH-based chipsets. Currently supported devices: ICH6, ICH7, ICH8 - ICH9, ICH10, Series 5/3400 (e.g. Ibex Peak), Series 6/C200 (e.g. + ICH9, ICH10, Series 5/3400 (eg Ibex Peak), Series 6/C200 (eg Cougar Point), NM10 (Tiger Point), and 3100 (Whitmore Lake). If unsure, say N. @@ -343,7 +343,7 @@ config GPIO_IOP select GPIO_GENERIC help Say yes here to support the GPIO functionality of a number of Intel - IOP32X or IOP33X series of chips. + IOP32X or IOP33X. If unsure, say N. @@ -370,7 +370,7 @@ config GPIO_LOONGSON bool "Loongson-2/3 GPIO support" depends on CPU_LOONGSON2EF || CPU_LOONGSON64 help - Driver for GPIO functionality on Loongson-2F/3A/3B processors. + driver for GPIO functionality on Loongson-2F/3A/3B processors. config GPIO_LPC18XX tristate "NXP LPC18XX/43XX GPIO support" @@ -398,15 +398,15 @@ config GPIO_MENZ127 depends on MCB select GPIO_GENERIC help - Say yes here to support the MEN 16Z127 GPIO Controller. + Say yes here to support the MEN 16Z127 GPIO Controller config GPIO_MM_LANTIQ bool "Lantiq Memory mapped GPIOs" depends on LANTIQ && SOC_XWAY help This enables support for memory mapped GPIOs on the External Bus Unit - (EBU) found on Lantiq SoCs. The GPIOs are output only as they are - created by attaching a 16-bit latch to the bus. + (EBU) found on Lantiq SoCs. The gpios are output only as they are + created by attaching a 16bit latch to the bus. config GPIO_MPC5200 def_bool y @@ -430,7 +430,7 @@ config GPIO_MT7621 select GPIO_GENERIC select GPIOLIB_IRQCHIP help - Say yes here to support the Mediatek MT7621 SoC GPIO device. + Say yes here to support the Mediatek MT7621 SoC GPIO device config GPIO_MVEBU def_bool y @@ -475,7 +475,7 @@ config GPIO_PL061 select IRQ_DOMAIN select GPIOLIB_IRQCHIP help - Say yes here to support the PrimeCell PL061 GPIO device. + Say yes here to support the PrimeCell PL061 GPIO device config GPIO_PMIC_EIC_SPRD tristate "Spreadtrum PMIC EIC support" @@ -497,7 +497,7 @@ config GPIO_PXA bool "PXA GPIO support" depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST help - Say yes here to support the PXA GPIO device. + Say yes here to support the PXA GPIO device config GPIO_RCAR tristate "Renesas R-Car and RZ/G GPIO support" @@ -588,7 +588,7 @@ config GPIO_SPEAR_SPICS depends on PLAT_SPEAR select GENERIC_IRQ_CHIP help - Say yes here to support ST SPEAr SPI Chip Select as GPIO device. + Say yes here to support ST SPEAr SPI Chip Select as GPIO device config GPIO_SPRD tristate "Spreadtrum GPIO support" @@ -613,8 +613,8 @@ config GPIO_STP_XWAY help This enables support for the Serial To Parallel (STP) unit found on XWAY SoC. The STP allows the SoC to drive a shift registers cascade, - that can be up to 24 bits. This peripheral is aimed at driving LEDs. - Some of the GPIOs/LEDs can be auto updated by the SoC with DSL and + that can be up to 24 bit. This peripheral is aimed at driving leds. + Some of the gpios/leds can be auto updated by the soc with dsl and phy status. config GPIO_SYSCON @@ -694,10 +694,10 @@ config GPIO_VISCONTI Say yes here to support GPIO on Tohisba Visconti. config GPIO_VR41XX - tristate "NEC VR4100 series General-purpose I/O Unit support" + tristate "NEC VR4100 series General-purpose I/O Uint support" depends on CPU_VR41XX help - Say yes here to support the NEC VR4100 series General-purpose I/O Unit. + Say yes here to support the NEC VR4100 series General-purpose I/O Uint config GPIO_VX855 tristate "VIA VX855/VX875 GPIO" @@ -705,14 +705,14 @@ config GPIO_VX855 select MFD_CORE select MFD_VX855 help - Support access to the VX855/VX875 GPIO lines through the GPIO library. + Support access to the VX855/VX875 GPIO lines through the gpio library. - This driver provides common support for accessing the device. - Additional drivers must be enabled in order to use the + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the functionality of the device. config GPIO_WCD934X - tristate "Qualcomm Technologies Inc WCD9340/WCD9341 GPIO controller driver" + tristate "Qualcomm Technologies Inc WCD9340/WCD9341 gpio controller driver" depends on MFD_WCD934X && OF_GPIO help This driver is to support GPIO block found on the Qualcomm Technologies @@ -742,15 +742,17 @@ config GPIO_XILINX select GPIOLIB_IRQCHIP depends on OF_GPIO help - Say yes here to support the Xilinx FPGA GPIO device. + Say yes here to support the Xilinx FPGA GPIO device config GPIO_XLP - tristate "Cavium ThunderX2 GPIO support" - depends on ARCH_THUNDER2 || COMPILE_TEST + tristate "Netlogic XLP GPIO support" + depends on OF_GPIO && (CPU_XLP || ARCH_THUNDER2 || COMPILE_TEST) select GPIOLIB_IRQCHIP help - This driver provides support for GPIO interface on Cavium's ThunderX2 - CN99XX SoCs (Originally from Netlogic XLP). + This driver provides support for GPIO interface on Netlogic XLP MIPS64 + SoCs. Currently supported XLP variants are XLP8XX, XLP3XX, XLP2XX, + XLP9XX and XLP5XX. The same GPIO controller block is also present in + Cavium's ThunderX2 CN99XX SoCs. If unsure, say N. @@ -761,7 +763,7 @@ config GPIO_XTENSA depends on !SMP help Say yes here to support the Xtensa internal GPIO32 IMPWIRE (input) - and EXPSTATE (output) ports. + and EXPSTATE (output) ports config GPIO_ZEVIO bool "LSI ZEVIO SoC memory mapped GPIOs" @@ -776,18 +778,6 @@ config GPIO_ZYNQ help Say yes here to support Xilinx Zynq GPIO controller. -config GPIO_ZYNQMP_MODEPIN - tristate "ZynqMP ps-mode pin GPIO configuration driver" - depends on ZYNQMP_FIRMWARE - default ZYNQMP_FIRMWARE - help - Say yes here to support the ZynqMP ps-mode pin GPIO configuration - driver. - - This ps-mode pin GPIO driver is based on GPIO framework. PS_MODE - is 4-bits boot mode pins. It sets and gets the status of - the ps-mode pin. Every pin can be configured as input/output. - config GPIO_LOONGSON1 tristate "Loongson1 GPIO support" depends on MACH_LOONGSON32 @@ -798,12 +788,12 @@ config GPIO_LOONGSON1 config GPIO_AMD_FCH tristate "GPIO support for AMD Fusion Controller Hub (G-series SOCs)" help - This option enables driver for GPIO on AMD's Fusion Controller Hub, - as found on G-series SOCs (e.g. GX-412TC). + This option enables driver for GPIO on AMDs Fusion Controller Hub, + as found on G-series SOCs (eg. GX-412TC) - Note: This driver doesn't register itself automatically, as it - needs to be provided with platform-specific configuration. - (See e.g. CONFIG_PCENGINES_APU2.) + Note: This driver doesn't registers itself automatically, as it + needs to be provided with platform specific configuration. + (See eg. CONFIG_PCENGINES_APU2.) config GPIO_MSC313 bool "MStar MSC313 GPIO support" @@ -813,7 +803,7 @@ config GPIO_MSC313 select IRQ_DOMAIN_HIERARCHY help Say Y here to support the main GPIO block on MStar/SigmaStar - ARMv7-based SoCs. + ARMv7 based SoCs. config GPIO_IDT3243X tristate "IDT 79RC3243X GPIO support" @@ -822,7 +812,7 @@ config GPIO_IDT3243X select GPIOLIB_IRQCHIP help Select this option to enable GPIO driver for - IDT 79RC3243X-based devices like Mikrotik RB532. + IDT 79RC3243X based devices like Mikrotik RB532. To compile this driver as a module, choose M here: the module will be called gpio-idt3243x. @@ -900,7 +890,7 @@ config GPIO_IT87 well. To compile this driver as a module, choose M here: the module will - be called gpio_it87. + be called gpio_it87 config GPIO_SCH tristate "Intel SCH/TunnelCreek/Centerton/Quark X1000 GPIO" @@ -916,7 +906,7 @@ config GPIO_SCH powered by the core power rail and are turned off during sleep modes (S3 and higher). The remaining four GPIOs are powered by the Intel SCH suspend power supply. These GPIOs remain - active during S3. The suspend-powered GPIOs can be used to wake the + active during S3. The suspend powered GPIOs can be used to wake the system from the Suspend-to-RAM state. The Intel Tunnel Creek processor has 5 GPIOs powered by the @@ -1069,7 +1059,7 @@ config GPIO_PCA953X_IRQ select GPIOLIB_IRQCHIP help Say yes here to enable the pca953x to be used as an interrupt - controller. + controller. It requires the driver to be built in the kernel. config GPIO_PCA9570 tristate "PCA9570 4-Bit I2C GPO expander" @@ -1145,6 +1135,17 @@ config GPIO_ARIZONA help Support for GPIOs on Wolfson Arizona class devices. +config GPIO_BD70528 + tristate "ROHM BD70528 GPIO support" + depends on MFD_ROHM_BD70528 + help + Support for GPIOs on ROHM BD70528 PMIC. There are four GPIOs + available on the ROHM PMIC in total. The GPIOs can also + generate interrupts. + + This driver can also be built as a module. If so, the module + will be called gpio-bd70528. + config GPIO_BD71815 tristate "ROHM BD71815 PMIC GPIO support" depends on MFD_ROHM_BD71828 @@ -1185,7 +1186,7 @@ config GPIO_CRYSTAL_COVE help Support for GPIO pins on Crystal Cove PMIC. - Say Yes if you have a Intel SoC-based tablet with Crystal Cove PMIC + Say Yes if you have a Intel SoC based tablet with Crystal Cove PMIC inside. This driver can also be built as a module. If so, the module will be @@ -1215,7 +1216,7 @@ config GPIO_DA9055 Say yes here to enable the GPIO driver for the DA9055 chip. The Dialog DA9055 PMIC chip has 3 GPIO pins that can be - be controlled by this driver. + be controller by this driver. If driver is built as a module it will be called gpio-da9055. @@ -1237,7 +1238,7 @@ config HTC_EGPIO help This driver supports the CPLD egpio chip present on several HTC phones. It provides basic support for input - pins, output pins, and IRQs. + pins, output pins, and irqs. config GPIO_FSM tristate "GPIO FSM support" @@ -1307,8 +1308,8 @@ config GPIO_MAX77620 help GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. MAX77620 PMIC has 8 pins that can be configured as GPIOs. The - driver also provides interrupt support for each of the GPIOs. - Say yes here to enable the max77620 to be used as GPIO controller. + driver also provides interrupt support for each of the gpios. + Say yes here to enable the max77620 to be used as gpio controller. config GPIO_MAX77650 tristate "Maxim MAX77650/77651 GPIO support" @@ -1330,8 +1331,8 @@ config GPIO_RC5T583 help Select this option to enable GPIO driver for the Ricoh RC5T583 chip family. - This driver provides the support for driving/reading the GPIO pins - of RC5T583 device through standard GPIO library. + This driver provides the support for driving/reading the gpio pins + of RC5T583 device through standard gpio library. config GPIO_SL28CPLD tristate "Kontron sl28cpld GPIO support" @@ -1400,7 +1401,7 @@ config GPIO_TPS65912 tristate "TI TPS65912 GPIO" depends on MFD_TPS65912 help - This driver supports TPS65912 GPIO chip. + This driver supports TPS65912 gpio chip config GPIO_TPS68470 bool "TPS68470 GPIO" @@ -1408,7 +1409,7 @@ config GPIO_TPS68470 help Select this option to enable GPIO driver for the TPS68470 chip family. - There are 7 GPIOs and few sensor-related GPIOs supported + There are 7 GPIOs and few sensor related GPIOs supported by the TPS68470. While the 7 GPIOs can be configured as input or output as appropriate, the sensor related GPIOs are "output only" GPIOs. @@ -1453,7 +1454,7 @@ config GPIO_WHISKEY_COVE help Support for GPIO pins on Whiskey Cove PMIC. - Say Yes if you have an Intel SoC-based tablet with Whiskey Cove PMIC + Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC inside. This driver can also be built as a module. If so, the module will be @@ -1490,10 +1491,10 @@ config GPIO_AMD8111 depends on X86 || COMPILE_TEST depends on HAS_IOPORT_MAP help - The AMD 8111 southbridge contains 32 GPIO pins which can be used. + The AMD 8111 south bridge contains 32 GPIO pins which can be used. - Note that usually system firmware/ACPI handles GPIO pins on their - own and users might easily break their systems with uncareful usage + Note, that usually system firmware/ACPI handles GPIO pins on their + own and users might easily break their systems with uncarefull usage of this driver! If unsure, say N @@ -1541,22 +1542,22 @@ config GPIO_ML_IOH select GENERIC_IRQ_CHIP help ML7213 is companion chip for Intel Atom E6xx series. - This driver can be used for OKI SEMICONDUCTOR ML7213 IOH (Input/Output - Hub) which is for IVI (In-Vehicle Infotainment) use. + This driver can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/Output + Hub) which is for IVI(In-Vehicle Infotainment) use. This driver can access the IOH's GPIO device. config GPIO_PCH - tristate "Intel EG20T PCH/LAPIS Semiconductor IOH (ML7223/ML7831) GPIO" + tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO" depends on X86_32 || MIPS || COMPILE_TEST select GENERIC_IRQ_CHIP help - This driver is for PCH (Platform Controller Hub) GPIO of Intel Topcliff, - which is an IOH (Input/Output Hub) for x86 embedded processor. + This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff + which is an IOH(Input/Output Hub) for x86 embedded processor. This driver can access PCH GPIO device. - This driver also can be used for LAPIS Semiconductor IOH (Input/ + This driver also can be used for LAPIS Semiconductor IOH(Input/ Output Hub), ML7223 and ML7831. - ML7223 IOH is for MP (Media Phone) use. + ML7223 IOH is for MP(Media Phone) use. ML7831 IOH is for general purpose use. ML7223/ML7831 is companion chip for Intel Atom E6xx series. ML7223/ML7831 is completely compatible for Intel EG20T PCH. @@ -1607,7 +1608,7 @@ config GPIO_74X164 help Driver for 74x164 compatible serial-in/parallel-out 8-outputs shift registers. This driver can be used to provide access - to more GPIO outputs. + to more gpio outputs. config GPIO_MAX3191X tristate "Maxim MAX3191x industrial serializer" @@ -1697,21 +1698,12 @@ config GPIO_MOCKUP config GPIO_VIRTIO tristate "VirtIO GPIO support" depends on VIRTIO - select GPIOLIB_IRQCHIP help Say Y here to enable guest support for virtio-based GPIO controllers. These virtual GPIOs can be routed to real GPIOs or attached to simulators on the host (like QEMU). -config GPIO_SIM - tristate "GPIO Simulator Module" - select IRQ_SIM - select CONFIGFS_FS - help - This enables the GPIO simulator - a configfs-based GPIO testing - driver. - endmenu endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index af65e7b223..0980f9b189 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o obj-$(CONFIG_GPIO_BCM_VIRT) += gpio-bcm-virt.o +obj-$(CONFIG_GPIO_BD70528) += gpio-bd70528.o obj-$(CONFIG_GPIO_BD71815) += gpio-bd71815.o obj-$(CONFIG_GPIO_BD71828) += gpio-bd71828.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o @@ -135,7 +136,6 @@ obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o -obj-$(CONFIG_GPIO_SIM) += gpio-sim.o obj-$(CONFIG_GPIO_SIOX) += gpio-siox.o obj-$(CONFIG_GPIO_SL28CPLD) += gpio-sl28cpld.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o @@ -187,4 +187,3 @@ obj-$(CONFIG_GPIO_XRA1403) += gpio-xra1403.o obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o -obj-$(CONFIG_GPIO_ZYNQMP_MODEPIN) += gpio-zynqmp-modepin.o diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index cc349d4e49..8eedfc6451 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -458,6 +458,7 @@ static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios, chip->ngpio = num_gpios; chip->label = adnp->client->name; chip->parent = &adnp->client->dev; + chip->of_node = chip->parent->of_node; chip->owner = THIS_MODULE; if (is_irq_controller) { diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 0cb2664085..23047dc84e 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -247,11 +247,6 @@ struct gpiochip_fwd { unsigned long tmp[]; /* values and descs for multiple ops */ }; -#define fwd_tmp_values(fwd) &(fwd)->tmp[0] -#define fwd_tmp_descs(fwd) (void *)&(fwd)->tmp[BITS_TO_LONGS((fwd)->chip.ngpio)] - -#define fwd_tmp_size(ngpios) (BITS_TO_LONGS((ngpios)) + (ngpios)) - static int gpio_fwd_get_direction(struct gpio_chip *chip, unsigned int offset) { struct gpiochip_fwd *fwd = gpiochip_get_data(chip); @@ -285,11 +280,15 @@ static int gpio_fwd_get(struct gpio_chip *chip, unsigned int offset) static int gpio_fwd_get_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, unsigned long *bits) { - struct gpio_desc **descs = fwd_tmp_descs(fwd); - unsigned long *values = fwd_tmp_values(fwd); + struct gpio_desc **descs; + unsigned long *values; unsigned int i, j = 0; int error; + /* Both values bitmap and desc pointers are stored in tmp[] */ + values = &fwd->tmp[0]; + descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)]; + bitmap_clear(values, 0, fwd->chip.ngpio); for_each_set_bit(i, mask, fwd->chip.ngpio) descs[j++] = fwd->descs[i]; @@ -341,10 +340,14 @@ static void gpio_fwd_set(struct gpio_chip *chip, unsigned int offset, int value) static void gpio_fwd_set_multiple(struct gpiochip_fwd *fwd, unsigned long *mask, unsigned long *bits) { - struct gpio_desc **descs = fwd_tmp_descs(fwd); - unsigned long *values = fwd_tmp_values(fwd); + struct gpio_desc **descs; + unsigned long *values; unsigned int i, j = 0; + /* Both values bitmap and desc pointers are stored in tmp[] */ + values = &fwd->tmp[0]; + descs = (void *)&fwd->tmp[BITS_TO_LONGS(fwd->chip.ngpio)]; + for_each_set_bit(i, mask, fwd->chip.ngpio) { __assign_bit(j, values, test_bit(i, bits)); descs[j++] = fwd->descs[i]; @@ -381,13 +384,6 @@ static int gpio_fwd_set_config(struct gpio_chip *chip, unsigned int offset, return gpiod_set_config(fwd->descs[offset], config); } -static int gpio_fwd_to_irq(struct gpio_chip *chip, unsigned int offset) -{ - struct gpiochip_fwd *fwd = gpiochip_get_data(chip); - - return gpiod_to_irq(fwd->descs[offset]); -} - /** * gpiochip_fwd_create() - Create a new GPIO forwarder * @dev: Parent device pointer @@ -412,8 +408,8 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, unsigned int i; int error; - fwd = devm_kzalloc(dev, struct_size(fwd, tmp, fwd_tmp_size(ngpios)), - GFP_KERNEL); + fwd = devm_kzalloc(dev, struct_size(fwd, tmp, + BITS_TO_LONGS(ngpios) + ngpios), GFP_KERNEL); if (!fwd) return ERR_PTR(-ENOMEM); @@ -428,8 +424,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, for (i = 0; i < ngpios; i++) { struct gpio_chip *parent = gpiod_to_chip(descs[i]); - dev_dbg(dev, "%u => gpio %d irq %d\n", i, - desc_to_gpio(descs[i]), gpiod_to_irq(descs[i])); + dev_dbg(dev, "%u => gpio-%d\n", i, desc_to_gpio(descs[i])); if (gpiod_cansleep(descs[i])) chip->can_sleep = true; @@ -447,7 +442,6 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, chip->get_multiple = gpio_fwd_get_multiple_locked; chip->set = gpio_fwd_set; chip->set_multiple = gpio_fwd_set_multiple_locked; - chip->to_irq = gpio_fwd_to_irq; chip->base = -1; chip->ngpio = ngpios; fwd->descs = descs; diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c index 8cfb353c3a..44398992ae 100644 --- a/drivers/gpio/gpio-amdpt.c +++ b/drivers/gpio/gpio-amdpt.c @@ -14,7 +14,6 @@ #include #define PT_TOTAL_GPIO 8 -#define PT_TOTAL_GPIO_EX 24 /* PCI-E MMIO register offsets */ #define PT_DIRECTION_REG 0x00 @@ -73,10 +72,12 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset) static int pt_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct acpi_device *acpi_dev; + acpi_handle handle = ACPI_HANDLE(dev); struct pt_gpio_chip *pt_gpio; int ret = 0; - if (!ACPI_COMPANION(dev)) { + if (acpi_bus_get_device(handle, &acpi_dev)) { dev_err(dev, "PT GPIO device node not found\n"); return -ENODEV; } @@ -104,8 +105,10 @@ static int pt_gpio_probe(struct platform_device *pdev) pt_gpio->gc.owner = THIS_MODULE; pt_gpio->gc.request = pt_gpio_request; pt_gpio->gc.free = pt_gpio_free; - pt_gpio->gc.ngpio = (uintptr_t)device_get_match_data(dev); - + pt_gpio->gc.ngpio = PT_TOTAL_GPIO; +#if defined(CONFIG_OF_GPIO) + pt_gpio->gc.of_node = dev->of_node; +#endif ret = gpiochip_add_data(&pt_gpio->gc, pt_gpio); if (ret) { dev_err(dev, "Failed to register GPIO lib\n"); @@ -132,9 +135,8 @@ static int pt_gpio_remove(struct platform_device *pdev) } static const struct acpi_device_id pt_gpio_acpi_match[] = { - { "AMDF030", PT_TOTAL_GPIO }, - { "AMDIF030", PT_TOTAL_GPIO }, - { "AMDIF031", PT_TOTAL_GPIO_EX }, + { "AMDF030", 0 }, + { "AMDIF030", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, pt_gpio_acpi_match); diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c index 02f9ae19cd..2bc173c352 100644 --- a/drivers/gpio/gpio-arizona.c +++ b/drivers/gpio/gpio-arizona.c @@ -151,8 +151,6 @@ static int arizona_gpio_probe(struct platform_device *pdev) struct arizona_gpio *arizona_gpio; int ret; - device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); - arizona_gpio = devm_kzalloc(&pdev->dev, sizeof(*arizona_gpio), GFP_KERNEL); if (!arizona_gpio) @@ -161,6 +159,9 @@ static int arizona_gpio_probe(struct platform_device *pdev) arizona_gpio->arizona = arizona; arizona_gpio->gpio_chip = template_chip; arizona_gpio->gpio_chip.parent = &pdev->dev; +#ifdef CONFIG_OF_GPIO + arizona_gpio->gpio_chip.of_node = arizona->dev->of_node; +#endif switch (arizona->type) { case WM5102: diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index e844744944..d329a143f5 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -606,7 +606,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) kona_gpio->pdev = pdev; platform_set_drvdata(pdev, kona_gpio); - chip->parent = dev; + chip->of_node = dev->of_node; chip->ngpio = kona_gpio->num_bank * GPIO_PER_BANK; kona_gpio->irq_domain = irq_domain_add_linear(dev->of_node, diff --git a/drivers/gpio/gpio-bd71828.c b/drivers/gpio/gpio-bd71828.c index b2ccc320c7..c8e382b53f 100644 --- a/drivers/gpio/gpio-bd71828.c +++ b/drivers/gpio/gpio-bd71828.c @@ -121,6 +121,7 @@ static int bd71828_probe(struct platform_device *pdev) * "gpio-reserved-ranges" and exclude them from control */ bdgpio->gpio.ngpio = 4; + bdgpio->gpio.of_node = dev->parent->of_node; bdgpio->regmap = dev_get_regmap(dev->parent, NULL); if (!bdgpio->regmap) return -ENODEV; diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index 74ef892488..895a799362 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -703,8 +703,9 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) goto fail; } + gc->of_node = np; gc->owner = THIS_MODULE; - gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); + gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", dev->of_node); if (!gc->label) { err = -ENOMEM; goto fail; diff --git a/drivers/gpio/gpio-creg-snps.c b/drivers/gpio/gpio-creg-snps.c index 789384c6e1..1d0827e797 100644 --- a/drivers/gpio/gpio-creg-snps.c +++ b/drivers/gpio/gpio-creg-snps.c @@ -163,12 +163,12 @@ static int creg_gpio_probe(struct platform_device *pdev) spin_lock_init(&hcg->lock); - hcg->gc.parent = dev; hcg->gc.label = dev_name(dev); hcg->gc.base = -1; hcg->gc.ngpio = ngpios; hcg->gc.set = creg_gpio_set; hcg->gc.direction_output = creg_gpio_dir_out; + hcg->gc.of_node = dev->of_node; ret = devm_gpiochip_add_data(dev, &hcg->gc, hcg); if (ret) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index f960587f86..cb5afaa7ed 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -254,6 +254,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_OF_GPIO chips->chip.of_gpio_n_cells = 2; chips->chip.parent = dev; + chips->chip.of_node = dev->of_node; chips->chip.request = gpiochip_generic_request; chips->chip.free = gpiochip_generic_free; #endif diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index b0f3aca619..f98fa33e16 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -52,9 +53,7 @@ #define GPIO_SWPORT_DR_STRIDE 0x0c /* register stride 3*32 bits */ #define GPIO_SWPORT_DDR_STRIDE 0x0c /* register stride 3*32 bits */ -#define GPIO_REG_OFFSET_V1 0 #define GPIO_REG_OFFSET_V2 1 -#define GPIO_REG_OFFSET_MASK BIT(0) #define GPIO_INTMASK_V2 0x44 #define GPIO_INTTYPE_LEVEL_V2 0x34 @@ -142,7 +141,7 @@ static inline u32 gpio_reg_v2_convert(unsigned int offset) static inline u32 gpio_reg_convert(struct dwapb_gpio *gpio, unsigned int offset) { - if ((gpio->flags & GPIO_REG_OFFSET_MASK) == GPIO_REG_OFFSET_V2) + if (gpio->flags & GPIO_REG_OFFSET_V2) return gpio_reg_v2_convert(offset); return offset; @@ -514,7 +513,9 @@ static int dwapb_gpio_add_port(struct dwapb_gpio *gpio, return err; } - port->gc.fwnode = pp->fwnode; +#ifdef CONFIG_OF_GPIO + port->gc.of_node = to_of_node(pp->fwnode); +#endif port->gc.ngpio = pp->ngpio; port->gc.base = pp->gpio_base; @@ -667,15 +668,15 @@ static int dwapb_get_clks(struct dwapb_gpio *gpio) } static const struct of_device_id dwapb_of_match[] = { - { .compatible = "snps,dw-apb-gpio", .data = (void *)GPIO_REG_OFFSET_V1}, + { .compatible = "snps,dw-apb-gpio", .data = (void *)0}, { .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2}, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, dwapb_of_match); static const struct acpi_device_id dwapb_acpi_match[] = { - {"HISI0181", GPIO_REG_OFFSET_V1}, - {"APMC0D07", GPIO_REG_OFFSET_V1}, + {"HISI0181", 0}, + {"APMC0D07", 0}, {"APMC0D81", GPIO_REG_OFFSET_V2}, { } }; diff --git a/drivers/gpio/gpio-eic-sprd.c b/drivers/gpio/gpio-eic-sprd.c index 8d722e026e..865ab2b34f 100644 --- a/drivers/gpio/gpio-eic-sprd.c +++ b/drivers/gpio/gpio-eic-sprd.c @@ -609,6 +609,7 @@ static int sprd_eic_probe(struct platform_device *pdev) sprd_eic->chip.ngpio = pdata->num_eics; sprd_eic->chip.base = -1; sprd_eic->chip.parent = &pdev->dev; + sprd_eic->chip.of_node = pdev->dev.of_node; sprd_eic->chip.direction_input = sprd_eic_direction_input; switch (sprd_eic->type) { case SPRD_EIC_DEBOUNCE: diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 858e6ebbb5..90b336e6ee 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -306,6 +306,7 @@ static int em_gio_probe(struct platform_device *pdev) } gpio_chip = &p->gpio_chip; + gpio_chip->of_node = dev->of_node; gpio_chip->direction_input = em_gio_direction_input; gpio_chip->get = em_gio_get; gpio_chip->direction_output = em_gio_direction_output; diff --git a/drivers/gpio/gpio-ge.c b/drivers/gpio/gpio-ge.c index f6a3de99f7..636952769b 100644 --- a/drivers/gpio/gpio-ge.c +++ b/drivers/gpio/gpio-ge.c @@ -82,6 +82,7 @@ static int __init gef_gpio_probe(struct platform_device *pdev) gc->base = -1; gc->ngpio = (u16)(uintptr_t)of_device_get_match_data(&pdev->dev); gc->of_gpio_n_cells = 2; + gc->of_node = pdev->dev.of_node; /* This function adds a memory mapped GPIO chip */ ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL); diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 23d447e17a..f954359c95 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -358,6 +358,7 @@ static int grgpio_probe(struct platform_device *ofdev) priv->imask = gc->read_reg(regs + GRGPIO_IMASK); priv->dev = &ofdev->dev; + gc->of_node = np; gc->owner = THIS_MODULE; gc->to_irq = grgpio_to_irq; gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np); diff --git a/drivers/gpio/gpio-gw-pld.c b/drivers/gpio/gpio-gw-pld.c index 2109803ffb..242112ff60 100644 --- a/drivers/gpio/gpio-gw-pld.c +++ b/drivers/gpio/gpio-gw-pld.c @@ -71,6 +71,7 @@ static int gw_pld_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; + struct device_node *np = dev->of_node; struct gw_pld *gw; int ret; @@ -81,6 +82,7 @@ static int gw_pld_probe(struct i2c_client *client, gw->chip.base = -1; gw->chip.can_sleep = true; gw->chip.parent = dev; + gw->chip.of_node = np; gw->chip.owner = THIS_MODULE; gw->chip.label = dev_name(dev); gw->chip.ngpio = 8; diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index d2b65cfb33..4e626c4235 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c @@ -512,10 +512,10 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev) return PTR_ERR(reg_base); for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) { - lpc32xx_gpiochip[i].chip.parent = &pdev->dev; if (pdev->dev.of_node) { lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate; lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3; + lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node; lpc32xx_gpiochip[i].reg_base = reg_base; } devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip, diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c index 51cd6f98d1..310d1a248c 100644 --- a/drivers/gpio/gpio-max3191x.c +++ b/drivers/gpio/gpio-max3191x.c @@ -326,7 +326,7 @@ static void gpiod_set_array_single_value_cansleep(unsigned int ndescs, bitmap_zero(values, ndescs); gpiod_set_array_value_cansleep(ndescs, desc, info, values); - bitmap_free(values); + kfree(values); } static struct gpio_descs *devm_gpiod_get_array_optional_count( diff --git a/drivers/gpio/gpio-max7300.c b/drivers/gpio/gpio-max7300.c index b2b547dd6e..19cc2ed6a3 100644 --- a/drivers/gpio/gpio-max7300.c +++ b/drivers/gpio/gpio-max7300.c @@ -50,9 +50,7 @@ static int max7300_probe(struct i2c_client *client, static int max7300_remove(struct i2c_client *client) { - __max730x_remove(&client->dev); - - return 0; + return __max730x_remove(&client->dev); } static const struct i2c_device_id max7300_id[] = { diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c index 5862d73bf3..1307c243b4 100644 --- a/drivers/gpio/gpio-max7301.c +++ b/drivers/gpio/gpio-max7301.c @@ -66,9 +66,7 @@ static int max7301_probe(struct spi_device *spi) static int max7301_remove(struct spi_device *spi) { - __max730x_remove(&spi->dev); - - return 0; + return __max730x_remove(&spi->dev); } static const struct spi_device_id max7301_id[] = { diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index bb5cf14ae4..b8c1fe20f4 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -220,14 +220,18 @@ int __max730x_probe(struct max7301 *ts) } EXPORT_SYMBOL_GPL(__max730x_probe); -void __max730x_remove(struct device *dev) +int __max730x_remove(struct device *dev) { struct max7301 *ts = dev_get_drvdata(dev); + if (ts == NULL) + return -ENODEV; + /* Power down the chip and disable IRQ output */ ts->write(dev, 0x04, 0x00); gpiochip_remove(&ts->chip); mutex_destroy(&ts->lock); + return 0; } EXPORT_SYMBOL_GPL(__max730x_remove); diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c index ebf9dea654..82b3a91300 100644 --- a/drivers/gpio/gpio-max77620.c +++ b/drivers/gpio/gpio-max77620.c @@ -365,4 +365,5 @@ module_platform_driver(max77620_gpio_driver); MODULE_DESCRIPTION("GPIO interface for MAX77620 and MAX20024 PMIC"); MODULE_AUTHOR("Laxman Dewangan "); MODULE_AUTHOR("Chaitanya Bandi "); +MODULE_ALIAS("platform:max77620-gpio"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index 31d2be1beb..f8194f7c61 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c @@ -139,6 +139,8 @@ static int mc33880_remove(struct spi_device *spi) struct mc33880 *mc; mc = spi_get_drvdata(spi); + if (!mc) + return -ENODEV; gpiochip_remove(&mc->chip); mutex_destroy(&mc->lock); diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index b060c47736..efa9acdc32 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -98,9 +98,9 @@ static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) spin_lock_irqsave(&chip->spinlock, flags); reg_val = ioread32(&chip->reg->regs[chip->ch].po); if (val) - reg_val |= BIT(nr); + reg_val |= (1 << nr); else - reg_val &= ~BIT(nr); + reg_val &= ~(1 << nr); iowrite32(reg_val, &chip->reg->regs[chip->ch].po); spin_unlock_irqrestore(&chip->spinlock, flags); @@ -110,7 +110,7 @@ static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) { struct ioh_gpio *chip = gpiochip_get_data(gpio); - return !!(ioread32(&chip->reg->regs[chip->ch].pi) & BIT(nr)); + return !!(ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr)); } static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, @@ -122,16 +122,16 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, unsigned long flags; spin_lock_irqsave(&chip->spinlock, flags); - pm = ioread32(&chip->reg->regs[chip->ch].pm); - pm &= BIT(num_ports[chip->ch]) - 1; - pm |= BIT(nr); + pm = ioread32(&chip->reg->regs[chip->ch].pm) & + ((1 << num_ports[chip->ch]) - 1); + pm |= (1 << nr); iowrite32(pm, &chip->reg->regs[chip->ch].pm); reg_val = ioread32(&chip->reg->regs[chip->ch].po); if (val) - reg_val |= BIT(nr); + reg_val |= (1 << nr); else - reg_val &= ~BIT(nr); + reg_val &= ~(1 << nr); iowrite32(reg_val, &chip->reg->regs[chip->ch].po); spin_unlock_irqrestore(&chip->spinlock, flags); @@ -146,9 +146,9 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) unsigned long flags; spin_lock_irqsave(&chip->spinlock, flags); - pm = ioread32(&chip->reg->regs[chip->ch].pm); - pm &= BIT(num_ports[chip->ch]) - 1; - pm &= ~BIT(nr); + pm = ioread32(&chip->reg->regs[chip->ch].pm) & + ((1 << num_ports[chip->ch]) - 1); + pm &= ~(1 << nr); iowrite32(pm, &chip->reg->regs[chip->ch].pm); spin_unlock_irqrestore(&chip->spinlock, flags); @@ -304,7 +304,7 @@ static void ioh_irq_unmask(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct ioh_gpio *chip = gc->private; - iowrite32(BIT(d->irq - chip->irq_base), + iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->regs[chip->ch].imaskclr); } @@ -313,7 +313,7 @@ static void ioh_irq_mask(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct ioh_gpio *chip = gc->private; - iowrite32(BIT(d->irq - chip->irq_base), + iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->regs[chip->ch].imask); } @@ -326,7 +326,7 @@ static void ioh_irq_disable(struct irq_data *d) spin_lock_irqsave(&chip->spinlock, flags); ien = ioread32(&chip->reg->regs[chip->ch].ien); - ien &= ~BIT(d->irq - chip->irq_base); + ien &= ~(1 << (d->irq - chip->irq_base)); iowrite32(ien, &chip->reg->regs[chip->ch].ien); spin_unlock_irqrestore(&chip->spinlock, flags); } @@ -340,7 +340,7 @@ static void ioh_irq_enable(struct irq_data *d) spin_lock_irqsave(&chip->spinlock, flags); ien = ioread32(&chip->reg->regs[chip->ch].ien); - ien |= BIT(d->irq - chip->irq_base); + ien |= 1 << (d->irq - chip->irq_base); iowrite32(ien, &chip->reg->regs[chip->ch].ien); spin_unlock_irqrestore(&chip->spinlock, flags); } @@ -401,7 +401,6 @@ static int ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, static int ioh_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct device *dev = &pdev->dev; int ret; int i, j; struct ioh_gpio *chip; @@ -411,19 +410,19 @@ static int ioh_gpio_probe(struct pci_dev *pdev, ret = pci_enable_device(pdev); if (ret) { - dev_err(dev, "%s : pci_enable_device failed", __func__); + dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__); goto err_pci_enable; } ret = pci_request_regions(pdev, KBUILD_MODNAME); if (ret) { - dev_err(dev, "pci_request_regions failed-%d", ret); + dev_err(&pdev->dev, "pci_request_regions failed-%d", ret); goto err_request_regions; } base = pci_iomap(pdev, 1, 0); if (!base) { - dev_err(dev, "%s : pci_iomap failed", __func__); + dev_err(&pdev->dev, "%s : pci_iomap failed", __func__); ret = -ENOMEM; goto err_iomap; } @@ -436,7 +435,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev, chip = chip_save; for (i = 0; i < 8; i++, chip++) { - chip->dev = dev; + chip->dev = &pdev->dev; chip->base = base; chip->reg = chip->base; chip->ch = i; @@ -444,17 +443,17 @@ static int ioh_gpio_probe(struct pci_dev *pdev, ioh_gpio_setup(chip, num_ports[i]); ret = gpiochip_add_data(&chip->gpio, chip); if (ret) { - dev_err(dev, "IOH gpio: Failed to register GPIO\n"); + dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n"); goto err_gpiochip_add; } } chip = chip_save; for (j = 0; j < 8; j++, chip++) { - irq_base = devm_irq_alloc_descs(dev, -1, IOH_IRQ_BASE, + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, IOH_IRQ_BASE, num_ports[j], NUMA_NO_NODE); if (irq_base < 0) { - dev_warn(dev, + dev_warn(&pdev->dev, "ml_ioh_gpio: Failed to get IRQ base num\n"); ret = irq_base; goto err_gpiochip_add; @@ -468,10 +467,11 @@ static int ioh_gpio_probe(struct pci_dev *pdev, } chip = chip_save; - ret = devm_request_irq(dev, pdev->irq, ioh_gpio_handler, + ret = devm_request_irq(&pdev->dev, pdev->irq, ioh_gpio_handler, IRQF_SHARED, KBUILD_MODNAME, chip); if (ret != 0) { - dev_err(dev, "%s request_irq failed\n", __func__); + dev_err(&pdev->dev, + "%s request_irq failed\n", __func__); goto err_gpiochip_add; } @@ -498,7 +498,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev, err_pci_enable: - dev_err(dev, "%s Failed returns %d\n", __func__, ret); + dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); return ret; } diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c index 3d89912a05..40a052bc67 100644 --- a/drivers/gpio/gpio-mlxbf2.c +++ b/drivers/gpio/gpio-mlxbf2.c @@ -1,14 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES - */ - #include #include #include #include -#include #include #include #include @@ -48,14 +43,9 @@ #define YU_GPIO_MODE0 0x0c #define YU_GPIO_DATASET 0x14 #define YU_GPIO_DATACLEAR 0x18 -#define YU_GPIO_CAUSE_RISE_EN 0x44 -#define YU_GPIO_CAUSE_FALL_EN 0x48 #define YU_GPIO_MODE1_CLEAR 0x50 #define YU_GPIO_MODE0_SET 0x54 #define YU_GPIO_MODE0_CLEAR 0x58 -#define YU_GPIO_CAUSE_OR_CAUSE_EVTEN0 0x80 -#define YU_GPIO_CAUSE_OR_EVTEN0 0x94 -#define YU_GPIO_CAUSE_OR_CLRCAUSE 0x98 struct mlxbf2_gpio_context_save_regs { u32 gpio_mode0; @@ -65,7 +55,6 @@ struct mlxbf2_gpio_context_save_regs { /* BlueField-2 gpio block context structure. */ struct mlxbf2_gpio_context { struct gpio_chip gc; - struct irq_chip irq_chip; /* YU GPIO blocks address */ void __iomem *gpio_io; @@ -229,114 +218,15 @@ static int mlxbf2_gpio_direction_output(struct gpio_chip *chip, return ret; } -static void mlxbf2_gpio_irq_enable(struct irq_data *irqd) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); - struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc); - int offset = irqd_to_hwirq(irqd); - unsigned long flags; - u32 val; - - spin_lock_irqsave(&gs->gc.bgpio_lock, flags); - val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); - val |= BIT(offset); - writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); - - val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); - val |= BIT(offset); - writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); -} - -static void mlxbf2_gpio_irq_disable(struct irq_data *irqd) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); - struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc); - int offset = irqd_to_hwirq(irqd); - unsigned long flags; - u32 val; - - spin_lock_irqsave(&gs->gc.bgpio_lock, flags); - val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); - val &= ~BIT(offset); - writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0); - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); -} - -static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr) -{ - struct mlxbf2_gpio_context *gs = ptr; - struct gpio_chip *gc = &gs->gc; - unsigned long pending; - u32 level; - - pending = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CAUSE_EVTEN0); - writel(pending, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE); - - for_each_set_bit(level, &pending, gc->ngpio) { - int gpio_irq = irq_find_mapping(gc->irq.domain, level); - generic_handle_irq(gpio_irq); - } - - return IRQ_RETVAL(pending); -} - -static int -mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); - struct mlxbf2_gpio_context *gs = gpiochip_get_data(gc); - int offset = irqd_to_hwirq(irqd); - unsigned long flags; - bool fall = false; - bool rise = false; - u32 val; - - switch (type & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_EDGE_BOTH: - fall = true; - rise = true; - break; - case IRQ_TYPE_EDGE_RISING: - rise = true; - break; - case IRQ_TYPE_EDGE_FALLING: - fall = true; - break; - default: - return -EINVAL; - } - - spin_lock_irqsave(&gs->gc.bgpio_lock, flags); - if (fall) { - val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN); - val |= BIT(offset); - writel(val, gs->gpio_io + YU_GPIO_CAUSE_FALL_EN); - } - - if (rise) { - val = readl(gs->gpio_io + YU_GPIO_CAUSE_RISE_EN); - val |= BIT(offset); - writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN); - } - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags); - - return 0; -} - /* BlueField-2 GPIO driver initialization routine. */ static int mlxbf2_gpio_probe(struct platform_device *pdev) { struct mlxbf2_gpio_context *gs; struct device *dev = &pdev->dev; - struct gpio_irq_chip *girq; struct gpio_chip *gc; unsigned int npins; - const char *name; - int ret, irq; - - name = dev_name(dev); + int ret; gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL); if (!gs) @@ -376,34 +266,6 @@ mlxbf2_gpio_probe(struct platform_device *pdev) gc->ngpio = npins; gc->owner = THIS_MODULE; - irq = platform_get_irq(pdev, 0); - if (irq >= 0) { - gs->irq_chip.name = name; - gs->irq_chip.irq_set_type = mlxbf2_gpio_irq_set_type; - gs->irq_chip.irq_enable = mlxbf2_gpio_irq_enable; - gs->irq_chip.irq_disable = mlxbf2_gpio_irq_disable; - - girq = &gs->gc.irq; - girq->chip = &gs->irq_chip; - girq->handler = handle_simple_irq; - girq->default_type = IRQ_TYPE_NONE; - /* This will let us handle the parent IRQ in the driver */ - girq->num_parents = 0; - girq->parents = NULL; - girq->parent_handler = NULL; - - /* - * Directly request the irq here instead of passing - * a flow-handler because the irq is shared. - */ - ret = devm_request_irq(dev, irq, mlxbf2_gpio_irq_handler, - IRQF_SHARED, name, gs); - if (ret) { - dev_err(dev, "failed to request IRQ"); - return ret; - } - } - platform_set_drvdata(pdev, gs); ret = devm_gpiochip_add_data(dev, &gs->gc, gs); @@ -458,5 +320,5 @@ static struct platform_driver mlxbf2_gpio_driver = { module_platform_driver(mlxbf2_gpio_driver); MODULE_DESCRIPTION("Mellanox BlueField-2 GPIO Driver"); -MODULE_AUTHOR("Asmaa Mnebhi "); +MODULE_AUTHOR("Mellanox Technologies"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 8943cea927..d26bff2915 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -491,6 +491,27 @@ static void gpio_mockup_unregister_pdevs(void) } } +static __init char **gpio_mockup_make_line_names(const char *label, + unsigned int num_lines) +{ + unsigned int i; + char **names; + + names = kcalloc(num_lines + 1, sizeof(char *), GFP_KERNEL); + if (!names) + return NULL; + + for (i = 0; i < num_lines; i++) { + names[i] = kasprintf(GFP_KERNEL, "%s-%u", label, i); + if (!names[i]) { + kfree_strarray(names, i); + return NULL; + } + } + + return names; +} + static int __init gpio_mockup_register_chip(int idx) { struct property_entry properties[GPIO_MOCKUP_MAX_PROP]; @@ -517,7 +538,7 @@ static int __init gpio_mockup_register_chip(int idx) properties[prop++] = PROPERTY_ENTRY_U16("nr-gpios", ngpio); if (gpio_mockup_named_lines) { - line_names = kasprintf_strarray(GFP_KERNEL, chip_label, ngpio); + line_names = gpio_mockup_make_line_names(chip_label, ngpio); if (!line_names) return -ENOMEM; diff --git a/drivers/gpio/gpio-msc313.c b/drivers/gpio/gpio-msc313.c index b2c90bdd39..da31a5ff7a 100644 --- a/drivers/gpio/gpio-msc313.c +++ b/drivers/gpio/gpio-msc313.c @@ -221,263 +221,6 @@ static const unsigned int msc313_offsets[] = { }; MSC313_GPIO_CHIPDATA(msc313); - -/* - * Unlike the msc313(e) the ssd20xd have a bunch of pins - * that are actually called gpio probably because they - * have no dedicated function. - */ -#define SSD20XD_PINNAME_GPIO0 "gpio0" -#define SSD20XD_PINNAME_GPIO1 "gpio1" -#define SSD20XD_PINNAME_GPIO2 "gpio2" -#define SSD20XD_PINNAME_GPIO3 "gpio3" -#define SSD20XD_PINNAME_GPIO4 "gpio4" -#define SSD20XD_PINNAME_GPIO5 "gpio5" -#define SSD20XD_PINNAME_GPIO6 "gpio6" -#define SSD20XD_PINNAME_GPIO7 "gpio7" -#define SSD20XD_PINNAME_GPIO10 "gpio10" -#define SSD20XD_PINNAME_GPIO11 "gpio11" -#define SSD20XD_PINNAME_GPIO12 "gpio12" -#define SSD20XD_PINNAME_GPIO13 "gpio13" -#define SSD20XD_PINNAME_GPIO14 "gpio14" -#define SSD20XD_PINNAME_GPIO85 "gpio85" -#define SSD20XD_PINNAME_GPIO86 "gpio86" -#define SSD20XD_PINNAME_GPIO90 "gpio90" - -#define SSD20XD_GPIO_NAMES SSD20XD_PINNAME_GPIO0, \ - SSD20XD_PINNAME_GPIO1, \ - SSD20XD_PINNAME_GPIO2, \ - SSD20XD_PINNAME_GPIO3, \ - SSD20XD_PINNAME_GPIO4, \ - SSD20XD_PINNAME_GPIO5, \ - SSD20XD_PINNAME_GPIO6, \ - SSD20XD_PINNAME_GPIO7, \ - SSD20XD_PINNAME_GPIO10, \ - SSD20XD_PINNAME_GPIO11, \ - SSD20XD_PINNAME_GPIO12, \ - SSD20XD_PINNAME_GPIO13, \ - SSD20XD_PINNAME_GPIO14, \ - SSD20XD_PINNAME_GPIO85, \ - SSD20XD_PINNAME_GPIO86, \ - SSD20XD_PINNAME_GPIO90 - -#define SSD20XD_GPIO_OFF_GPIO0 0x0 -#define SSD20XD_GPIO_OFF_GPIO1 0x4 -#define SSD20XD_GPIO_OFF_GPIO2 0x8 -#define SSD20XD_GPIO_OFF_GPIO3 0xc -#define SSD20XD_GPIO_OFF_GPIO4 0x10 -#define SSD20XD_GPIO_OFF_GPIO5 0x14 -#define SSD20XD_GPIO_OFF_GPIO6 0x18 -#define SSD20XD_GPIO_OFF_GPIO7 0x1c -#define SSD20XD_GPIO_OFF_GPIO10 0x28 -#define SSD20XD_GPIO_OFF_GPIO11 0x2c -#define SSD20XD_GPIO_OFF_GPIO12 0x30 -#define SSD20XD_GPIO_OFF_GPIO13 0x34 -#define SSD20XD_GPIO_OFF_GPIO14 0x38 -#define SSD20XD_GPIO_OFF_GPIO85 0x100 -#define SSD20XD_GPIO_OFF_GPIO86 0x104 -#define SSD20XD_GPIO_OFF_GPIO90 0x114 - -#define SSD20XD_GPIO_OFFSETS SSD20XD_GPIO_OFF_GPIO0, \ - SSD20XD_GPIO_OFF_GPIO1, \ - SSD20XD_GPIO_OFF_GPIO2, \ - SSD20XD_GPIO_OFF_GPIO3, \ - SSD20XD_GPIO_OFF_GPIO4, \ - SSD20XD_GPIO_OFF_GPIO5, \ - SSD20XD_GPIO_OFF_GPIO6, \ - SSD20XD_GPIO_OFF_GPIO7, \ - SSD20XD_GPIO_OFF_GPIO10, \ - SSD20XD_GPIO_OFF_GPIO11, \ - SSD20XD_GPIO_OFF_GPIO12, \ - SSD20XD_GPIO_OFF_GPIO13, \ - SSD20XD_GPIO_OFF_GPIO14, \ - SSD20XD_GPIO_OFF_GPIO85, \ - SSD20XD_GPIO_OFF_GPIO86, \ - SSD20XD_GPIO_OFF_GPIO90 - -/* "ttl" pins lcd interface pins */ -#define SSD20XD_PINNAME_TTL0 "ttl0" -#define SSD20XD_PINNAME_TTL1 "ttl1" -#define SSD20XD_PINNAME_TTL2 "ttl2" -#define SSD20XD_PINNAME_TTL3 "ttl3" -#define SSD20XD_PINNAME_TTL4 "ttl4" -#define SSD20XD_PINNAME_TTL5 "ttl5" -#define SSD20XD_PINNAME_TTL6 "ttl6" -#define SSD20XD_PINNAME_TTL7 "ttl7" -#define SSD20XD_PINNAME_TTL8 "ttl8" -#define SSD20XD_PINNAME_TTL9 "ttl9" -#define SSD20XD_PINNAME_TTL10 "ttl10" -#define SSD20XD_PINNAME_TTL11 "ttl11" -#define SSD20XD_PINNAME_TTL12 "ttl12" -#define SSD20XD_PINNAME_TTL13 "ttl13" -#define SSD20XD_PINNAME_TTL14 "ttl14" -#define SSD20XD_PINNAME_TTL15 "ttl15" -#define SSD20XD_PINNAME_TTL16 "ttl16" -#define SSD20XD_PINNAME_TTL17 "ttl17" -#define SSD20XD_PINNAME_TTL18 "ttl18" -#define SSD20XD_PINNAME_TTL19 "ttl19" -#define SSD20XD_PINNAME_TTL20 "ttl20" -#define SSD20XD_PINNAME_TTL21 "ttl21" -#define SSD20XD_PINNAME_TTL22 "ttl22" -#define SSD20XD_PINNAME_TTL23 "ttl23" -#define SSD20XD_PINNAME_TTL24 "ttl24" -#define SSD20XD_PINNAME_TTL25 "ttl25" -#define SSD20XD_PINNAME_TTL26 "ttl26" -#define SSD20XD_PINNAME_TTL27 "ttl27" - -#define SSD20XD_TTL_PINNAMES SSD20XD_PINNAME_TTL0, \ - SSD20XD_PINNAME_TTL1, \ - SSD20XD_PINNAME_TTL2, \ - SSD20XD_PINNAME_TTL3, \ - SSD20XD_PINNAME_TTL4, \ - SSD20XD_PINNAME_TTL5, \ - SSD20XD_PINNAME_TTL6, \ - SSD20XD_PINNAME_TTL7, \ - SSD20XD_PINNAME_TTL8, \ - SSD20XD_PINNAME_TTL9, \ - SSD20XD_PINNAME_TTL10, \ - SSD20XD_PINNAME_TTL11, \ - SSD20XD_PINNAME_TTL12, \ - SSD20XD_PINNAME_TTL13, \ - SSD20XD_PINNAME_TTL14, \ - SSD20XD_PINNAME_TTL15, \ - SSD20XD_PINNAME_TTL16, \ - SSD20XD_PINNAME_TTL17, \ - SSD20XD_PINNAME_TTL18, \ - SSD20XD_PINNAME_TTL19, \ - SSD20XD_PINNAME_TTL20, \ - SSD20XD_PINNAME_TTL21, \ - SSD20XD_PINNAME_TTL22, \ - SSD20XD_PINNAME_TTL23, \ - SSD20XD_PINNAME_TTL24, \ - SSD20XD_PINNAME_TTL25, \ - SSD20XD_PINNAME_TTL26, \ - SSD20XD_PINNAME_TTL27 - -#define SSD20XD_TTL_OFFSET_TTL0 0x80 -#define SSD20XD_TTL_OFFSET_TTL1 0x84 -#define SSD20XD_TTL_OFFSET_TTL2 0x88 -#define SSD20XD_TTL_OFFSET_TTL3 0x8c -#define SSD20XD_TTL_OFFSET_TTL4 0x90 -#define SSD20XD_TTL_OFFSET_TTL5 0x94 -#define SSD20XD_TTL_OFFSET_TTL6 0x98 -#define SSD20XD_TTL_OFFSET_TTL7 0x9c -#define SSD20XD_TTL_OFFSET_TTL8 0xa0 -#define SSD20XD_TTL_OFFSET_TTL9 0xa4 -#define SSD20XD_TTL_OFFSET_TTL10 0xa8 -#define SSD20XD_TTL_OFFSET_TTL11 0xac -#define SSD20XD_TTL_OFFSET_TTL12 0xb0 -#define SSD20XD_TTL_OFFSET_TTL13 0xb4 -#define SSD20XD_TTL_OFFSET_TTL14 0xb8 -#define SSD20XD_TTL_OFFSET_TTL15 0xbc -#define SSD20XD_TTL_OFFSET_TTL16 0xc0 -#define SSD20XD_TTL_OFFSET_TTL17 0xc4 -#define SSD20XD_TTL_OFFSET_TTL18 0xc8 -#define SSD20XD_TTL_OFFSET_TTL19 0xcc -#define SSD20XD_TTL_OFFSET_TTL20 0xd0 -#define SSD20XD_TTL_OFFSET_TTL21 0xd4 -#define SSD20XD_TTL_OFFSET_TTL22 0xd8 -#define SSD20XD_TTL_OFFSET_TTL23 0xdc -#define SSD20XD_TTL_OFFSET_TTL24 0xe0 -#define SSD20XD_TTL_OFFSET_TTL25 0xe4 -#define SSD20XD_TTL_OFFSET_TTL26 0xe8 -#define SSD20XD_TTL_OFFSET_TTL27 0xec - -#define SSD20XD_TTL_OFFSETS SSD20XD_TTL_OFFSET_TTL0, \ - SSD20XD_TTL_OFFSET_TTL1, \ - SSD20XD_TTL_OFFSET_TTL2, \ - SSD20XD_TTL_OFFSET_TTL3, \ - SSD20XD_TTL_OFFSET_TTL4, \ - SSD20XD_TTL_OFFSET_TTL5, \ - SSD20XD_TTL_OFFSET_TTL6, \ - SSD20XD_TTL_OFFSET_TTL7, \ - SSD20XD_TTL_OFFSET_TTL8, \ - SSD20XD_TTL_OFFSET_TTL9, \ - SSD20XD_TTL_OFFSET_TTL10, \ - SSD20XD_TTL_OFFSET_TTL11, \ - SSD20XD_TTL_OFFSET_TTL12, \ - SSD20XD_TTL_OFFSET_TTL13, \ - SSD20XD_TTL_OFFSET_TTL14, \ - SSD20XD_TTL_OFFSET_TTL15, \ - SSD20XD_TTL_OFFSET_TTL16, \ - SSD20XD_TTL_OFFSET_TTL17, \ - SSD20XD_TTL_OFFSET_TTL18, \ - SSD20XD_TTL_OFFSET_TTL19, \ - SSD20XD_TTL_OFFSET_TTL20, \ - SSD20XD_TTL_OFFSET_TTL21, \ - SSD20XD_TTL_OFFSET_TTL22, \ - SSD20XD_TTL_OFFSET_TTL23, \ - SSD20XD_TTL_OFFSET_TTL24, \ - SSD20XD_TTL_OFFSET_TTL25, \ - SSD20XD_TTL_OFFSET_TTL26, \ - SSD20XD_TTL_OFFSET_TTL27 - -/* On the ssd20xd the two normal uarts have dedicated pins */ -#define SSD20XD_PINNAME_UART0_RX "uart0_rx" -#define SSD20XD_PINNAME_UART0_TX "uart0_tx" - -#define SSD20XD_UART0_NAMES \ - SSD20XD_PINNAME_UART0_RX, \ - SSD20XD_PINNAME_UART0_TX - -#define SSD20XD_PINNAME_UART1_RX "uart1_rx" -#define SSD20XD_PINNAME_UART1_TX "uart1_tx" - -#define SSD20XD_UART1_NAMES \ - SSD20XD_PINNAME_UART1_RX, \ - SSD20XD_PINNAME_UART1_TX - -#define SSD20XD_OFF_UART0_RX 0x60 -#define SSD20XD_OFF_UART0_TX 0x64 - -#define SSD20XD_UART0_OFFSETS \ - SSD20XD_OFF_UART0_RX, \ - SSD20XD_OFF_UART0_TX - -#define SSD20XD_OFF_UART1_RX 0x68 -#define SSD20XD_OFF_UART1_TX 0x6c - -#define SSD20XD_UART1_OFFSETS \ - SSD20XD_OFF_UART1_RX, \ - SSD20XD_OFF_UART1_TX - -/* - * ssd20x has the same pin names but different ordering - * of the registers that control the gpio. - */ -#define SSD20XD_OFF_SD_D0 0x140 -#define SSD20XD_OFF_SD_D1 0x144 -#define SSD20XD_OFF_SD_D2 0x148 -#define SSD20XD_OFF_SD_D3 0x14c -#define SSD20XD_OFF_SD_CMD 0x150 -#define SSD20XD_OFF_SD_CLK 0x154 - -#define SSD20XD_SD_OFFSETS SSD20XD_OFF_SD_CLK, \ - SSD20XD_OFF_SD_CMD, \ - SSD20XD_OFF_SD_D0, \ - SSD20XD_OFF_SD_D1, \ - SSD20XD_OFF_SD_D2, \ - SSD20XD_OFF_SD_D3 - -static const char * const ssd20xd_names[] = { - FUART_NAMES, - SD_NAMES, - SSD20XD_UART0_NAMES, - SSD20XD_UART1_NAMES, - SSD20XD_TTL_PINNAMES, - SSD20XD_GPIO_NAMES, -}; - -static const unsigned int ssd20xd_offsets[] = { - FUART_OFFSETS, - SSD20XD_SD_OFFSETS, - SSD20XD_UART0_OFFSETS, - SSD20XD_UART1_OFFSETS, - SSD20XD_TTL_OFFSETS, - SSD20XD_GPIO_OFFSETS, -}; - -MSC313_GPIO_CHIPDATA(ssd20xd); #endif struct msc313_gpio { @@ -601,6 +344,7 @@ static int msc313_gpio_probe(struct platform_device *pdev) struct irq_domain *parent_domain; struct device_node *parent_node; struct device *dev = &pdev->dev; + int ret; match_data = of_device_get_match_data(dev); if (!match_data) @@ -655,7 +399,8 @@ static int msc313_gpio_probe(struct platform_device *pdev) gpioirqchip->handler = handle_bad_irq; gpioirqchip->default_type = IRQ_TYPE_NONE; - return devm_gpiochip_add_data(dev, gpiochip, gpio); + ret = devm_gpiochip_add_data(dev, gpiochip, gpio); + return ret; } static int msc313_gpio_remove(struct platform_device *pdev) @@ -669,10 +414,6 @@ static const struct of_device_id msc313_gpio_of_match[] = { .compatible = "mstar,msc313-gpio", .data = &msc313_data, }, - { - .compatible = "sstar,ssd20xd-gpio", - .data = &ssd20xd_data, - }, #endif { } }; @@ -715,4 +456,5 @@ static struct platform_driver msc313_gpio_driver = { .probe = msc313_gpio_probe, .remove = msc313_gpio_remove, }; + builtin_platform_driver(msc313_gpio_driver); diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c index ccaad1cb3c..c3658a597a 100644 --- a/drivers/gpio/gpio-mt7621.c +++ b/drivers/gpio/gpio-mt7621.c @@ -205,7 +205,8 @@ mediatek_gpio_xlate(struct gpio_chip *chip, } static int -mediatek_gpio_bank_probe(struct device *dev, int bank) +mediatek_gpio_bank_probe(struct device *dev, + struct device_node *node, int bank) { struct mtk *mtk = dev_get_drvdata(dev); struct mtk_gc *rg; @@ -216,6 +217,7 @@ mediatek_gpio_bank_probe(struct device *dev, int bank) memset(rg, 0, sizeof(*rg)); spin_lock_init(&rg->lock); + rg->chip.of_node = node; rg->bank = bank; dat = mtk->base + GPIO_REG_DATA + (rg->bank * GPIO_BANK_STRIDE); @@ -309,7 +311,7 @@ mediatek_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mtk); for (i = 0; i < MTK_BANK_CNT; i++) { - ret = mediatek_gpio_bank_probe(dev, i); + ret = mediatek_gpio_bank_probe(dev, np, i); if (ret) return ret; } diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 4c1f9e1091..8f429d9f36 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -1183,6 +1183,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK; mvchip->chip.ngpio = ngpios; mvchip->chip.can_sleep = false; + mvchip->chip.of_node = np; mvchip->chip.dbg_show = mvebu_gpio_dbg_show; if (soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e099c39e03..415e8df89d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1419,6 +1419,9 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->is_mpuio = pdata->is_mpuio; bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->regs = pdata->regs; +#ifdef CONFIG_OF_GPIO + bank->chip.of_node = of_node_get(node); +#endif if (node) { if (!of_property_read_bool(node, "ti,gpio-always-on")) diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index bac10c2faf..e8e9029ba5 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c @@ -170,7 +170,9 @@ static int palmas_gpio_probe(struct platform_device *pdev) palmas_gpio->gpio_chip.set = palmas_gpio_set; palmas_gpio->gpio_chip.get = palmas_gpio_get; palmas_gpio->gpio_chip.parent = &pdev->dev; - +#ifdef CONFIG_OF_GPIO + palmas_gpio->gpio_chip.of_node = pdev->dev.of_node; +#endif palmas_pdata = dev_get_platdata(palmas->dev); if (palmas_pdata && palmas_pdata->gpio_base) palmas_gpio->gpio_chip.base = palmas_pdata->gpio_base; diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 3a0bd87957..a552df298a 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -346,45 +346,51 @@ static int pch_gpio_alloc_generic_chip(struct pch_gpio *chip, static int pch_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - struct device *dev = &pdev->dev; s32 ret; struct pch_gpio *chip; int irq_base; - chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; - chip->dev = dev; + chip->dev = &pdev->dev; ret = pcim_enable_device(pdev); if (ret) { - dev_err(dev, "pci_enable_device FAILED"); + dev_err(&pdev->dev, "pci_enable_device FAILED"); return ret; } ret = pcim_iomap_regions(pdev, BIT(1), KBUILD_MODNAME); if (ret) { - dev_err(dev, "pci_request_regions FAILED-%d", ret); + dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret); return ret; } chip->base = pcim_iomap_table(pdev)[1]; - chip->ioh = id->driver_data; + + if (pdev->device == 0x8803) + chip->ioh = INTEL_EG20T_PCH; + else if (pdev->device == 0x8014) + chip->ioh = OKISEMI_ML7223m_IOH; + else if (pdev->device == 0x8043) + chip->ioh = OKISEMI_ML7223n_IOH; + chip->reg = chip->base; pci_set_drvdata(pdev, chip); spin_lock_init(&chip->spinlock); pch_gpio_setup(chip); - ret = devm_gpiochip_add_data(dev, &chip->gpio, chip); + ret = devm_gpiochip_add_data(&pdev->dev, &chip->gpio, chip); if (ret) { - dev_err(dev, "PCH gpio: Failed to register GPIO\n"); + dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n"); return ret; } - irq_base = devm_irq_alloc_descs(dev, -1, 0, + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, gpio_pins[chip->ioh], NUMA_NO_NODE); if (irq_base < 0) { - dev_warn(dev, "PCH gpio: Failed to get IRQ base num\n"); + dev_warn(&pdev->dev, "PCH gpio: Failed to get IRQ base num\n"); chip->irq_base = -1; return 0; } @@ -394,10 +400,10 @@ static int pch_gpio_probe(struct pci_dev *pdev, iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->imask); iowrite32(BIT(gpio_pins[chip->ioh]) - 1, &chip->reg->ien); - ret = devm_request_irq(dev, pdev->irq, pch_gpio_handler, + ret = devm_request_irq(&pdev->dev, pdev->irq, pch_gpio_handler, IRQF_SHARED, KBUILD_MODNAME, chip); if (ret) { - dev_err(dev, "request_irq failed\n"); + dev_err(&pdev->dev, "request_irq failed\n"); return ret; } @@ -433,14 +439,10 @@ static int __maybe_unused pch_gpio_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pch_gpio_pm_ops, pch_gpio_suspend, pch_gpio_resume); static const struct pci_device_id pch_gpio_pcidev_id[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803), - .driver_data = INTEL_EG20T_PCH }, - { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014), - .driver_data = OKISEMI_ML7223m_IOH }, - { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043), - .driver_data = OKISEMI_ML7223n_IOH }, - { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8803), - .driver_data = INTEL_EG20T_PCH }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, + { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, + { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043) }, + { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8803) }, { 0, } }; MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); diff --git a/drivers/gpio/gpio-pmic-eic-sprd.c b/drivers/gpio/gpio-pmic-eic-sprd.c index e518490c4b..9382851905 100644 --- a/drivers/gpio/gpio-pmic-eic-sprd.c +++ b/drivers/gpio/gpio-pmic-eic-sprd.c @@ -331,6 +331,7 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev) pmic_eic->chip.ngpio = SPRD_PMIC_EIC_NR; pmic_eic->chip.base = -1; pmic_eic->chip.parent = &pdev->dev; + pmic_eic->chip.of_node = pdev->dev.of_node; pmic_eic->chip.direction_input = sprd_pmic_eic_direction_input; pmic_eic->chip.request = sprd_pmic_eic_request; pmic_eic->chip.free = sprd_pmic_eic_free; diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index c7fbfa3ae4..382468e294 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -343,7 +343,8 @@ static int pxa_gpio_of_xlate(struct gpio_chip *gc, } #endif -static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, void __iomem *regbase) +static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, + struct device_node *np, void __iomem *regbase) { int i, gpio, nbanks = DIV_ROUND_UP(ngpio, 32); struct pxa_gpio_bank *bank; @@ -353,7 +354,6 @@ static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, void __iom if (!pchip->banks) return -ENOMEM; - pchip->chip.parent = pchip->dev; pchip->chip.label = "gpio-pxa"; pchip->chip.direction_input = pxa_gpio_direction_input; pchip->chip.direction_output = pxa_gpio_direction_output; @@ -365,6 +365,7 @@ static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, void __iom pchip->chip.free = gpiochip_generic_free; #ifdef CONFIG_OF_GPIO + pchip->chip.of_node = np; pchip->chip.of_xlate = pxa_gpio_of_xlate; pchip->chip.of_gpio_n_cells = 2; #endif @@ -674,7 +675,8 @@ static int pxa_gpio_probe(struct platform_device *pdev) } /* Initialize GPIO chips */ - ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, gpio_reg_base); + ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, pdev->dev.of_node, + gpio_reg_base); if (ret) { clk_put(clk); return ret; diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c index 3c414e0005..64a552ecc2 100644 --- a/drivers/gpio/gpio-raspberrypi-exp.c +++ b/drivers/gpio/gpio-raspberrypi-exp.c @@ -221,6 +221,7 @@ static int rpi_exp_gpio_probe(struct platform_device *pdev) rpi_gpio->gc.parent = dev; rpi_gpio->gc.label = MODULE_NAME; rpi_gpio->gc.owner = THIS_MODULE; + rpi_gpio->gc.of_node = np; rpi_gpio->gc.base = -1; rpi_gpio->gc.ngpio = NUM_GPIO; diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index bd2e16d6e2..f7b653314e 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -477,6 +477,7 @@ static void gpio_rcar_enable_inputs(struct gpio_rcar_priv *p) static int gpio_rcar_probe(struct platform_device *pdev) { struct gpio_rcar_priv *p; + struct resource *irq; struct gpio_chip *gpio_chip; struct irq_chip *irq_chip; struct gpio_irq_chip *girq; @@ -501,10 +502,12 @@ static int gpio_rcar_probe(struct platform_device *pdev) pm_runtime_enable(dev); - ret = platform_get_irq(pdev, 0); - if (ret < 0) + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(dev, "missing IRQ\n"); + ret = -EINVAL; goto err0; - p->irq_parent = ret; + } p->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(p->base)) { @@ -552,10 +555,11 @@ static int gpio_rcar_probe(struct platform_device *pdev) goto err0; } - ret = devm_request_irq(dev, p->irq_parent, gpio_rcar_irq_handler, - IRQF_SHARED, name, p); - if (ret) { + p->irq_parent = irq->start; + if (devm_request_irq(dev, irq->start, gpio_rcar_irq_handler, + IRQF_SHARED, name, p)) { dev_err(dev, "failed to request IRQ\n"); + ret = -ENOENT; goto err1; } diff --git a/drivers/gpio/gpio-rda.c b/drivers/gpio/gpio-rda.c index 62ba18b3a6..4638464311 100644 --- a/drivers/gpio/gpio-rda.c +++ b/drivers/gpio/gpio-rda.c @@ -197,6 +197,7 @@ static void rda_gpio_irq_handler(struct irq_desc *desc) static int rda_gpio_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; struct gpio_irq_chip *girq; struct rda_gpio *rda_gpio; @@ -239,6 +240,8 @@ static int rda_gpio_probe(struct platform_device *pdev) rda_gpio->chip.label = dev_name(dev); rda_gpio->chip.ngpio = ngpios; rda_gpio->chip.base = -1; + rda_gpio->chip.parent = dev; + rda_gpio->chip.of_node = np; if (rda_gpio->irq >= 0) { rda_gpio->irq_chip.name = "rda-gpio", diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 6383136cbe..69c2197420 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -244,12 +244,16 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config chip = &gpio->gpio_chip; chip->parent = config->parent; - chip->fwnode = config->fwnode; chip->base = -1; chip->ngpio = config->ngpio; chip->names = config->names; chip->label = config->label ?: dev_name(config->parent); +#if defined(CONFIG_OF_GPIO) + /* gpiolib will use of_node of the parent if chip->of_node is NULL */ + chip->of_node = to_of_node(config->fwnode); +#endif /* CONFIG_OF_GPIO */ + /* * If our regmap is fast_io we should probably set can_sleep to false. * Right now, the regmap doesn't save this property, nor is there any diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 099e358d24..24155c038f 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -467,22 +467,6 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) return ret; } -static int rockchip_irq_reqres(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct rockchip_pin_bank *bank = gc->private; - - return gpiochip_reqres_irq(&bank->gpio_chip, d->hwirq); -} - -static void rockchip_irq_relres(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct rockchip_pin_bank *bank = gc->private; - - gpiochip_relres_irq(&bank->gpio_chip, d->hwirq); -} - static void rockchip_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); @@ -554,8 +538,6 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank) gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; - gc->chip_types[0].chip.irq_request_resources = rockchip_irq_reqres; - gc->chip_types[0].chip.irq_release_resources = rockchip_irq_relres; gc->wake_enabled = IRQ_MSK(bank->nr_pins); /* @@ -586,6 +568,9 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank) gc->ngpio = bank->nr_pins; gc->label = bank->name; gc->parent = bank->dev; +#ifdef CONFIG_OF_GPIO + gc->of_node = of_node_get(bank->of_node); +#endif ret = gpiochip_add_data(gc, bank); if (ret) { diff --git a/drivers/gpio/gpio-sama5d2-piobu.c b/drivers/gpio/gpio-sama5d2-piobu.c index 3e95da717f..b7c9506581 100644 --- a/drivers/gpio/gpio-sama5d2-piobu.c +++ b/drivers/gpio/gpio-sama5d2-piobu.c @@ -192,6 +192,7 @@ static int sama5d2_piobu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, piobu); piobu->chip.label = pdev->name; piobu->chip.parent = &pdev->dev; + piobu->chip.of_node = pdev->dev.of_node; piobu->chip.owner = THIS_MODULE, piobu->chip.get_direction = sama5d2_piobu_get_direction, piobu->chip.direction_input = sama5d2_piobu_direction_input, diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index acda4c5052..0600f71462 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -139,7 +139,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned int gpio_num, /* * according to the datasheet, writing to the level register has no * effect when GPIO is programmed as input. - * Actually the level register is read-only when configured as input. + * Actually the the level register is read-only when configured as input. * Thus presetting the output level before switching to output is _NOT_ possible. * Hence we set the level after configuring the GPIO as output. * But we cannot prevent a short low pulse if direction is set to high diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c index 9bff63990e..9dd9dabb57 100644 --- a/drivers/gpio/gpio-sprd.c +++ b/drivers/gpio/gpio-sprd.c @@ -237,6 +237,7 @@ static int sprd_gpio_probe(struct platform_device *pdev) sprd_gpio->chip.ngpio = SPRD_GPIO_NR; sprd_gpio->chip.base = -1; sprd_gpio->chip.parent = &pdev->dev; + sprd_gpio->chip.of_node = pdev->dev.of_node; sprd_gpio->chip.request = sprd_gpio_request; sprd_gpio->chip.free = sprd_gpio_free; sprd_gpio->chip.get = sprd_gpio_get; diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index e07cca0f8d..392fcab06a 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c @@ -324,7 +324,7 @@ static int gsta_alloc_irq_chip(struct gsta_gpio *chip) if (rv) return rv; - /* Set up all 128 interrupts: code from setup_generic_chip */ + /* Set up all all 128 interrupts: code from setup_generic_chip */ { struct irq_chip_type *ct = gc->chip_types; int i, j; diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 0fa4f0a933..dd4d58b4ae 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -477,6 +477,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.parent = &pdev->dev; + stmpe_gpio->chip.of_node = np; stmpe_gpio->chip.base = -1; if (IS_ENABLED(CONFIG_DEBUG_FS)) diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 443fe975bf..8d15849248 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -319,6 +319,7 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) tc3589x_gpio->chip.ngpio = tc3589x->num_gpio; tc3589x_gpio->chip.parent = &pdev->dev; tc3589x_gpio->chip.base = -1; + tc3589x_gpio->chip.of_node = np; girq = &tc3589x_gpio->chip.irq; girq->chip = &tc3589x_gpio_irq_chip; diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 8d298beffd..00762de3d4 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -14,8 +14,6 @@ #include #include -#include -#include /* security registers */ #define TEGRA186_GPIO_CTL_SCR 0x0c @@ -71,8 +69,6 @@ struct tegra_gpio_soc { const char *name; unsigned int instance; - unsigned int num_irqs_per_bank; - const struct tegra186_pin_range *pin_ranges; unsigned int num_pin_ranges; const char *pinmux; @@ -85,8 +81,6 @@ struct tegra_gpio { unsigned int *irq; const struct tegra_gpio_soc *soc; - unsigned int num_irqs_per_bank; - unsigned int num_banks; void __iomem *secure; void __iomem *base; @@ -462,7 +456,7 @@ static void tegra186_gpio_irq(struct irq_desc *desc) struct irq_domain *domain = gpio->gpio.irq.domain; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int parent = irq_desc_get_irq(desc); - unsigned int i, j, offset = 0; + unsigned int i, offset = 0; chained_irq_enter(chip, desc); @@ -475,12 +469,7 @@ static void tegra186_gpio_irq(struct irq_desc *desc) base = gpio->base + port->bank * 0x1000 + port->port * 0x200; /* skip ports that are not associated with this bank */ - for (j = 0; j < gpio->num_irqs_per_bank; j++) { - if (parent == gpio->irq[port->bank * gpio->num_irqs_per_bank + j]) - break; - } - - if (j == gpio->num_irqs_per_bank) + if (parent != gpio->irq[port->bank]) goto skip; value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); @@ -582,7 +571,6 @@ static const struct of_device_id tegra186_pmc_of_match[] = { static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) { - struct device *dev = gpio->gpio.parent; unsigned int i, j; u32 value; @@ -601,60 +589,17 @@ static void tegra186_gpio_init_route_mapping(struct tegra_gpio *gpio) */ if ((value & TEGRA186_GPIO_CTL_SCR_SEC_REN) == 0 && (value & TEGRA186_GPIO_CTL_SCR_SEC_WEN) == 0) { - /* - * On Tegra194 and later, each pin can be routed to one or more - * interrupts. - */ - for (j = 0; j < gpio->num_irqs_per_bank; j++) { - dev_dbg(dev, "programming default interrupt routing for port %s\n", - port->name); - + for (j = 0; j < 8; j++) { offset = TEGRA186_GPIO_INT_ROUTE_MAPPING(p, j); - /* - * By default we only want to route GPIO pins to IRQ 0. This works - * only under the assumption that we're running as the host kernel - * and hence all GPIO pins are owned by Linux. - * - * For cases where Linux is the guest OS, the hypervisor will have - * to configure the interrupt routing and pass only the valid - * interrupts via device tree. - */ - if (j == 0) { - value = readl(base + offset); - value = BIT(port->pins) - 1; - writel(value, base + offset); - } + value = readl(base + offset); + value = BIT(port->pins) - 1; + writel(value, base + offset); } } } } -static unsigned int tegra186_gpio_irqs_per_bank(struct tegra_gpio *gpio) -{ - struct device *dev = gpio->gpio.parent; - - if (gpio->num_irq > gpio->num_banks) { - if (gpio->num_irq % gpio->num_banks != 0) - goto error; - } - - if (gpio->num_irq < gpio->num_banks) - goto error; - - gpio->num_irqs_per_bank = gpio->num_irq / gpio->num_banks; - - if (gpio->num_irqs_per_bank > gpio->soc->num_irqs_per_bank) - goto error; - - return 0; - -error: - dev_err(dev, "invalid number of interrupts (%u) for %u banks\n", - gpio->num_irq, gpio->num_banks); - return -EINVAL; -} - static int tegra186_gpio_probe(struct platform_device *pdev) { unsigned int i, j, offset; @@ -669,17 +614,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) return -ENOMEM; gpio->soc = device_get_match_data(&pdev->dev); - gpio->gpio.label = gpio->soc->name; - gpio->gpio.parent = &pdev->dev; - /* count the number of banks in the controller */ - for (i = 0; i < gpio->soc->num_ports; i++) - if (gpio->soc->ports[i].bank > gpio->num_banks) - gpio->num_banks = gpio->soc->ports[i].bank; - - gpio->num_banks++; - - /* get register apertures */ gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); if (IS_ERR(gpio->secure)) { gpio->secure = devm_platform_ioremap_resource(pdev, 0); @@ -700,10 +635,6 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->num_irq = err; - err = tegra186_gpio_irqs_per_bank(gpio); - if (err < 0) - return err; - gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq), GFP_KERNEL); if (!gpio->irq) @@ -717,6 +648,9 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->irq[i] = err; } + gpio->gpio.label = gpio->soc->name; + gpio->gpio.parent = &pdev->dev; + gpio->gpio.request = gpiochip_generic_request; gpio->gpio.free = gpiochip_generic_free; gpio->gpio.get_direction = tegra186_gpio_get_direction; @@ -756,6 +690,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->gpio.names = (const char * const *)names; #if defined(CONFIG_OF_GPIO) + gpio->gpio.of_node = pdev->dev.of_node; gpio->gpio.of_gpio_n_cells = 2; gpio->gpio.of_xlate = tegra186_gpio_of_xlate; #endif /* CONFIG_OF_GPIO */ @@ -779,31 +714,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) irq->parent_handler = tegra186_gpio_irq; irq->parent_handler_data = gpio; irq->num_parents = gpio->num_irq; - - /* - * To simplify things, use a single interrupt per bank for now. Some - * chips support up to 8 interrupts per bank, which can be useful to - * distribute the load and decrease the processing latency for GPIOs - * but it also requires a more complicated interrupt routing than we - * currently program. - */ - if (gpio->num_irqs_per_bank > 1) { - irq->parents = devm_kcalloc(&pdev->dev, gpio->num_banks, - sizeof(*irq->parents), GFP_KERNEL); - if (!irq->parents) - return -ENOMEM; - - for (i = 0; i < gpio->num_banks; i++) - irq->parents[i] = gpio->irq[i * gpio->num_irqs_per_bank]; - - irq->num_parents = gpio->num_banks; - } else { - irq->num_parents = gpio->num_irq; - irq->parents = gpio->irq; - } - - if (gpio->soc->num_irqs_per_bank > 1) - tegra186_gpio_init_route_mapping(gpio); + irq->parents = gpio->irq; np = of_find_matching_node(NULL, tegra186_pmc_of_match); if (np) { @@ -814,6 +725,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev) return -EPROBE_DEFER; } + tegra186_gpio_init_route_mapping(gpio); + irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, sizeof(*irq->map), GFP_KERNEL); if (!irq->map) @@ -870,7 +783,6 @@ static const struct tegra_gpio_soc tegra186_main_soc = { .ports = tegra186_main_ports, .name = "tegra186-gpio", .instance = 0, - .num_irqs_per_bank = 1, }; #define TEGRA186_AON_GPIO_PORT(_name, _bank, _port, _pins) \ @@ -897,7 +809,6 @@ static const struct tegra_gpio_soc tegra186_aon_soc = { .ports = tegra186_aon_ports, .name = "tegra186-gpio-aon", .instance = 1, - .num_irqs_per_bank = 1, }; #define TEGRA194_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ @@ -949,7 +860,6 @@ static const struct tegra_gpio_soc tegra194_main_soc = { .ports = tegra194_main_ports, .name = "tegra194-gpio", .instance = 0, - .num_irqs_per_bank = 8, .num_pin_ranges = ARRAY_SIZE(tegra194_main_pin_ranges), .pin_ranges = tegra194_main_pin_ranges, .pinmux = "nvidia,tegra194-pinmux", @@ -976,125 +886,6 @@ static const struct tegra_gpio_soc tegra194_aon_soc = { .ports = tegra194_aon_ports, .name = "tegra194-gpio-aon", .instance = 1, - .num_irqs_per_bank = 8, -}; - -#define TEGRA234_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA234_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } - -static const struct tegra_gpio_port tegra234_main_ports[] = { - TEGRA234_MAIN_GPIO_PORT( A, 0, 0, 8), - TEGRA234_MAIN_GPIO_PORT( B, 0, 3, 1), - TEGRA234_MAIN_GPIO_PORT( C, 5, 1, 8), - TEGRA234_MAIN_GPIO_PORT( D, 5, 2, 4), - TEGRA234_MAIN_GPIO_PORT( E, 5, 3, 8), - TEGRA234_MAIN_GPIO_PORT( F, 5, 4, 6), - TEGRA234_MAIN_GPIO_PORT( G, 4, 0, 8), - TEGRA234_MAIN_GPIO_PORT( H, 4, 1, 8), - TEGRA234_MAIN_GPIO_PORT( I, 4, 2, 7), - TEGRA234_MAIN_GPIO_PORT( J, 5, 0, 6), - TEGRA234_MAIN_GPIO_PORT( K, 3, 0, 8), - TEGRA234_MAIN_GPIO_PORT( L, 3, 1, 4), - TEGRA234_MAIN_GPIO_PORT( M, 2, 0, 8), - TEGRA234_MAIN_GPIO_PORT( N, 2, 1, 8), - TEGRA234_MAIN_GPIO_PORT( P, 2, 2, 8), - TEGRA234_MAIN_GPIO_PORT( Q, 2, 3, 8), - TEGRA234_MAIN_GPIO_PORT( R, 2, 4, 6), - TEGRA234_MAIN_GPIO_PORT( X, 1, 0, 8), - TEGRA234_MAIN_GPIO_PORT( Y, 1, 1, 8), - TEGRA234_MAIN_GPIO_PORT( Z, 1, 2, 8), - TEGRA234_MAIN_GPIO_PORT(AC, 0, 1, 8), - TEGRA234_MAIN_GPIO_PORT(AD, 0, 2, 4), - TEGRA234_MAIN_GPIO_PORT(AE, 3, 3, 2), - TEGRA234_MAIN_GPIO_PORT(AF, 3, 4, 4), - TEGRA234_MAIN_GPIO_PORT(AG, 3, 2, 8), -}; - -static const struct tegra_gpio_soc tegra234_main_soc = { - .num_ports = ARRAY_SIZE(tegra234_main_ports), - .ports = tegra234_main_ports, - .name = "tegra234-gpio", - .instance = 0, - .num_irqs_per_bank = 8, -}; - -#define TEGRA234_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA234_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } - -static const struct tegra_gpio_port tegra234_aon_ports[] = { - TEGRA234_AON_GPIO_PORT(AA, 0, 4, 8), - TEGRA234_AON_GPIO_PORT(BB, 0, 5, 4), - TEGRA234_AON_GPIO_PORT(CC, 0, 2, 8), - TEGRA234_AON_GPIO_PORT(DD, 0, 3, 3), - TEGRA234_AON_GPIO_PORT(EE, 0, 0, 8), - TEGRA234_AON_GPIO_PORT(GG, 0, 1, 1), -}; - -static const struct tegra_gpio_soc tegra234_aon_soc = { - .num_ports = ARRAY_SIZE(tegra234_aon_ports), - .ports = tegra234_aon_ports, - .name = "tegra234-gpio-aon", - .instance = 1, - .num_irqs_per_bank = 8, -}; - -#define TEGRA241_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA241_MAIN_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } - -static const struct tegra_gpio_port tegra241_main_ports[] = { - TEGRA241_MAIN_GPIO_PORT(A, 0, 0, 8), - TEGRA241_MAIN_GPIO_PORT(B, 0, 1, 8), - TEGRA241_MAIN_GPIO_PORT(C, 0, 2, 2), - TEGRA241_MAIN_GPIO_PORT(D, 0, 3, 6), - TEGRA241_MAIN_GPIO_PORT(E, 0, 4, 8), - TEGRA241_MAIN_GPIO_PORT(F, 1, 0, 8), - TEGRA241_MAIN_GPIO_PORT(G, 1, 1, 8), - TEGRA241_MAIN_GPIO_PORT(H, 1, 2, 8), - TEGRA241_MAIN_GPIO_PORT(J, 1, 3, 8), - TEGRA241_MAIN_GPIO_PORT(K, 1, 4, 4), - TEGRA241_MAIN_GPIO_PORT(L, 1, 5, 6), -}; - -static const struct tegra_gpio_soc tegra241_main_soc = { - .num_ports = ARRAY_SIZE(tegra241_main_ports), - .ports = tegra241_main_ports, - .name = "tegra241-gpio", - .instance = 0, -}; - -#define TEGRA241_AON_GPIO_PORT(_name, _bank, _port, _pins) \ - [TEGRA241_AON_GPIO_PORT_##_name] = { \ - .name = #_name, \ - .bank = _bank, \ - .port = _port, \ - .pins = _pins, \ - } - -static const struct tegra_gpio_port tegra241_aon_ports[] = { - TEGRA241_AON_GPIO_PORT(AA, 0, 0, 8), - TEGRA241_AON_GPIO_PORT(BB, 0, 0, 4), -}; - -static const struct tegra_gpio_soc tegra241_aon_soc = { - .num_ports = ARRAY_SIZE(tegra241_aon_ports), - .ports = tegra241_aon_ports, - .name = "tegra241-gpio-aon", - .instance = 1, }; static const struct of_device_id tegra186_gpio_of_match[] = { @@ -1110,12 +901,6 @@ static const struct of_device_id tegra186_gpio_of_match[] = { }, { .compatible = "nvidia,tegra194-gpio-aon", .data = &tegra194_aon_soc - }, { - .compatible = "nvidia,tegra234-gpio", - .data = &tegra234_main_soc - }, { - .compatible = "nvidia,tegra234-gpio-aon", - .data = &tegra234_aon_soc }, { /* sentinel */ } @@ -1127,8 +912,6 @@ static const struct acpi_device_id tegra186_gpio_acpi_match[] = { { .id = "NVDA0208", .driver_data = (kernel_ulong_t)&tegra186_aon_soc }, { .id = "NVDA0308", .driver_data = (kernel_ulong_t)&tegra194_main_soc }, { .id = "NVDA0408", .driver_data = (kernel_ulong_t)&tegra194_aon_soc }, - { .id = "NVDA0508", .driver_data = (kernel_ulong_t)&tegra241_main_soc }, - { .id = "NVDA0608", .driver_data = (kernel_ulong_t)&tegra241_aon_soc }, {} }; MODULE_DEVICE_TABLE(acpi, tegra186_gpio_acpi_match); diff --git a/drivers/gpio/gpio-tps65218.c b/drivers/gpio/gpio-tps65218.c index e1d425a188..3517debe2b 100644 --- a/drivers/gpio/gpio-tps65218.c +++ b/drivers/gpio/gpio-tps65218.c @@ -196,6 +196,9 @@ static int tps65218_gpio_probe(struct platform_device *pdev) tps65218_gpio->tps65218 = tps65218; tps65218_gpio->gpio_chip = template_chip; tps65218_gpio->gpio_chip.parent = &pdev->dev; +#ifdef CONFIG_OF_GPIO + tps65218_gpio->gpio_chip.of_node = pdev->dev.of_node; +#endif return devm_gpiochip_add_data(&pdev->dev, &tps65218_gpio->gpio_chip, tps65218_gpio); @@ -227,3 +230,4 @@ module_platform_driver(tps65218_gpio_driver); MODULE_AUTHOR("Nicolas Saenz Julienne "); MODULE_DESCRIPTION("GPO interface for TPS65218 PMICs"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps65218-gpio"); diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index c5713524b5..da0304b764 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -77,8 +77,6 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) struct tps6586x_platform_data *pdata; struct tps6586x_gpio *tps6586x_gpio; - device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); - pdata = dev_get_platdata(pdev->dev.parent); tps6586x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps6586x_gpio), GFP_KERNEL); @@ -99,6 +97,9 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; tps6586x_gpio->gpio_chip.to_irq = tps6586x_gpio_to_irq; +#ifdef CONFIG_OF_GPIO + tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; +#endif if (pdata && pdata->gpio_base) tps6586x_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 321e6945f0..7fa8c84108 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -111,8 +111,6 @@ static int tps65910_gpio_probe(struct platform_device *pdev) int ret; int i; - device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); - tps65910_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65910_gpio), GFP_KERNEL); if (!tps65910_gpio) @@ -139,7 +137,9 @@ static int tps65910_gpio_probe(struct platform_device *pdev) tps65910_gpio->gpio_chip.set = tps65910_gpio_set; tps65910_gpio->gpio_chip.get = tps65910_gpio_get; tps65910_gpio->gpio_chip.parent = &pdev->dev; - +#ifdef CONFIG_OF_GPIO + tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node; +#endif if (pdata && pdata->gpio_base) tps65910_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-ts5500.c b/drivers/gpio/gpio-ts5500.c index b159e92a36..c918904884 100644 --- a/drivers/gpio/gpio-ts5500.c +++ b/drivers/gpio/gpio-ts5500.c @@ -317,19 +317,22 @@ static int ts5500_dio_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const char *name = dev_name(dev); struct ts5500_priv *priv; + struct resource *res; unsigned long flags; int ret; - ret = platform_get_irq(pdev, 0); - if (ret < 0) - return ret; + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "missing IRQ resource\n"); + return -EINVAL; + } priv = devm_kzalloc(dev, sizeof(struct ts5500_priv), GFP_KERNEL); if (!priv) return -ENOMEM; platform_set_drvdata(pdev, priv); - priv->hwirq = ret; + priv->hwirq = res->start; spin_lock_init(&priv->lock); priv->gpio_chip.owner = THIS_MODULE; diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index 6c3fbf382d..648fb418d7 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -80,8 +80,6 @@ static int gpo_twl6040_probe(struct platform_device *pdev) struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev); int ret; - device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); - twl6040gpo_chip.base = -1; if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0) @@ -90,6 +88,9 @@ static int gpo_twl6040_probe(struct platform_device *pdev) twl6040gpo_chip.ngpio = 1; /* twl6041 have 1 GPO */ twl6040gpo_chip.parent = &pdev->dev; +#ifdef CONFIG_OF_GPIO + twl6040gpo_chip.of_node = twl6040_core_dev->of_node; +#endif ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, NULL); if (ret < 0) { diff --git a/drivers/gpio/gpio-uniphier.c b/drivers/gpio/gpio-uniphier.c index 19ce6675cb..39dca147d5 100644 --- a/drivers/gpio/gpio-uniphier.c +++ b/drivers/gpio/gpio-uniphier.c @@ -179,8 +179,8 @@ static int uniphier_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) static void uniphier_gpio_irq_mask(struct irq_data *data) { - struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); - u32 mask = BIT(irqd_to_hwirq(data)); + struct uniphier_gpio_priv *priv = data->chip_data; + u32 mask = BIT(data->hwirq); uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, 0); @@ -189,8 +189,8 @@ static void uniphier_gpio_irq_mask(struct irq_data *data) static void uniphier_gpio_irq_unmask(struct irq_data *data) { - struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); - u32 mask = BIT(irqd_to_hwirq(data)); + struct uniphier_gpio_priv *priv = data->chip_data; + u32 mask = BIT(data->hwirq); uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, mask); @@ -199,8 +199,8 @@ static void uniphier_gpio_irq_unmask(struct irq_data *data) static int uniphier_gpio_irq_set_type(struct irq_data *data, unsigned int type) { - struct uniphier_gpio_priv *priv = irq_data_get_irq_chip_data(data); - u32 mask = BIT(irqd_to_hwirq(data)); + struct uniphier_gpio_priv *priv = data->chip_data; + u32 mask = BIT(data->hwirq); u32 val = 0; if (type == IRQ_TYPE_EDGE_BOTH) { @@ -297,8 +297,7 @@ static int uniphier_gpio_irq_domain_activate(struct irq_domain *domain, struct uniphier_gpio_priv *priv = domain->host_data; struct gpio_chip *chip = &priv->chip; - return gpiochip_lock_as_irq(chip, - irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); + return gpiochip_lock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); } static void uniphier_gpio_irq_domain_deactivate(struct irq_domain *domain, @@ -307,8 +306,7 @@ static void uniphier_gpio_irq_domain_deactivate(struct irq_domain *domain, struct uniphier_gpio_priv *priv = domain->host_data; struct gpio_chip *chip = &priv->chip; - gpiochip_unlock_as_irq(chip, - irqd_to_hwirq(data) + UNIPHIER_GPIO_IRQ_OFFSET); + gpiochip_unlock_as_irq(chip, data->hwirq + UNIPHIER_GPIO_IRQ_OFFSET); } static const struct irq_domain_ops uniphier_gpio_irq_domain_ops = { diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index 20780c35da..e0f2b67558 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -298,6 +298,7 @@ static int vf610_gpio_probe(struct platform_device *pdev) } gc = &port->gc; + gc->of_node = np; gc->parent = dev; gc->label = "vf610-gpio"; gc->ngpio = VF610_GPIO_PER_PORT; diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c index fcc5e8c089..dd3b23c958 100644 --- a/drivers/gpio/gpio-virtio.c +++ b/drivers/gpio/gpio-virtio.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -29,30 +28,12 @@ struct virtio_gpio_line { unsigned int rxlen; }; -struct vgpio_irq_line { - u8 type; - bool disabled; - bool masked; - bool queued; - bool update_pending; - bool queue_pending; - - struct virtio_gpio_irq_request ireq ____cacheline_aligned; - struct virtio_gpio_irq_response ires ____cacheline_aligned; -}; - struct virtio_gpio { struct virtio_device *vdev; struct mutex lock; /* Protects virtqueue operation */ struct gpio_chip gc; struct virtio_gpio_line *lines; struct virtqueue *request_vq; - - /* irq support */ - struct virtqueue *event_vq; - struct mutex irq_lock; /* Protects irq operation */ - raw_spinlock_t eventq_lock; /* Protects queuing of the buffer */ - struct vgpio_irq_line *irq_lines; }; static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio, @@ -201,238 +182,6 @@ static void virtio_gpio_set(struct gpio_chip *gc, unsigned int gpio, int value) virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_SET_VALUE, gpio, value, NULL); } -/* Interrupt handling */ -static void virtio_gpio_irq_prepare(struct virtio_gpio *vgpio, u16 gpio) -{ - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[gpio]; - struct virtio_gpio_irq_request *ireq = &irq_line->ireq; - struct virtio_gpio_irq_response *ires = &irq_line->ires; - struct scatterlist *sgs[2], req_sg, res_sg; - int ret; - - if (WARN_ON(irq_line->queued || irq_line->masked || irq_line->disabled)) - return; - - ireq->gpio = cpu_to_le16(gpio); - sg_init_one(&req_sg, ireq, sizeof(*ireq)); - sg_init_one(&res_sg, ires, sizeof(*ires)); - sgs[0] = &req_sg; - sgs[1] = &res_sg; - - ret = virtqueue_add_sgs(vgpio->event_vq, sgs, 1, 1, irq_line, GFP_ATOMIC); - if (ret) { - dev_err(&vgpio->vdev->dev, "failed to add request to eventq\n"); - return; - } - - irq_line->queued = true; - virtqueue_kick(vgpio->event_vq); -} - -static void virtio_gpio_irq_enable(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - - raw_spin_lock(&vgpio->eventq_lock); - irq_line->disabled = false; - irq_line->masked = false; - irq_line->queue_pending = true; - raw_spin_unlock(&vgpio->eventq_lock); - - irq_line->update_pending = true; -} - -static void virtio_gpio_irq_disable(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - - raw_spin_lock(&vgpio->eventq_lock); - irq_line->disabled = true; - irq_line->masked = true; - irq_line->queue_pending = false; - raw_spin_unlock(&vgpio->eventq_lock); - - irq_line->update_pending = true; -} - -static void virtio_gpio_irq_mask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - - raw_spin_lock(&vgpio->eventq_lock); - irq_line->masked = true; - raw_spin_unlock(&vgpio->eventq_lock); -} - -static void virtio_gpio_irq_unmask(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - - raw_spin_lock(&vgpio->eventq_lock); - irq_line->masked = false; - - /* Queue the buffer unconditionally on unmask */ - virtio_gpio_irq_prepare(vgpio, d->hwirq); - raw_spin_unlock(&vgpio->eventq_lock); -} - -static int virtio_gpio_irq_set_type(struct irq_data *d, unsigned int type) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - type = VIRTIO_GPIO_IRQ_TYPE_EDGE_RISING; - break; - case IRQ_TYPE_EDGE_FALLING: - type = VIRTIO_GPIO_IRQ_TYPE_EDGE_FALLING; - break; - case IRQ_TYPE_EDGE_BOTH: - type = VIRTIO_GPIO_IRQ_TYPE_EDGE_BOTH; - break; - case IRQ_TYPE_LEVEL_LOW: - type = VIRTIO_GPIO_IRQ_TYPE_LEVEL_LOW; - break; - case IRQ_TYPE_LEVEL_HIGH: - type = VIRTIO_GPIO_IRQ_TYPE_LEVEL_HIGH; - break; - default: - dev_err(&vgpio->vdev->dev, "unsupported irq type: %u\n", type); - return -EINVAL; - } - - irq_line->type = type; - irq_line->update_pending = true; - - return 0; -} - -static void virtio_gpio_irq_bus_lock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - - mutex_lock(&vgpio->irq_lock); -} - -static void virtio_gpio_irq_bus_sync_unlock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct virtio_gpio *vgpio = gpiochip_get_data(gc); - struct vgpio_irq_line *irq_line = &vgpio->irq_lines[d->hwirq]; - u8 type = irq_line->disabled ? VIRTIO_GPIO_IRQ_TYPE_NONE : irq_line->type; - unsigned long flags; - - if (irq_line->update_pending) { - irq_line->update_pending = false; - virtio_gpio_req(vgpio, VIRTIO_GPIO_MSG_IRQ_TYPE, d->hwirq, type, - NULL); - - /* Queue the buffer only after interrupt is enabled */ - raw_spin_lock_irqsave(&vgpio->eventq_lock, flags); - if (irq_line->queue_pending) { - irq_line->queue_pending = false; - virtio_gpio_irq_prepare(vgpio, d->hwirq); - } - raw_spin_unlock_irqrestore(&vgpio->eventq_lock, flags); - } - - mutex_unlock(&vgpio->irq_lock); -} - -static struct irq_chip vgpio_irq_chip = { - .name = "virtio-gpio", - .irq_enable = virtio_gpio_irq_enable, - .irq_disable = virtio_gpio_irq_disable, - .irq_mask = virtio_gpio_irq_mask, - .irq_unmask = virtio_gpio_irq_unmask, - .irq_set_type = virtio_gpio_irq_set_type, - - /* These are required to implement irqchip for slow busses */ - .irq_bus_lock = virtio_gpio_irq_bus_lock, - .irq_bus_sync_unlock = virtio_gpio_irq_bus_sync_unlock, -}; - -static bool ignore_irq(struct virtio_gpio *vgpio, int gpio, - struct vgpio_irq_line *irq_line) -{ - bool ignore = false; - - raw_spin_lock(&vgpio->eventq_lock); - irq_line->queued = false; - - /* Interrupt is disabled currently */ - if (irq_line->masked || irq_line->disabled) { - ignore = true; - goto unlock; - } - - /* - * Buffer is returned as the interrupt was disabled earlier, but is - * enabled again now. Requeue the buffers. - */ - if (irq_line->ires.status == VIRTIO_GPIO_IRQ_STATUS_INVALID) { - virtio_gpio_irq_prepare(vgpio, gpio); - ignore = true; - goto unlock; - } - - if (WARN_ON(irq_line->ires.status != VIRTIO_GPIO_IRQ_STATUS_VALID)) - ignore = true; - -unlock: - raw_spin_unlock(&vgpio->eventq_lock); - - return ignore; -} - -static void virtio_gpio_event_vq(struct virtqueue *vq) -{ - struct virtio_gpio *vgpio = vq->vdev->priv; - struct device *dev = &vgpio->vdev->dev; - struct vgpio_irq_line *irq_line; - int gpio, ret; - unsigned int len; - - while (true) { - irq_line = virtqueue_get_buf(vgpio->event_vq, &len); - if (!irq_line) - break; - - if (len != sizeof(irq_line->ires)) { - dev_err(dev, "irq with incorrect length (%u : %u)\n", - len, (unsigned int)sizeof(irq_line->ires)); - continue; - } - - /* - * Find GPIO line number from the offset of irq_line within the - * irq_lines block. We can also get GPIO number from - * irq-request, but better not to rely on a buffer returned by - * remote. - */ - gpio = irq_line - vgpio->irq_lines; - WARN_ON(gpio >= vgpio->gc.ngpio); - - if (unlikely(ignore_irq(vgpio, gpio, irq_line))) - continue; - - ret = generic_handle_domain_irq(vgpio->gc.irq.domain, gpio); - if (ret) - dev_err(dev, "failed to handle interrupt: %d\n", ret); - } -} - static void virtio_gpio_request_vq(struct virtqueue *vq) { struct virtio_gpio_line *line; @@ -450,22 +199,21 @@ static void virtio_gpio_request_vq(struct virtqueue *vq) static void virtio_gpio_free_vqs(struct virtio_device *vdev) { - virtio_reset_device(vdev); + vdev->config->reset(vdev); vdev->config->del_vqs(vdev); } static int virtio_gpio_alloc_vqs(struct virtio_gpio *vgpio, struct virtio_device *vdev) { - const char * const names[] = { "requestq", "eventq" }; + const char * const names[] = { "requestq" }; vq_callback_t *cbs[] = { virtio_gpio_request_vq, - virtio_gpio_event_vq, }; - struct virtqueue *vqs[2] = { NULL, NULL }; + struct virtqueue *vqs[1] = { NULL }; int ret; - ret = virtio_find_vqs(vdev, vgpio->irq_lines ? 2 : 1, vqs, cbs, names, NULL); + ret = virtio_find_vqs(vdev, 1, vqs, cbs, names, NULL); if (ret) { dev_err(&vdev->dev, "failed to find vqs: %d\n", ret); return ret; @@ -473,23 +221,11 @@ static int virtio_gpio_alloc_vqs(struct virtio_gpio *vgpio, if (!vqs[0]) { dev_err(&vdev->dev, "failed to find requestq vq\n"); - goto out; + return -ENODEV; } vgpio->request_vq = vqs[0]; - if (vgpio->irq_lines && !vqs[1]) { - dev_err(&vdev->dev, "failed to find eventq vq\n"); - goto out; - } - vgpio->event_vq = vqs[1]; - return 0; - -out: - if (vqs[0] || vqs[1]) - virtio_gpio_free_vqs(vdev); - - return -ENODEV; } static const char **virtio_gpio_get_names(struct virtio_gpio *vgpio, @@ -585,30 +321,6 @@ static int virtio_gpio_probe(struct virtio_device *vdev) vgpio->gc.owner = THIS_MODULE; vgpio->gc.can_sleep = true; - /* Interrupt support */ - if (virtio_has_feature(vdev, VIRTIO_GPIO_F_IRQ)) { - vgpio->irq_lines = devm_kcalloc(dev, ngpio, sizeof(*vgpio->irq_lines), GFP_KERNEL); - if (!vgpio->irq_lines) - return -ENOMEM; - - /* The event comes from the outside so no parent handler */ - vgpio->gc.irq.parent_handler = NULL; - vgpio->gc.irq.num_parents = 0; - vgpio->gc.irq.parents = NULL; - vgpio->gc.irq.default_type = IRQ_TYPE_NONE; - vgpio->gc.irq.handler = handle_level_irq; - vgpio->gc.irq.chip = &vgpio_irq_chip; - - for (i = 0; i < ngpio; i++) { - vgpio->irq_lines[i].type = VIRTIO_GPIO_IRQ_TYPE_NONE; - vgpio->irq_lines[i].disabled = true; - vgpio->irq_lines[i].masked = true; - } - - mutex_init(&vgpio->irq_lock); - raw_spin_lock_init(&vgpio->eventq_lock); - } - ret = virtio_gpio_alloc_vqs(vgpio, vdev); if (ret) return ret; @@ -641,13 +353,7 @@ static const struct virtio_device_id id_table[] = { }; MODULE_DEVICE_TABLE(virtio, id_table); -static const unsigned int features[] = { - VIRTIO_GPIO_F_IRQ, -}; - static struct virtio_driver virtio_gpio_driver = { - .feature_table = features, - .feature_table_size = ARRAY_SIZE(features), .id_table = id_table, .probe = virtio_gpio_probe, .remove = virtio_gpio_remove, diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index 7eaf8a2863..9cf1e5ebb3 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c @@ -262,8 +262,6 @@ static int wm831x_gpio_probe(struct platform_device *pdev) struct wm831x_pdata *pdata = &wm831x->pdata; struct wm831x_gpio *wm831x_gpio; - device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent)); - wm831x_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm831x_gpio), GFP_KERNEL); if (wm831x_gpio == NULL) @@ -277,6 +275,9 @@ static int wm831x_gpio_probe(struct platform_device *pdev) wm831x_gpio->gpio_chip.base = pdata->gpio_base; else wm831x_gpio->gpio_chip.base = -1; +#ifdef CONFIG_OF_GPIO + wm831x_gpio->gpio_chip.of_node = wm831x->dev->of_node; +#endif return devm_gpiochip_add_data(&pdev->dev, &wm831x_gpio->gpio_chip, wm831x_gpio); } diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index b6d3a57e27..a1b66338d0 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -371,7 +371,8 @@ static int __maybe_unused xgpio_resume(struct device *dev) static int __maybe_unused xgpio_runtime_suspend(struct device *dev) { - struct xgpio_instance *gpio = dev_get_drvdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct xgpio_instance *gpio = platform_get_drvdata(pdev); clk_disable(gpio->clk); @@ -380,7 +381,8 @@ static int __maybe_unused xgpio_runtime_suspend(struct device *dev) static int __maybe_unused xgpio_runtime_resume(struct device *dev) { - struct xgpio_instance *gpio = dev_get_drvdata(dev); + struct platform_device *pdev = to_platform_device(dev); + struct xgpio_instance *gpio = platform_get_drvdata(pdev); return clk_enable(gpio->clk); } diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c index 0199f54533..0d94d3aef7 100644 --- a/drivers/gpio/gpio-xlp.c +++ b/drivers/gpio/gpio-xlp.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,16 @@ * * where addr is base address of the that feature register and gpio is the pin. */ +#define GPIO_OUTPUT_EN 0x00 +#define GPIO_PADDRV 0x08 +#define GPIO_INT_EN00 0x18 +#define GPIO_INT_EN10 0x20 +#define GPIO_INT_EN20 0x28 +#define GPIO_INT_EN30 0x30 +#define GPIO_INT_POL 0x38 +#define GPIO_INT_TYPE 0x40 +#define GPIO_INT_STAT 0x48 + #define GPIO_9XX_BYTESWAP 0X00 #define GPIO_9XX_CTRL 0X04 #define GPIO_9XX_OUTPUT_EN 0x14 @@ -41,6 +52,14 @@ #define GPIO_9XX_INT_TYPE 0x114 #define GPIO_9XX_INT_STAT 0x124 +#define GPIO_3XX_INT_EN00 0x18 +#define GPIO_3XX_INT_EN10 0x20 +#define GPIO_3XX_INT_EN20 0x28 +#define GPIO_3XX_INT_EN30 0x30 +#define GPIO_3XX_INT_POL 0x78 +#define GPIO_3XX_INT_TYPE 0x80 +#define GPIO_3XX_INT_STAT 0x88 + /* Interrupt type register mask */ #define XLP_GPIO_IRQ_TYPE_LVL 0x0 #define XLP_GPIO_IRQ_TYPE_EDGE 0x1 @@ -53,6 +72,16 @@ #define XLP_GPIO_IRQ_BASE 768 #define XLP_MAX_NR_GPIO 96 +/* XLP variants supported by this driver */ +enum { + XLP_GPIO_VARIANT_XLP832 = 1, + XLP_GPIO_VARIANT_XLP316, + XLP_GPIO_VARIANT_XLP208, + XLP_GPIO_VARIANT_XLP980, + XLP_GPIO_VARIANT_XLP532, + GPIO_VARIANT_VULCAN +}; + struct xlp_gpio_priv { struct gpio_chip chip; DECLARE_BITMAP(gpio_enabled_mask, XLP_MAX_NR_GPIO); @@ -228,13 +257,44 @@ static void xlp_gpio_set(struct gpio_chip *gc, unsigned gpio, int state) xlp_gpio_set_reg(priv->gpio_paddrv, gpio, state); } +static const struct of_device_id xlp_gpio_of_ids[] = { + { + .compatible = "netlogic,xlp832-gpio", + .data = (void *)XLP_GPIO_VARIANT_XLP832, + }, + { + .compatible = "netlogic,xlp316-gpio", + .data = (void *)XLP_GPIO_VARIANT_XLP316, + }, + { + .compatible = "netlogic,xlp208-gpio", + .data = (void *)XLP_GPIO_VARIANT_XLP208, + }, + { + .compatible = "netlogic,xlp980-gpio", + .data = (void *)XLP_GPIO_VARIANT_XLP980, + }, + { + .compatible = "netlogic,xlp532-gpio", + .data = (void *)XLP_GPIO_VARIANT_XLP532, + }, + { + .compatible = "brcm,vulcan-gpio", + .data = (void *)GPIO_VARIANT_VULCAN, + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, xlp_gpio_of_ids); + static int xlp_gpio_probe(struct platform_device *pdev) { struct gpio_chip *gc; struct gpio_irq_chip *girq; struct xlp_gpio_priv *priv; void __iomem *gpio_base; - int irq, err; + int irq_base, irq, err; + int ngpio; + u32 soc_type; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -248,12 +308,62 @@ static int xlp_gpio_probe(struct platform_device *pdev) if (irq < 0) return irq; - priv->gpio_out_en = gpio_base + GPIO_9XX_OUTPUT_EN; - priv->gpio_paddrv = gpio_base + GPIO_9XX_PADDRV; - priv->gpio_intr_stat = gpio_base + GPIO_9XX_INT_STAT; - priv->gpio_intr_type = gpio_base + GPIO_9XX_INT_TYPE; - priv->gpio_intr_pol = gpio_base + GPIO_9XX_INT_POL; - priv->gpio_intr_en = gpio_base + GPIO_9XX_INT_EN00; + if (pdev->dev.of_node) { + soc_type = (uintptr_t)of_device_get_match_data(&pdev->dev); + } else { + const struct acpi_device_id *acpi_id; + + acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table, + &pdev->dev); + if (!acpi_id || !acpi_id->driver_data) { + dev_err(&pdev->dev, "Unable to match ACPI ID\n"); + return -ENODEV; + } + soc_type = (uintptr_t) acpi_id->driver_data; + } + + switch (soc_type) { + case XLP_GPIO_VARIANT_XLP832: + priv->gpio_out_en = gpio_base + GPIO_OUTPUT_EN; + priv->gpio_paddrv = gpio_base + GPIO_PADDRV; + priv->gpio_intr_stat = gpio_base + GPIO_INT_STAT; + priv->gpio_intr_type = gpio_base + GPIO_INT_TYPE; + priv->gpio_intr_pol = gpio_base + GPIO_INT_POL; + priv->gpio_intr_en = gpio_base + GPIO_INT_EN00; + ngpio = 41; + break; + case XLP_GPIO_VARIANT_XLP208: + case XLP_GPIO_VARIANT_XLP316: + priv->gpio_out_en = gpio_base + GPIO_OUTPUT_EN; + priv->gpio_paddrv = gpio_base + GPIO_PADDRV; + priv->gpio_intr_stat = gpio_base + GPIO_3XX_INT_STAT; + priv->gpio_intr_type = gpio_base + GPIO_3XX_INT_TYPE; + priv->gpio_intr_pol = gpio_base + GPIO_3XX_INT_POL; + priv->gpio_intr_en = gpio_base + GPIO_3XX_INT_EN00; + + ngpio = (soc_type == XLP_GPIO_VARIANT_XLP208) ? 42 : 57; + break; + case XLP_GPIO_VARIANT_XLP980: + case XLP_GPIO_VARIANT_XLP532: + case GPIO_VARIANT_VULCAN: + priv->gpio_out_en = gpio_base + GPIO_9XX_OUTPUT_EN; + priv->gpio_paddrv = gpio_base + GPIO_9XX_PADDRV; + priv->gpio_intr_stat = gpio_base + GPIO_9XX_INT_STAT; + priv->gpio_intr_type = gpio_base + GPIO_9XX_INT_TYPE; + priv->gpio_intr_pol = gpio_base + GPIO_9XX_INT_POL; + priv->gpio_intr_en = gpio_base + GPIO_9XX_INT_EN00; + + if (soc_type == XLP_GPIO_VARIANT_XLP980) + ngpio = 66; + else if (soc_type == XLP_GPIO_VARIANT_XLP532) + ngpio = 67; + else + ngpio = 70; + break; + default: + dev_err(&pdev->dev, "Unknown Processor type!\n"); + return -ENODEV; + } bitmap_zero(priv->gpio_enabled_mask, XLP_MAX_NR_GPIO); @@ -263,7 +373,8 @@ static int xlp_gpio_probe(struct platform_device *pdev) gc->label = dev_name(&pdev->dev); gc->base = 0; gc->parent = &pdev->dev; - gc->ngpio = 70; + gc->ngpio = ngpio; + gc->of_node = pdev->dev.of_node; gc->direction_output = xlp_gpio_dir_output; gc->direction_input = xlp_gpio_dir_input; gc->set = xlp_gpio_set; @@ -271,6 +382,19 @@ static int xlp_gpio_probe(struct platform_device *pdev) spin_lock_init(&priv->lock); + /* XLP(MIPS) has fixed range for GPIO IRQs, Vulcan(ARM64) does not */ + if (soc_type != GPIO_VARIANT_VULCAN) { + irq_base = devm_irq_alloc_descs(&pdev->dev, -1, + XLP_GPIO_IRQ_BASE, + gc->ngpio, 0); + if (irq_base < 0) { + dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); + return irq_base; + } + } else { + irq_base = 0; + } + girq = &gc->irq; girq->chip = &xlp_gpio_irq_chip; girq->parent_handler = xlp_gpio_generic_handler; @@ -281,7 +405,7 @@ static int xlp_gpio_probe(struct platform_device *pdev) if (!girq->parents) return -ENOMEM; girq->parents[0] = irq; - girq->first = 0; + girq->first = irq_base; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; @@ -296,8 +420,8 @@ static int xlp_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_ACPI static const struct acpi_device_id xlp_gpio_acpi_match[] = { - { "BRCM9006" }, - { "CAV9006" }, + { "BRCM9006", GPIO_VARIANT_VULCAN }, + { "CAV9006", GPIO_VARIANT_VULCAN }, {}, }; MODULE_DEVICE_TABLE(acpi, xlp_gpio_acpi_match); @@ -306,6 +430,7 @@ MODULE_DEVICE_TABLE(acpi, xlp_gpio_acpi_match); static struct platform_driver xlp_gpio_driver = { .driver = { .name = "xlp-gpio", + .of_match_table = xlp_gpio_of_ids, .acpi_match_table = ACPI_PTR(xlp_gpio_acpi_match), }, .probe = xlp_gpio_probe, diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index c0f6a25c32..d040c72fea 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -95,7 +95,10 @@ static bool acpi_gpio_deferred_req_irqs_done; static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) { - return gc->parent && device_match_acpi_handle(gc->parent, data); + if (!gc->parent) + return false; + + return ACPI_HANDLE(gc->parent) == data; } /** @@ -219,13 +222,14 @@ EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource); static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, struct acpi_gpio_event *event) { - struct device *parent = acpi_gpio->chip->parent; int ret, value; ret = request_threaded_irq(event->irq, NULL, event->handler, event->irqflags | IRQF_ONESHOT, "ACPI:Event", event); if (ret) { - dev_err(parent, "Failed to setup interrupt handler for %d\n", event->irq); + dev_err(acpi_gpio->chip->parent, + "Failed to setup interrupt handler for %d\n", + event->irq); return; } @@ -346,7 +350,8 @@ static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) return false; err: - pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_wake: %s\n", ignore_wake); + pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n", + ignore_wake); return false; } @@ -577,25 +582,37 @@ void acpi_dev_remove_driver_gpios(struct acpi_device *adev) } EXPORT_SYMBOL_GPL(acpi_dev_remove_driver_gpios); -static void acpi_dev_release_driver_gpios(void *adev) +static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res) { - acpi_dev_remove_driver_gpios(adev); + acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev)); } int devm_acpi_dev_add_driver_gpios(struct device *dev, const struct acpi_gpio_mapping *gpios) { - struct acpi_device *adev = ACPI_COMPANION(dev); + void *res; int ret; - ret = acpi_dev_add_driver_gpios(adev, gpios); - if (ret) - return ret; + res = devres_alloc(devm_acpi_dev_release_driver_gpios, 0, GFP_KERNEL); + if (!res) + return -ENOMEM; - return devm_add_action_or_reset(dev, acpi_dev_release_driver_gpios, adev); + ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), gpios); + if (ret) { + devres_free(res); + return ret; + } + devres_add(dev, res); + return 0; } EXPORT_SYMBOL_GPL(devm_acpi_dev_add_driver_gpios); +void devm_acpi_dev_remove_driver_gpios(struct device *dev) +{ + WARN_ON(devres_release(dev, devm_acpi_dev_release_driver_gpios, NULL, NULL)); +} +EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); + static bool acpi_get_driver_gpio_data(struct acpi_device *adev, const char *name, int index, struct fwnode_reference_args *args, @@ -927,7 +944,7 @@ struct gpio_desc *acpi_find_gpio(struct device *dev, if (info.gpioint && (*dflags == GPIOD_OUT_LOW || *dflags == GPIOD_OUT_HIGH)) { - dev_dbg(&adev->dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n"); + dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n"); return ERR_PTR(-ENOENT); } @@ -1339,9 +1356,6 @@ void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) /* Set default fwnode to parent's one if present */ if (gc->parent) ACPI_COMPANION_SET(&gdev->dev, ACPI_COMPANION(gc->parent)); - - if (gc->fwnode) - device_set_node(&gdev->dev, gc->fwnode); } static int acpi_gpio_package_count(const union acpi_object *obj) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 91dcf2c6cd..0ad288ab62 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -1046,9 +1046,6 @@ void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) if (gc->parent) gdev->dev.of_node = gc->parent->of_node; - if (gc->fwnode) - gc->of_node = to_of_node(gc->fwnode); - /* If the gpiochip has an assigned OF node this takes precedence */ if (gc->of_node) gdev->dev.of_node = gc->of_node; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1fa6016543..34bac9a763 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -424,16 +424,8 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip) if (count > chip->ngpio) count = chip->ngpio; - for (i = 0; i < count; i++) { - /* - * Allow overriding "fixed" names provided by the GPIO - * provider. The "fixed" names are more often than not - * generic and less informative than the names given in - * device properties. - */ - if (names[chip->offset + i] && names[chip->offset + i][0]) - gdev->descs[i].name = names[chip->offset + i]; - } + for (i = 0; i < count; i++) + gdev->descs[i].name = names[chip->offset + i]; kfree(names); @@ -603,18 +595,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, struct lock_class_key *lock_key, struct lock_class_key *request_key) { - struct fwnode_handle *fwnode = NULL; + struct fwnode_handle *fwnode = gc->parent ? dev_fwnode(gc->parent) : NULL; + unsigned long flags; + int ret = 0; + unsigned i; + int base = gc->base; struct gpio_device *gdev; - unsigned long flags; - int base = gc->base; - unsigned int i; - int ret = 0; - u32 ngpios; - - if (gc->fwnode) - fwnode = gc->fwnode; - else if (gc->parent) - fwnode = dev_fwnode(gc->parent); /* * First: allocate and populate the internal stat container, and @@ -662,26 +648,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, goto err_free_dev_name; } - /* - * Try the device properties if the driver didn't supply the number - * of GPIO lines. - */ - if (gc->ngpio == 0) { - ret = device_property_read_u32(&gdev->dev, "ngpios", &ngpios); - if (ret == -ENODATA) - /* - * -ENODATA means that there is no property found and - * we want to issue the error message to the user. - * Besides that, we want to return different error code - * to state that supplied value is not valid. - */ - ngpios = 0; - else if (ret) - goto err_free_descs; - - gc->ngpio = ngpios; - } - if (gc->ngpio == 0) { chip_err(gc, "tried to insert a GPIO chip with zero lines\n"); ret = -EINVAL; @@ -744,12 +710,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, INIT_LIST_HEAD(&gdev->pin_ranges); #endif - if (gc->names) { + if (gc->names) ret = gpiochip_set_desc_names(gc); - if (ret) - goto err_remove_from_list; - } - ret = devprop_gpiochip_set_names(gc); + else + ret = devprop_gpiochip_set_names(gc); if (ret) goto err_remove_from_list; @@ -1572,14 +1536,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc, } if (gc->irq.parent_handler) { + void *data = gc->irq.parent_handler_data ?: gc; + for (i = 0; i < gc->irq.num_parents; i++) { - void *data; - - if (gc->irq.per_parent_data) - data = gc->irq.parent_handler_data_array[i]; - else - data = gc->irq.parent_handler_data ?: gc; - /* * The parent IRQ chip is already using the chip_data * for this IRQ chip, so our callbacks simply use the @@ -3149,16 +3108,6 @@ int gpiod_to_irq(const struct gpio_desc *desc) return retirq; } -#ifdef CONFIG_GPIOLIB_IRQCHIP - if (gc->irq.chip) { - /* - * Avoid race condition with other code, which tries to lookup - * an IRQ before the irqchip has been properly registered, - * i.e. while gpiochip is still being brought up. - */ - return -EPROBE_DEFER; - } -#endif return -ENXIO; } EXPORT_SYMBOL_GPL(gpiod_to_irq); @@ -3535,7 +3484,11 @@ EXPORT_SYMBOL_GPL(gpiod_set_array_value_cansleep); */ void gpiod_add_lookup_table(struct gpiod_lookup_table *table) { - gpiod_add_lookup_tables(&table, 1); + mutex_lock(&gpio_lookup_lock); + + list_add_tail(&table->list, &gpio_lookup_list); + + mutex_unlock(&gpio_lookup_lock); } EXPORT_SYMBOL_GPL(gpiod_add_lookup_table); @@ -3584,17 +3537,6 @@ void gpiod_add_hogs(struct gpiod_hog *hogs) } EXPORT_SYMBOL_GPL(gpiod_add_hogs); -void gpiod_remove_hogs(struct gpiod_hog *hogs) -{ - struct gpiod_hog *hog; - - mutex_lock(&gpio_machine_hogs_mutex); - for (hog = &hogs[0]; hog->chip_label; hog++) - list_del(&hog->list); - mutex_unlock(&gpio_machine_hogs_mutex); -} -EXPORT_SYMBOL_GPL(gpiod_remove_hogs); - static struct gpiod_lookup_table *gpiod_find_lookup_table(struct device *dev) { const char *dev_id = dev ? dev_name(dev) : NULL; diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b1f22e457f..cea777ae7f 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -8,7 +8,6 @@ menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA - select DRM_NOMODESET select DRM_PANEL_ORIENTATION_QUIRKS select HDMI select FB_CMDLINE @@ -101,25 +100,11 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS This has the potential to use a lot of memory and print some very large kernel messages. If in doubt, say "N". -config DRM_DEBUG_MODESET_LOCK - bool "Enable backtrace history for lock contention" - depends on STACKTRACE_SUPPORT - depends on DEBUG_KERNEL - depends on EXPERT - select STACKDEPOT - default y if DEBUG_WW_MUTEX_SLOWPATH - help - Enable debug tracing of failures to gracefully handle drm modeset lock - contention. A history of each drm modeset lock path hitting -EDEADLK - will be saved until gracefully handled, and the backtrace will be - printed when attempting to lock a contended lock. - - If in doubt, say "N". - config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" - depends on DRM_KMS_HELPER - depends on FB=y || FB=DRM_KMS_HELPER + depends on DRM + depends on FB + select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -212,14 +197,21 @@ config DRM_TTM_HELPER Helpers for ttm-based gem objects config DRM_GEM_CMA_HELPER - tristate + bool depends on DRM help Choose this if you need the GEM CMA helper functions +config DRM_KMS_CMA_HELPER + bool + depends on DRM + select DRM_GEM_CMA_HELPER + help + Choose this if you need the KMS CMA helper functions + config DRM_GEM_SHMEM_HELPER - tristate - depends on DRM && MMU + bool + depends on DRM help Choose this if you need the GEM shmem helper functions @@ -279,8 +271,7 @@ source "drivers/gpu/drm/kmb/Kconfig" config DRM_VGEM tristate "Virtual GEM provider" - depends on DRM && MMU - select DRM_GEM_SHMEM_HELPER + depends on DRM help Choose this option to get a virtual graphics memory manager, as used by Mesa's software renderer for enhanced performance. @@ -288,7 +279,7 @@ config DRM_VGEM config DRM_VKMS tristate "Virtual KMS (EXPERIMENTAL)" - depends on DRM && MMU + depends on DRM select DRM_KMS_HELPER select DRM_GEM_SHMEM_HELPER select CRC32 @@ -360,6 +351,8 @@ source "drivers/gpu/drm/hisilicon/Kconfig" source "drivers/gpu/drm/mediatek/Kconfig" +source "drivers/gpu/drm/zte/Kconfig" + source "drivers/gpu/drm/mxsfb/Kconfig" source "drivers/gpu/drm/meson/Kconfig" @@ -388,8 +381,6 @@ source "drivers/gpu/drm/xlnx/Kconfig" source "drivers/gpu/drm/gud/Kconfig" -source "drivers/gpu/drm/sprd/Kconfig" - config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV @@ -488,15 +479,6 @@ config DRM_EXPORT_FOR_TESTS config DRM_PANEL_ORIENTATION_QUIRKS tristate -# Separate option because nomodeset parameter is global and expected built-in -config DRM_NOMODESET - bool - default n - config DRM_LIB_RANDOM bool default n - -config DRM_PRIVACY_SCREEN - bool - default n diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 301a44dc18..ad11121548 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -4,44 +4,37 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. drm-y := drm_aperture.o drm_auth.o drm_cache.o \ - drm_file.o drm_gem.o drm_ioctl.o \ + drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_drv.o \ - drm_sysfs.o drm_mm.o \ + drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o drm_displayid.o \ + drm_encoder_slave.o \ drm_trace_points.o drm_prime.o \ - drm_vma_manager.o \ + drm_rect.o drm_vma_manager.o drm_flip_work.o \ drm_modeset_lock.o drm_atomic.o drm_bridge.o \ drm_framebuffer.o drm_connector.o drm_blend.o \ drm_encoder.o drm_mode_object.o drm_property.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ - drm_client_modeset.o drm_atomic_uapi.o \ + drm_client_modeset.o drm_atomic_uapi.o drm_hdcp.o \ drm_managed.o drm_vblank_work.o drm-$(CONFIG_DRM_LEGACY) += drm_agpsupport.o drm_bufs.o drm_context.o drm_dma.o \ - drm_hashtab.o drm_irq.o drm_legacy_misc.o drm_lock.o \ - drm_memory.o drm_scatter.o drm_vm.o + drm_legacy_misc.o drm_lock.o drm_memory.o drm_scatter.o \ + drm_vm.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_COMPAT) += drm_ioc32.o +drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o +drm-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_gem_shmem_helper.o drm-$(CONFIG_DRM_PANEL) += drm_panel.o drm-$(CONFIG_OF) += drm_of.o drm-$(CONFIG_PCI) += drm_pci.o drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o -drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o drm_privacy_screen_x86.o obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o -obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o - -drm_cma_helper-y := drm_gem_cma_helper.o -drm_cma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_cma_helper.o -obj-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_cma_helper.o - -drm_shmem_helper-y := drm_gem_shmem_helper.o -obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o - drm_vram_helper-y := drm_gem_vram_helper.o obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o @@ -49,18 +42,18 @@ drm_ttm_helper-y := drm_gem_ttm_helper.o obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \ - drm_dsc.o drm_encoder_slave.o drm_flip_work.o drm_hdcp.o \ - drm_probe_helper.o \ + drm_dsc.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ drm_simple_kms_helper.o drm_modeset_helper.o \ drm_scdc_helper.o drm_gem_atomic_helper.o \ drm_gem_framebuffer_helper.o \ drm_atomic_state_helper.o drm_damage_helper.o \ - drm_format_helper.o drm_self_refresh_helper.o drm_rect.o + drm_format_helper.o drm_self_refresh_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o @@ -120,6 +113,7 @@ obj-y += bridge/ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ obj-y += hisilicon/ +obj-$(CONFIG_DRM_ZTE) += zte/ obj-$(CONFIG_DRM_MXSFB) += mxsfb/ obj-y += tiny/ obj-$(CONFIG_DRM_PL111) += pl111/ @@ -134,4 +128,3 @@ obj-$(CONFIG_DRM_TIDSS) += tidss/ obj-y += xlnx/ obj-y += gud/ obj-$(CONFIG_DRM_HYPERV) += hyperv/ -obj-$(CONFIG_DRM_SPRD) += sprd/ diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 7fedbb725e..8d0748184a 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -45,7 +45,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ amdgpu_atombios.o atombios_crtc.o amdgpu_connectors.o \ atom.o amdgpu_fence.o amdgpu_ttm.o amdgpu_object.o amdgpu_gart.o \ amdgpu_encoders.o amdgpu_display.o amdgpu_i2c.o \ - amdgpu_gem.o amdgpu_ring.o \ + amdgpu_fb.o amdgpu_gem.o amdgpu_ring.o \ amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o amdgpu_test.o \ atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \ atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ @@ -73,8 +73,10 @@ amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce amdgpu-y += \ vi.o mxgpu_vi.o nbio_v6_1.o soc15.o emu_soc.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o \ - vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o arct_reg_init.o mxgpu_nv.o \ - nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o + vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \ + arct_reg_init.o navi12_reg_init.o mxgpu_nv.o sienna_cichlid_reg_init.o vangogh_reg_init.o \ + nbio_v7_2.o dimgrey_cavefish_reg_init.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o \ + beige_goby_reg_init.o yellow_carp_reg_init.o cyan_skillfish_reg_init.o # add DF block amdgpu-y += \ diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c index bcfdb63b1d..148f6c3343 100644 --- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -307,8 +307,6 @@ static int aldebaran_mode2_restore_ip(struct amdgpu_device *adev) adev->ip_blocks[i].status.late_initialized = true; } - amdgpu_ras_set_error_query_ready(adev, true); - amdgpu_device_set_cg_state(adev, AMD_CG_STATE_GATE); amdgpu_device_set_pg_state(adev, AMD_PG_STATE_GATE); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9a53a4de2b..7e73ac6fb2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -205,7 +205,6 @@ extern struct amdgpu_mgpu_info mgpu_info; extern int amdgpu_ras_enable; extern uint amdgpu_ras_mask; extern int amdgpu_bad_page_threshold; -extern bool amdgpu_ignore_bad_page_threshold; extern struct amdgpu_watchdog_timer amdgpu_watchdog_timer; extern int amdgpu_async_gfx_ring; extern int amdgpu_mcbp; @@ -458,6 +457,7 @@ struct amdgpu_flip_work { uint64_t base; struct drm_pending_vblank_event *event; struct amdgpu_bo *old_abo; + struct dma_fence *excl; unsigned shared_count; struct dma_fence **shared; struct dma_fence_cb cb; @@ -744,7 +744,6 @@ enum amd_hw_ip_block_type { UVD_HWIP, VCN_HWIP = UVD_HWIP, JPEG_HWIP = VCN_HWIP, - VCN1_HWIP, VCE_HWIP, DF_HWIP, DCE_HWIP, @@ -756,16 +755,11 @@ enum amd_hw_ip_block_type { CLK_HWIP, UMC_HWIP, RSMU_HWIP, - XGMI_HWIP, - DCI_HWIP, MAX_HWIP }; #define HWIP_MAX_INSTANCE 10 -#define HW_ID_MAX 300 -#define IP_VERSION(mj, mn, rv) (((mj) << 16) | ((mn) << 8) | (rv)) - struct amd_powerplay { void *pp_handle; const struct amd_pm_funcs *pp_funcs; @@ -812,7 +806,6 @@ struct amd_powerplay { #define AMDGPU_RESET_MAGIC_NUM 64 #define AMDGPU_MAX_DF_PERFMONS 4 -#define AMDGPU_PRODUCT_NAME_LEN 64 struct amdgpu_device { struct device *dev; struct pci_dev *pdev; @@ -837,7 +830,6 @@ struct amdgpu_device { struct notifier_block acpi_nb; struct amdgpu_i2c_chan *i2c_bus[AMDGPU_MAX_I2C_BUS]; struct debugfs_blob_wrapper debugfs_vbios_blob; - struct debugfs_blob_wrapper debugfs_discovery_blob; struct mutex srbm_mutex; /* GRBM index mutex. Protects concurrent access to GRBM index */ struct mutex grbm_idx_mutex; @@ -1084,7 +1076,7 @@ struct amdgpu_device { /* Chip product information */ char product_number[16]; - char product_name[AMDGPU_PRODUCT_NAME_LEN]; + char product_name[32]; char serial[20]; atomic_t throttling_logging_enabled; @@ -1097,9 +1089,6 @@ struct amdgpu_device { pci_channel_state_t pci_channel_state; struct amdgpu_reset_control *reset_cntl; - uint32_t ip_versions[MAX_HWIP][HWIP_MAX_INSTANCE]; - - bool ram_is_direct_mapped; }; static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) @@ -1320,8 +1309,6 @@ void amdgpu_device_flush_hdp(struct amdgpu_device *adev, void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring); -void amdgpu_device_halt(struct amdgpu_device *adev); - /* atpx handler */ #if defined(CONFIG_VGA_SWITCHEROO) void amdgpu_register_atpx_handler(void); @@ -1365,6 +1352,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon); u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc); int amdgpu_enable_vblank_kms(struct drm_crtc *crtc); void amdgpu_disable_vblank_kms(struct drm_crtc *crtc); +long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 6ca1db3c24..1d41c2c006 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -31,8 +31,6 @@ #include #include "amdgpu_xgmi.h" #include -#include "amdgpu_ras.h" -#include "amdgpu_umc.h" /* Total memory size in system memory and all GPU VRAM. Used to * estimate worst case amount of memory to reserve for page tables @@ -72,7 +70,8 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev) if (!kfd_initialized) return; - adev->kfd.dev = kgd2kfd_probe(adev, vf); + adev->kfd.dev = kgd2kfd_probe((struct kgd_dev *)adev, + adev->pdev, adev->asic_type, vf); if (adev->kfd.dev) amdgpu_amdkfd_total_mem_size += adev->gmc.real_vram_size; @@ -233,16 +232,19 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev) return r; } -void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev) +void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + if (amdgpu_device_should_recover_gpu(adev)) amdgpu_device_gpu_recover(adev, NULL); } -int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size, +int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, void **mem_obj, uint64_t *gpu_addr, void **cpu_ptr, bool cp_mqd_gfx9) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_bo *bo = NULL; struct amdgpu_bo_param bp; int r; @@ -311,7 +313,7 @@ int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size, return r; } -void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj) +void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) { struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj; @@ -322,9 +324,10 @@ void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj) amdgpu_bo_unref(&(bo)); } -int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size, +int amdgpu_amdkfd_alloc_gws(struct kgd_dev *kgd, size_t size, void **mem_obj) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_bo *bo = NULL; struct amdgpu_bo_user *ubo; struct amdgpu_bo_param bp; @@ -351,16 +354,18 @@ int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size, return 0; } -void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj) +void amdgpu_amdkfd_free_gws(struct kgd_dev *kgd, void *mem_obj) { struct amdgpu_bo *bo = (struct amdgpu_bo *)mem_obj; amdgpu_bo_unref(&bo); } -uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev, +uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + switch (type) { case KGD_ENGINE_PFP: return adev->gfx.pfp_fw_version; @@ -393,9 +398,11 @@ uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev, return 0; } -void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev, +void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, struct kfd_local_mem_info *mem_info) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + memset(mem_info, 0, sizeof(*mem_info)); mem_info->local_mem_size_public = adev->gmc.visible_vram_size; @@ -420,15 +427,19 @@ void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev, mem_info->mem_clk_max = 100; } -uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev) +uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + if (adev->gfx.funcs->get_gpu_clock_counter) return adev->gfx.funcs->get_gpu_clock_counter(adev); return 0; } -uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev) +uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + /* the sclk is in quantas of 10kHz */ if (amdgpu_sriov_vf(adev)) return adev->clock.default_sclk / 100; @@ -438,8 +449,9 @@ uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev) return 100; } -void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, struct kfd_cu_info *cu_info) +void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_cu_info acu_info = adev->gfx.cu_info; memset(cu_info, 0, sizeof(*cu_info)); @@ -460,12 +472,13 @@ void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, struct kfd_cu_info *c cu_info->lds_size = acu_info.lds_size; } -int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, - struct amdgpu_device **dmabuf_adev, +int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd, + struct kgd_dev **dma_buf_kgd, uint64_t *bo_size, void *metadata_buffer, size_t buffer_size, uint32_t *metadata_size, uint32_t *flags) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct dma_buf *dma_buf; struct drm_gem_object *obj; struct amdgpu_bo *bo; @@ -493,8 +506,8 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, goto out_put; r = 0; - if (dmabuf_adev) - *dmabuf_adev = adev; + if (dma_buf_kgd) + *dma_buf_kgd = (struct kgd_dev *)adev; if (bo_size) *bo_size = amdgpu_bo_size(bo); if (metadata_buffer) @@ -514,11 +527,32 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, return r; } -uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst, - struct amdgpu_device *src) +uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd) { - struct amdgpu_device *peer_adev = src; - struct amdgpu_device *adev = dst; + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + + return amdgpu_vram_mgr_usage(vram_man); +} + +uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->gmc.xgmi.hive_id; +} + +uint64_t amdgpu_amdkfd_get_unique_id(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->unique_id; +} + +uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *src) +{ + struct amdgpu_device *peer_adev = (struct amdgpu_device *)src; + struct amdgpu_device *adev = (struct amdgpu_device *)dst; int ret = amdgpu_xgmi_get_hops_count(adev, peer_adev); if (ret < 0) { @@ -530,18 +564,16 @@ uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst, return (uint8_t)ret; } -int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst, - struct amdgpu_device *src, - bool is_min) +int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct kgd_dev *dst, struct kgd_dev *src, bool is_min) { - struct amdgpu_device *adev = dst, *peer_adev; + struct amdgpu_device *adev = (struct amdgpu_device *)dst, *peer_adev; int num_links; if (adev->asic_type != CHIP_ALDEBARAN) return 0; if (src) - peer_adev = src; + peer_adev = (struct amdgpu_device *)src; /* num links returns 0 for indirect peers since indirect route is unknown. */ num_links = is_min ? 1 : amdgpu_xgmi_get_num_links(adev, peer_adev); @@ -556,8 +588,9 @@ int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst, return (num_links * 16 * 25000)/BITS_PER_BYTE; } -int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min) +int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min) { + struct amdgpu_device *adev = (struct amdgpu_device *)dev; int num_lanes_shift = (is_min ? ffs(adev->pm.pcie_mlw_mask) : fls(adev->pm.pcie_mlw_mask)) - 1; int gen_speed_shift = (is_min ? ffs(adev->pm.pcie_gen_mask & @@ -613,11 +646,39 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_ return (num_lanes_factor * gen_speed_mbits_factor)/BITS_PER_BYTE; } -int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, - enum kgd_engine_type engine, +uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->rmmio_remap.bus_addr; +} + +uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->gds.gws_size; +} + +uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->rev_id; +} + +int amdgpu_amdkfd_get_noretry(struct kgd_dev *kgd) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + return adev->gmc.noretry; +} + +int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, uint32_t vmid, uint64_t gpu_addr, uint32_t *ib_cmd, uint32_t ib_len) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_job *job; struct amdgpu_ib *ib; struct amdgpu_ring *ring; @@ -668,8 +729,10 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, return ret; } -void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) +void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_COMPUTE, !idle); @@ -683,9 +746,10 @@ bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) return false; } -int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev, - uint16_t vmid) +int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + if (adev->family == AMDGPU_FAMILY_AI) { int i; @@ -698,9 +762,10 @@ int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev, return 0; } -int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, - uint16_t pasid, enum TLB_FLUSH_TYPE flush_type) +int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid, + enum TLB_FLUSH_TYPE flush_type) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; bool all_hub = false; if (adev->family == AMDGPU_FAMILY_AI) @@ -709,18 +774,9 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub); } -bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev) +bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + return adev->have_atomics_support; } - -void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, bool reset) -{ - struct ras_err_data err_data = {0, 0, 0, NULL}; - - /* CPU MCA will handle page retirement if connected_to_cpu is 1 */ - if (!adev->gmc.xgmi.connected_to_cpu) - amdgpu_umc_poison_handler(adev, &err_data, reset); - else if (reset) - amdgpu_amdkfd_gpu_reset(adev); -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index ac841ae8f5..3bc52b2c60 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -144,16 +144,14 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev, void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev); void amdgpu_amdkfd_device_init(struct amdgpu_device *adev); void amdgpu_amdkfd_device_fini_sw(struct amdgpu_device *adev); -int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, - enum kgd_engine_type engine, +int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine, uint32_t vmid, uint64_t gpu_addr, uint32_t *ib_cmd, uint32_t ib_len); -void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle); -bool amdgpu_amdkfd_have_atomics_support(struct amdgpu_device *adev); -int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct amdgpu_device *adev, - uint16_t vmid); -int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, - uint16_t pasid, enum TLB_FLUSH_TYPE flush_type); +void amdgpu_amdkfd_set_compute_idle(struct kgd_dev *kgd, bool idle); +bool amdgpu_amdkfd_have_atomics_support(struct kgd_dev *kgd); +int amdgpu_amdkfd_flush_gpu_tlb_vmid(struct kgd_dev *kgd, uint16_t vmid); +int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct kgd_dev *kgd, uint16_t pasid, + enum TLB_FLUSH_TYPE flush_type); bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid); @@ -161,7 +159,7 @@ int amdgpu_amdkfd_pre_reset(struct amdgpu_device *adev); int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev); -void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev); +void amdgpu_amdkfd_gpu_reset(struct kgd_dev *kgd); int amdgpu_queue_mask_bit_to_set_resource_bit(struct amdgpu_device *adev, int queue_bit); @@ -200,35 +198,37 @@ int amdgpu_amdkfd_evict_userptr(struct kgd_mem *mem, struct mm_struct *mm) } #endif /* Shared API */ -int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size, +int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, void **mem_obj, uint64_t *gpu_addr, void **cpu_ptr, bool mqd_gfx9); -void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj); -int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size, - void **mem_obj); -void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj); +void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj); +int amdgpu_amdkfd_alloc_gws(struct kgd_dev *kgd, size_t size, void **mem_obj); +void amdgpu_amdkfd_free_gws(struct kgd_dev *kgd, void *mem_obj); int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem); int amdgpu_amdkfd_remove_gws_from_process(void *info, void *mem); -uint32_t amdgpu_amdkfd_get_fw_version(struct amdgpu_device *adev, +uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); -void amdgpu_amdkfd_get_local_mem_info(struct amdgpu_device *adev, +void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, struct kfd_local_mem_info *mem_info); -uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev); +uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd); -uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev); -void amdgpu_amdkfd_get_cu_info(struct amdgpu_device *adev, - struct kfd_cu_info *cu_info); -int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd, - struct amdgpu_device **dmabuf_adev, +uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct kgd_dev *kgd); +void amdgpu_amdkfd_get_cu_info(struct kgd_dev *kgd, struct kfd_cu_info *cu_info); +int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd, + struct kgd_dev **dmabuf_kgd, uint64_t *bo_size, void *metadata_buffer, size_t buffer_size, uint32_t *metadata_size, uint32_t *flags); -uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct amdgpu_device *dst, - struct amdgpu_device *src); -int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst, - struct amdgpu_device *src, - bool is_min); -int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min); +uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); +uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd); +uint64_t amdgpu_amdkfd_get_unique_id(struct kgd_dev *kgd); +uint64_t amdgpu_amdkfd_get_mmio_remap_phys_addr(struct kgd_dev *kgd); +uint32_t amdgpu_amdkfd_get_num_gws(struct kgd_dev *kgd); +uint32_t amdgpu_amdkfd_get_asic_rev_id(struct kgd_dev *kgd); +int amdgpu_amdkfd_get_noretry(struct kgd_dev *kgd); +uint8_t amdgpu_amdkfd_get_xgmi_hops_count(struct kgd_dev *dst, struct kgd_dev *src); +int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct kgd_dev *dst, struct kgd_dev *src, bool is_min); +int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct kgd_dev *dev, bool is_min); /* Read user wptr from a specified user address space with page fault * disabled. The memory must be pinned and mapped to the hardware when @@ -258,56 +258,43 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_ (&((struct amdgpu_fpriv *) \ ((struct drm_file *)(drm_priv))->driver_priv)->vm) -int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd, struct file *filp, u32 pasid, void **process_info, struct dma_fence **ef); -void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev, - void *drm_priv); +void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *drm_priv); uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv); int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( - struct amdgpu_device *adev, uint64_t va, uint64_t size, + struct kgd_dev *kgd, uint64_t va, uint64_t size, void *drm_priv, struct kgd_mem **mem, uint64_t *offset, uint32_t flags); int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv, + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, uint64_t *size); int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv, - bool *table_freed); + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, bool *table_freed); int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv); int amdgpu_amdkfd_gpuvm_sync_memory( - struct amdgpu_device *adev, struct kgd_mem *mem, bool intr); -int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev, + struct kgd_dev *kgd, struct kgd_mem *mem, bool intr); +int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd, struct kgd_mem *mem, void **kptr, uint64_t *size); -void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev, - struct kgd_mem *mem); - int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info, struct dma_fence **ef); -int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd, struct kfd_vm_fault_info *info); -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd, struct dma_buf *dmabuf, uint64_t va, void *drm_priv, struct kgd_mem **mem, uint64_t *size, uint64_t *mmap_offset); -int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev, +int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd, struct tile_config *config); -void amdgpu_amdkfd_ras_poison_consumption_handler(struct amdgpu_device *adev, - bool reset); #if IS_ENABLED(CONFIG_HSA_AMD) void amdgpu_amdkfd_gpuvm_init_mem_limits(void); void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, struct amdgpu_vm *vm); - -/** - * @amdgpu_amdkfd_release_notify() - Notify KFD when GEM object is released - * - * Allows KFD to release its resources associated with the GEM object. - */ -void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo); +void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo); void amdgpu_amdkfd_reserve_system_mem(uint64_t size); #else static inline @@ -322,7 +309,7 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, } static inline -void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo) +void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) { } #endif @@ -334,7 +321,8 @@ int kgd2kfd_schedule_evict_and_restore_process(struct mm_struct *mm, #if IS_ENABLED(CONFIG_HSA_AMD) int kgd2kfd_init(void); void kgd2kfd_exit(void); -struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf); +struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev, + unsigned int asic_type, bool vf); bool kgd2kfd_device_init(struct kfd_dev *kfd, struct drm_device *ddev, const struct kgd2kfd_shared_resources *gpu_resources); @@ -358,7 +346,8 @@ static inline void kgd2kfd_exit(void) } static inline -struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) +struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev, + unsigned int asic_type, bool vf) { return NULL; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index abe93b3ff7..5a7f680bcb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -57,6 +57,11 @@ (*dump)[i++][1] = RREG32(addr); \ } while (0) +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd) { return (struct v9_sdma_mqd *)mqd; @@ -118,9 +123,10 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev, return sdma_rlc_reg_offset; } -int kgd_arcturus_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; unsigned long end_jiffies; @@ -187,10 +193,11 @@ int kgd_arcturus_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, return 0; } -int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev, +int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev, engine_id, queue_id); uint32_t i = 0, reg; @@ -218,9 +225,9 @@ int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev, return 0; } -bool kgd_arcturus_hqd_sdma_is_occupied(struct amdgpu_device *adev, - void *mqd) +bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -237,9 +244,10 @@ bool kgd_arcturus_hqd_sdma_is_occupied(struct amdgpu_device *adev, return false; } -int kgd_arcturus_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h index 756c1a5679..ce08131b7b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.h @@ -20,12 +20,11 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -int kgd_arcturus_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +int kgd_arcturus_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm); -int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev, +int kgd_arcturus_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs); -bool kgd_arcturus_hqd_sdma_is_occupied(struct amdgpu_device *adev, - void *mqd); -int kgd_arcturus_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +bool kgd_arcturus_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); +int kgd_arcturus_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c index 7b7f4b2764..960acf6815 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -39,26 +39,37 @@ enum hqd_dequeue_request_type { SAVE_WAVES }; -static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe, +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, uint32_t queue, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + mutex_lock(&adev->srbm_mutex); nv_grbm_select(adev, mec, pipe, queue, vmid); } -static void unlock_srbm(struct amdgpu_device *adev) +static void unlock_srbm(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + nv_grbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); } -static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id, +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, queue_id, 0); + lock_srbm(kgd, mec, pipe, queue_id, 0); } static uint64_t get_queue_mask(struct amdgpu_device *adev, @@ -70,29 +81,33 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev, return 1ull << bit; } -static void release_queue(struct amdgpu_device *adev) +static void release_queue(struct kgd_dev *kgd) { - unlock_srbm(adev); + unlock_srbm(kgd); } -static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid, +static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, sh_mem_config); WREG32_SOC15(GC, 0, mmSH_MEM_BASES, sh_mem_bases); /* APE1 no longer exists on GFX9 */ - unlock_srbm(adev); + unlock_srbm(kgd); } -static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, +static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid, unsigned int vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + /* * We have to assume that there is no outstanding mapping. * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because @@ -135,21 +150,22 @@ static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, * but still works */ -static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id) +static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t mec; uint32_t pipe; mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, 0, 0); + lock_srbm(kgd, mec, pipe, 0, 0); WREG32_SOC15(GC, 0, mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); - unlock_srbm(adev); + unlock_srbm(kgd); return 0; } @@ -202,11 +218,12 @@ static inline struct v10_sdma_mqd *get_sdma_mqd(void *mqd) return (struct v10_sdma_mqd *)mqd; } -static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t __user *wptr, uint32_t wptr_shift, - uint32_t wptr_mask, struct mm_struct *mm) +static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t wptr_shift, uint32_t wptr_mask, + struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_compute_mqd *m; uint32_t *mqd_hqd; uint32_t reg, hqd_base, data; @@ -214,7 +231,7 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */ mqd_hqd = &m->cp_mqd_base_addr_lo; @@ -279,15 +296,16 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, data); - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, +static int kgd_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t doorbell_off) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; struct v10_compute_mqd *m; uint32_t mec, pipe; @@ -295,7 +313,7 @@ static int kgd_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); @@ -331,15 +349,16 @@ static int kgd_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, out_unlock: spin_unlock(&adev->gfx.kiq.ring_lock); - release_queue(adev); + release_queue(kgd); return r; } -static int kgd_hqd_dump(struct amdgpu_device *adev, +static int kgd_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t i = 0, reg; #define HQD_N_REGS 56 #define DUMP_REG(addr) do { \ @@ -353,13 +372,13 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, if (*dump == NULL) return -ENOMEM; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR); reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++) DUMP_REG(reg); - release_queue(adev); + release_queue(kgd); WARN_ON_ONCE(i != HQD_N_REGS); *n_regs = i; @@ -367,9 +386,10 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, return 0; } -static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; unsigned long end_jiffies; @@ -436,10 +456,11 @@ static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, return 0; } -static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, +static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev, engine_id, queue_id); uint32_t i = 0, reg; @@ -467,15 +488,15 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, return 0; } -static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t act; bool retval = false; uint32_t low, high; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); act = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE); if (act) { low = lower_32_bits(queue_address >> 8); @@ -485,12 +506,13 @@ static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, high == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE_HI)) retval = true; } - release_queue(adev); + release_queue(kgd); return retval; } -static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) +static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -507,11 +529,12 @@ static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) return false; } -static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); enum hqd_dequeue_request_type type; unsigned long end_jiffies; uint32_t temp; @@ -525,7 +548,7 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, int retry; #endif - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (m->cp_hqd_vmid == 0) WREG32_FIELD15(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0); @@ -610,19 +633,20 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, break; if (time_after(jiffies, end_jiffies)) { pr_err("cp queue preemption time out.\n"); - release_queue(adev); + release_queue(kgd); return -ETIME; } usleep_range(500, 1000); } - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; @@ -659,10 +683,11 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, return 0; } -static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, +static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid) { uint32_t value; + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING) + vmid); @@ -671,12 +696,12 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -static int kgd_address_watch_disable(struct amdgpu_device *adev) +static int kgd_address_watch_disable(struct kgd_dev *kgd) { return 0; } -static int kgd_address_watch_execute(struct amdgpu_device *adev, +static int kgd_address_watch_execute(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, @@ -685,10 +710,11 @@ static int kgd_address_watch_execute(struct amdgpu_device *adev, return 0; } -static int kgd_wave_control_execute(struct amdgpu_device *adev, +static int kgd_wave_control_execute(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; mutex_lock(&adev->grbm_idx_mutex); @@ -709,16 +735,18 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev, return 0; } -static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev, +static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset) { return 0; } -static void set_vm_context_page_table_base(struct amdgpu_device *adev, - uint32_t vmid, uint64_t page_table_base) +static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, + uint64_t page_table_base) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { pr_err("trying to set page table base for wrong VMID %u\n", vmid); @@ -729,10 +757,12 @@ static void set_vm_context_page_table_base(struct amdgpu_device *adev, adev->gfxhub.funcs->setup_vm_pt_regs(adev, vmid, page_table_base); } -static void program_trap_handler_settings(struct amdgpu_device *adev, +static void program_trap_handler_settings(struct kgd_dev *kgd, uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); /* * Program TBA registers @@ -751,7 +781,7 @@ static void program_trap_handler_settings(struct amdgpu_device *adev, WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI), upper_32_bits(tma_addr >> 8)); - unlock_srbm(adev); + unlock_srbm(kgd); } const struct kfd2kgd_calls gfx_v10_kfd2kgd = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c index 1f37d35740..dac0d751d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c @@ -38,26 +38,37 @@ enum hqd_dequeue_request_type { SAVE_WAVES }; -static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe, +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, uint32_t queue, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + mutex_lock(&adev->srbm_mutex); nv_grbm_select(adev, mec, pipe, queue, vmid); } -static void unlock_srbm(struct amdgpu_device *adev) +static void unlock_srbm(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + nv_grbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); } -static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id, +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, queue_id, 0); + lock_srbm(kgd, mec, pipe, queue_id, 0); } static uint64_t get_queue_mask(struct amdgpu_device *adev, @@ -69,30 +80,34 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev, return 1ull << bit; } -static void release_queue(struct amdgpu_device *adev) +static void release_queue(struct kgd_dev *kgd) { - unlock_srbm(adev); + unlock_srbm(kgd); } -static void program_sh_mem_settings_v10_3(struct amdgpu_device *adev, uint32_t vmid, +static void program_sh_mem_settings_v10_3(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32_SOC15(GC, 0, mmSH_MEM_CONFIG, sh_mem_config); WREG32_SOC15(GC, 0, mmSH_MEM_BASES, sh_mem_bases); /* APE1 no longer exists on GFX9 */ - unlock_srbm(adev); + unlock_srbm(kgd); } /* ATC is defeatured on Sienna_Cichlid */ -static int set_pasid_vmid_mapping_v10_3(struct amdgpu_device *adev, unsigned int pasid, +static int set_pasid_vmid_mapping_v10_3(struct kgd_dev *kgd, unsigned int pasid, unsigned int vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t value = pasid << IH_VMID_0_LUT__PASID__SHIFT; /* Mapping vmid to pasid also for IH block */ @@ -103,21 +118,22 @@ static int set_pasid_vmid_mapping_v10_3(struct amdgpu_device *adev, unsigned int return 0; } -static int init_interrupts_v10_3(struct amdgpu_device *adev, uint32_t pipe_id) +static int init_interrupts_v10_3(struct kgd_dev *kgd, uint32_t pipe_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t mec; uint32_t pipe; mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, 0, 0); + lock_srbm(kgd, mec, pipe, 0, 0); WREG32_SOC15(GC, 0, mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); - unlock_srbm(adev); + unlock_srbm(kgd); return 0; } @@ -172,11 +188,12 @@ static inline struct v10_sdma_mqd *get_sdma_mqd(void *mqd) return (struct v10_sdma_mqd *)mqd; } -static int hqd_load_v10_3(struct amdgpu_device *adev, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t __user *wptr, uint32_t wptr_shift, - uint32_t wptr_mask, struct mm_struct *mm) +static int hqd_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t wptr_shift, uint32_t wptr_mask, + struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_compute_mqd *m; uint32_t *mqd_hqd; uint32_t reg, hqd_base, data; @@ -184,7 +201,7 @@ static int hqd_load_v10_3(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); pr_debug("Load hqd of pipe %d queue %d\n", pipe_id, queue_id); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); /* HIQ is set during driver init period with vmid set to 0*/ if (m->cp_hqd_vmid == 0) { @@ -264,15 +281,16 @@ static int hqd_load_v10_3(struct amdgpu_device *adev, void *mqd, data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); WREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE, data); - release_queue(adev); + release_queue(kgd); return 0; } -static int hiq_mqd_load_v10_3(struct amdgpu_device *adev, void *mqd, +static int hiq_mqd_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t doorbell_off) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; struct v10_compute_mqd *m; uint32_t mec, pipe; @@ -280,7 +298,7 @@ static int hiq_mqd_load_v10_3(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); @@ -316,15 +334,16 @@ static int hiq_mqd_load_v10_3(struct amdgpu_device *adev, void *mqd, out_unlock: spin_unlock(&adev->gfx.kiq.ring_lock); - release_queue(adev); + release_queue(kgd); return r; } -static int hqd_dump_v10_3(struct amdgpu_device *adev, +static int hqd_dump_v10_3(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t i = 0, reg; #define HQD_N_REGS 56 #define DUMP_REG(addr) do { \ @@ -338,13 +357,13 @@ static int hqd_dump_v10_3(struct amdgpu_device *adev, if (*dump == NULL) return -ENOMEM; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR); reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++) DUMP_REG(reg); - release_queue(adev); + release_queue(kgd); WARN_ON_ONCE(i != HQD_N_REGS); *n_regs = i; @@ -352,9 +371,10 @@ static int hqd_dump_v10_3(struct amdgpu_device *adev, return 0; } -static int hqd_sdma_load_v10_3(struct amdgpu_device *adev, void *mqd, +static int hqd_sdma_load_v10_3(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; unsigned long end_jiffies; @@ -421,10 +441,11 @@ static int hqd_sdma_load_v10_3(struct amdgpu_device *adev, void *mqd, return 0; } -static int hqd_sdma_dump_v10_3(struct amdgpu_device *adev, +static int hqd_sdma_dump_v10_3(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev, engine_id, queue_id); uint32_t i = 0, reg; @@ -452,15 +473,15 @@ static int hqd_sdma_dump_v10_3(struct amdgpu_device *adev, return 0; } -static bool hqd_is_occupied_v10_3(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +static bool hqd_is_occupied_v10_3(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t act; bool retval = false; uint32_t low, high; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); act = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE); if (act) { low = lower_32_bits(queue_address >> 8); @@ -470,13 +491,13 @@ static bool hqd_is_occupied_v10_3(struct amdgpu_device *adev, high == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE_HI)) retval = true; } - release_queue(adev); + release_queue(kgd); return retval; } -static bool hqd_sdma_is_occupied_v10_3(struct amdgpu_device *adev, - void *mqd) +static bool hqd_sdma_is_occupied_v10_3(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -493,17 +514,18 @@ static bool hqd_sdma_is_occupied_v10_3(struct amdgpu_device *adev, return false; } -static int hqd_destroy_v10_3(struct amdgpu_device *adev, void *mqd, +static int hqd_destroy_v10_3(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); enum hqd_dequeue_request_type type; unsigned long end_jiffies; uint32_t temp; struct v10_compute_mqd *m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (m->cp_hqd_vmid == 0) WREG32_FIELD15(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0); @@ -533,19 +555,20 @@ static int hqd_destroy_v10_3(struct amdgpu_device *adev, void *mqd, if (time_after(jiffies, end_jiffies)) { pr_err("cp queue pipe %d queue %d preemption failed\n", pipe_id, queue_id); - release_queue(adev); + release_queue(kgd); return -ETIME; } usleep_range(500, 1000); } - release_queue(adev); + release_queue(kgd); return 0; } -static int hqd_sdma_destroy_v10_3(struct amdgpu_device *adev, void *mqd, +static int hqd_sdma_destroy_v10_3(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v10_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; @@ -583,12 +606,12 @@ static int hqd_sdma_destroy_v10_3(struct amdgpu_device *adev, void *mqd, } -static int address_watch_disable_v10_3(struct amdgpu_device *adev) +static int address_watch_disable_v10_3(struct kgd_dev *kgd) { return 0; } -static int address_watch_execute_v10_3(struct amdgpu_device *adev, +static int address_watch_execute_v10_3(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, @@ -597,10 +620,11 @@ static int address_watch_execute_v10_3(struct amdgpu_device *adev, return 0; } -static int wave_control_execute_v10_3(struct amdgpu_device *adev, +static int wave_control_execute_v10_3(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; mutex_lock(&adev->grbm_idx_mutex); @@ -621,24 +645,28 @@ static int wave_control_execute_v10_3(struct amdgpu_device *adev, return 0; } -static uint32_t address_watch_get_offset_v10_3(struct amdgpu_device *adev, +static uint32_t address_watch_get_offset_v10_3(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset) { return 0; } -static void set_vm_context_page_table_base_v10_3(struct amdgpu_device *adev, - uint32_t vmid, uint64_t page_table_base) +static void set_vm_context_page_table_base_v10_3(struct kgd_dev *kgd, uint32_t vmid, + uint64_t page_table_base) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + /* SDMA is on gfxhub as well for Navi1* series */ adev->gfxhub.funcs->setup_vm_pt_regs(adev, vmid, page_table_base); } -static void program_trap_handler_settings_v10_3(struct amdgpu_device *adev, +static void program_trap_handler_settings_v10_3(struct kgd_dev *kgd, uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); /* * Program TBA registers @@ -657,14 +685,15 @@ static void program_trap_handler_settings_v10_3(struct amdgpu_device *adev, WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI), upper_32_bits(tma_addr >> 8)); - unlock_srbm(adev); + unlock_srbm(kgd); } #if 0 -uint32_t enable_debug_trap_v10_3(struct amdgpu_device *adev, +uint32_t enable_debug_trap_v10_3(struct kgd_dev *kgd, uint32_t trap_debug_wave_launch_mode, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; uint32_t orig_wave_cntl_value; uint32_t orig_stall_vmid; @@ -691,8 +720,10 @@ uint32_t enable_debug_trap_v10_3(struct amdgpu_device *adev, return 0; } -uint32_t disable_debug_trap_v10_3(struct amdgpu_device *adev) +uint32_t disable_debug_trap_v10_3(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + mutex_lock(&adev->grbm_idx_mutex); WREG32(SOC15_REG_OFFSET(GC, 0, mmSPI_GDBG_TRAP_MASK), 0); @@ -702,10 +733,11 @@ uint32_t disable_debug_trap_v10_3(struct amdgpu_device *adev) return 0; } -uint32_t set_wave_launch_trap_override_v10_3(struct amdgpu_device *adev, +uint32_t set_wave_launch_trap_override_v10_3(struct kgd_dev *kgd, uint32_t trap_override, uint32_t trap_mask) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; mutex_lock(&adev->grbm_idx_mutex); @@ -730,10 +762,11 @@ uint32_t set_wave_launch_trap_override_v10_3(struct amdgpu_device *adev, return 0; } -uint32_t set_wave_launch_mode_v10_3(struct amdgpu_device *adev, +uint32_t set_wave_launch_mode_v10_3(struct kgd_dev *kgd, uint8_t wave_launch_mode, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; bool is_stall_mode; bool is_mode_set; @@ -772,14 +805,16 @@ uint32_t set_wave_launch_mode_v10_3(struct amdgpu_device *adev, * sem_rearm_wait_time -- Wait Count for Semaphore re-arm. * deq_retry_wait_time -- Wait Count for Global Wave Syncs. */ -void get_iq_wait_times_v10_3(struct amdgpu_device *adev, +void get_iq_wait_times_v10_3(struct kgd_dev *kgd, uint32_t *wait_times) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + *wait_times = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_IQ_WAIT_TIME2)); } -void build_grace_period_packet_info_v10_3(struct amdgpu_device *adev, +void build_grace_period_packet_info_v10_3(struct kgd_dev *kgd, uint32_t wait_times, uint32_t grace_period, uint32_t *reg_offset, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index 36528dad76..b91d27e39b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -82,54 +82,68 @@ union TCP_WATCH_CNTL_BITS { float f32All; }; -static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe, +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, uint32_t queue, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue); mutex_lock(&adev->srbm_mutex); WREG32(mmSRBM_GFX_CNTL, value); } -static void unlock_srbm(struct amdgpu_device *adev) +static void unlock_srbm(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + WREG32(mmSRBM_GFX_CNTL, 0); mutex_unlock(&adev->srbm_mutex); } -static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id, +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, queue_id, 0); + lock_srbm(kgd, mec, pipe, queue_id, 0); } -static void release_queue(struct amdgpu_device *adev) +static void release_queue(struct kgd_dev *kgd) { - unlock_srbm(adev); + unlock_srbm(kgd); } -static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid, +static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32(mmSH_MEM_CONFIG, sh_mem_config); WREG32(mmSH_MEM_APE1_BASE, sh_mem_ape1_base); WREG32(mmSH_MEM_APE1_LIMIT, sh_mem_ape1_limit); WREG32(mmSH_MEM_BASES, sh_mem_bases); - unlock_srbm(adev); + unlock_srbm(kgd); } -static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, +static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid, unsigned int vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + /* * We have to assume that there is no outstanding mapping. * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because @@ -151,20 +165,21 @@ static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, return 0; } -static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id) +static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t mec; uint32_t pipe; mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, 0, 0); + lock_srbm(kgd, mec, pipe, 0, 0); WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); - unlock_srbm(adev); + unlock_srbm(kgd); return 0; } @@ -192,11 +207,12 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd) return (struct cik_sdma_rlc_registers *)mqd; } -static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t __user *wptr, uint32_t wptr_shift, - uint32_t wptr_mask, struct mm_struct *mm) +static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t wptr_shift, uint32_t wptr_mask, + struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct cik_mqd *m; uint32_t *mqd_hqd; uint32_t reg, wptr_val, data; @@ -204,7 +220,7 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); /* HQD registers extend from CP_MQD_BASE_ADDR to CP_MQD_CONTROL. */ mqd_hqd = &m->cp_mqd_base_addr_lo; @@ -223,24 +239,25 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, * release srbm_mutex to avoid circular dependency between * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. */ - release_queue(adev); + release_queue(kgd); valid_wptr = read_user_wptr(mm, wptr, wptr_val); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (valid_wptr) WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); WREG32(mmCP_HQD_ACTIVE, data); - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_dump(struct amdgpu_device *adev, +static int kgd_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t i = 0, reg; #define HQD_N_REGS (35+4) #define DUMP_REG(addr) do { \ @@ -254,7 +271,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, if (*dump == NULL) return -ENOMEM; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0); DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1); @@ -264,7 +281,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_MQD_CONTROL; reg++) DUMP_REG(reg); - release_queue(adev); + release_queue(kgd); WARN_ON_ONCE(i != HQD_N_REGS); *n_regs = i; @@ -272,9 +289,10 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, return 0; } -static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct cik_sdma_rlc_registers *m; unsigned long end_jiffies; uint32_t sdma_rlc_reg_offset; @@ -327,10 +345,11 @@ static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, return 0; } -static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, +static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET + queue_id * KFD_CIK_SDMA_QUEUE_OFFSET; uint32_t i = 0, reg; @@ -353,15 +372,15 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, return 0; } -static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t act; bool retval = false; uint32_t low, high; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); act = RREG32(mmCP_HQD_ACTIVE); if (act) { low = lower_32_bits(queue_address >> 8); @@ -371,12 +390,13 @@ static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, high == RREG32(mmCP_HQD_PQ_BASE_HI)) retval = true; } - release_queue(adev); + release_queue(kgd); return retval; } -static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) +static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct cik_sdma_rlc_registers *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -392,11 +412,12 @@ static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) return false; } -static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t temp; enum hqd_dequeue_request_type type; unsigned long flags, end_jiffies; @@ -405,7 +426,7 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, if (amdgpu_in_reset(adev)) return -EIO; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 0); switch (reset_type) { @@ -483,19 +504,20 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, break; if (time_after(jiffies, end_jiffies)) { pr_err("cp queue preemption time out\n"); - release_queue(adev); + release_queue(kgd); return -ETIME; } usleep_range(500, 1000); } - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct cik_sdma_rlc_registers *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; @@ -529,8 +551,9 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, return 0; } -static int kgd_address_watch_disable(struct amdgpu_device *adev) +static int kgd_address_watch_disable(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); union TCP_WATCH_CNTL_BITS cntl; unsigned int i; @@ -548,12 +571,13 @@ static int kgd_address_watch_disable(struct amdgpu_device *adev) return 0; } -static int kgd_address_watch_execute(struct amdgpu_device *adev, +static int kgd_address_watch_execute(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, uint32_t addr_lo) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); union TCP_WATCH_CNTL_BITS cntl; cntl.u32All = cntl_val; @@ -578,10 +602,11 @@ static int kgd_address_watch_execute(struct amdgpu_device *adev, return 0; } -static int kgd_wave_control_execute(struct amdgpu_device *adev, +static int kgd_wave_control_execute(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data; mutex_lock(&adev->grbm_idx_mutex); @@ -602,17 +627,18 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev, return 0; } -static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev, +static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset) { return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset]; } -static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, +static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid) { uint32_t value; + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; value = RREG32(mmATC_VMID0_PASID_MAPPING + vmid); *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK; @@ -620,17 +646,21 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -static void set_scratch_backing_va(struct amdgpu_device *adev, +static void set_scratch_backing_va(struct kgd_dev *kgd, uint64_t va, uint32_t vmid) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va); - unlock_srbm(adev); + unlock_srbm(kgd); } -static void set_vm_context_page_table_base(struct amdgpu_device *adev, - uint32_t vmid, uint64_t page_table_base) +static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, + uint64_t page_table_base) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { pr_err("trying to set page table base for wrong VMID\n"); return; @@ -646,8 +676,10 @@ static void set_vm_context_page_table_base(struct amdgpu_device *adev, * @vmid: vmid pointer * read vmid from register (CIK). */ -static uint32_t read_vmid_from_vmfault_reg(struct amdgpu_device *adev) +static uint32_t read_vmid_from_vmfault_reg(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS); return REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS, VMID); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index 52832cd69a..5ce0ce704a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -39,54 +39,68 @@ enum hqd_dequeue_request_type { RESET_WAVES }; -static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe, +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, uint32_t queue, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t value = PIPEID(pipe) | MEID(mec) | VMID(vmid) | QUEUEID(queue); mutex_lock(&adev->srbm_mutex); WREG32(mmSRBM_GFX_CNTL, value); } -static void unlock_srbm(struct amdgpu_device *adev) +static void unlock_srbm(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + WREG32(mmSRBM_GFX_CNTL, 0); mutex_unlock(&adev->srbm_mutex); } -static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id, +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, queue_id, 0); + lock_srbm(kgd, mec, pipe, queue_id, 0); } -static void release_queue(struct amdgpu_device *adev) +static void release_queue(struct kgd_dev *kgd) { - unlock_srbm(adev); + unlock_srbm(kgd); } -static void kgd_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid, +static void kgd_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32(mmSH_MEM_CONFIG, sh_mem_config); WREG32(mmSH_MEM_APE1_BASE, sh_mem_ape1_base); WREG32(mmSH_MEM_APE1_LIMIT, sh_mem_ape1_limit); WREG32(mmSH_MEM_BASES, sh_mem_bases); - unlock_srbm(adev); + unlock_srbm(kgd); } -static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, +static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid, unsigned int vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + /* * We have to assume that there is no outstanding mapping. * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because @@ -109,20 +123,21 @@ static int kgd_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, return 0; } -static int kgd_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id) +static int kgd_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t mec; uint32_t pipe; mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, 0, 0); + lock_srbm(kgd, mec, pipe, 0, 0); WREG32(mmCPC_INT_CNTL, CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); - unlock_srbm(adev); + unlock_srbm(kgd); return 0; } @@ -150,11 +165,12 @@ static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd) return (struct vi_sdma_mqd *)mqd; } -static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t __user *wptr, uint32_t wptr_shift, - uint32_t wptr_mask, struct mm_struct *mm) +static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t wptr_shift, uint32_t wptr_mask, + struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct vi_mqd *m; uint32_t *mqd_hqd; uint32_t reg, wptr_val, data; @@ -162,7 +178,7 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); /* HIQ is set during driver init period with vmid set to 0*/ if (m->cp_hqd_vmid == 0) { @@ -190,7 +206,7 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, * on ASICs that do not support context-save. * EOP writes/reads can start anywhere in the ring. */ - if (adev->asic_type != CHIP_TONGA) { + if (get_amdgpu_device(kgd)->asic_type != CHIP_TONGA) { WREG32(mmCP_HQD_EOP_RPTR, m->cp_hqd_eop_rptr); WREG32(mmCP_HQD_EOP_WPTR, m->cp_hqd_eop_wptr); WREG32(mmCP_HQD_EOP_WPTR_MEM, m->cp_hqd_eop_wptr_mem); @@ -210,24 +226,25 @@ static int kgd_hqd_load(struct amdgpu_device *adev, void *mqd, * release srbm_mutex to avoid circular dependency between * srbm_mutex->mm_sem->reservation_ww_class_mutex->srbm_mutex. */ - release_queue(adev); + release_queue(kgd); valid_wptr = read_user_wptr(mm, wptr, wptr_val); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (valid_wptr) WREG32(mmCP_HQD_PQ_WPTR, (wptr_val << wptr_shift) & wptr_mask); data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); WREG32(mmCP_HQD_ACTIVE, data); - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_dump(struct amdgpu_device *adev, +static int kgd_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t i = 0, reg; #define HQD_N_REGS (54+4) #define DUMP_REG(addr) do { \ @@ -241,7 +258,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, if (*dump == NULL) return -ENOMEM; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE0); DUMP_REG(mmCOMPUTE_STATIC_THREAD_MGMT_SE1); @@ -251,7 +268,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, for (reg = mmCP_MQD_BASE_ADDR; reg <= mmCP_HQD_EOP_DONES; reg++) DUMP_REG(reg); - release_queue(adev); + release_queue(kgd); WARN_ON_ONCE(i != HQD_N_REGS); *n_regs = i; @@ -259,9 +276,10 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, return 0; } -static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct vi_sdma_mqd *m; unsigned long end_jiffies; uint32_t sdma_rlc_reg_offset; @@ -313,10 +331,11 @@ static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, return 0; } -static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, +static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_offset = engine_id * SDMA1_REGISTER_OFFSET + queue_id * KFD_VI_SDMA_QUEUE_OFFSET; uint32_t i = 0, reg; @@ -348,15 +367,15 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, return 0; } -static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t act; bool retval = false; uint32_t low, high; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); act = RREG32(mmCP_HQD_ACTIVE); if (act) { low = lower_32_bits(queue_address >> 8); @@ -366,12 +385,13 @@ static bool kgd_hqd_is_occupied(struct amdgpu_device *adev, high == RREG32(mmCP_HQD_PQ_BASE_HI)) retval = true; } - release_queue(adev); + release_queue(kgd); return retval; } -static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) +static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct vi_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -387,11 +407,12 @@ static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) return false; } -static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t temp; enum hqd_dequeue_request_type type; unsigned long flags, end_jiffies; @@ -401,7 +422,7 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, if (amdgpu_in_reset(adev)) return -EIO; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (m->cp_hqd_vmid == 0) WREG32_FIELD(RLC_CP_SCHEDULERS, scheduler1, 0); @@ -481,19 +502,20 @@ static int kgd_hqd_destroy(struct amdgpu_device *adev, void *mqd, break; if (time_after(jiffies, end_jiffies)) { pr_err("cp queue preemption time out.\n"); - release_queue(adev); + release_queue(kgd); return -ETIME; } usleep_range(500, 1000); } - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct vi_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; @@ -527,10 +549,11 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, return 0; } -static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, +static bool get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid) { uint32_t value; + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; value = RREG32(mmATC_VMID0_PASID_MAPPING + vmid); *p_pasid = value & ATC_VMID0_PASID_MAPPING__PASID_MASK; @@ -538,12 +561,12 @@ static bool get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -static int kgd_address_watch_disable(struct amdgpu_device *adev) +static int kgd_address_watch_disable(struct kgd_dev *kgd) { return 0; } -static int kgd_address_watch_execute(struct amdgpu_device *adev, +static int kgd_address_watch_execute(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, @@ -552,10 +575,11 @@ static int kgd_address_watch_execute(struct amdgpu_device *adev, return 0; } -static int kgd_wave_control_execute(struct amdgpu_device *adev, +static int kgd_wave_control_execute(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; mutex_lock(&adev->grbm_idx_mutex); @@ -576,24 +600,28 @@ static int kgd_wave_control_execute(struct amdgpu_device *adev, return 0; } -static uint32_t kgd_address_watch_get_offset(struct amdgpu_device *adev, +static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset) { return 0; } -static void set_scratch_backing_va(struct amdgpu_device *adev, +static void set_scratch_backing_va(struct kgd_dev *kgd, uint64_t va, uint32_t vmid) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32(mmSH_HIDDEN_PRIVATE_BASE_VMID, va); - unlock_srbm(adev); + unlock_srbm(kgd); } -static void set_vm_context_page_table_base(struct amdgpu_device *adev, - uint32_t vmid, uint64_t page_table_base) +static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, + uint64_t page_table_base) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { pr_err("trying to set page table base for wrong VMID\n"); return; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 1abf662a0e..bcc1cbeb87 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -46,26 +46,37 @@ enum hqd_dequeue_request_type { SAVE_WAVES }; -static void lock_srbm(struct amdgpu_device *adev, uint32_t mec, uint32_t pipe, +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + +static void lock_srbm(struct kgd_dev *kgd, uint32_t mec, uint32_t pipe, uint32_t queue, uint32_t vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + mutex_lock(&adev->srbm_mutex); soc15_grbm_select(adev, mec, pipe, queue, vmid); } -static void unlock_srbm(struct amdgpu_device *adev) +static void unlock_srbm(struct kgd_dev *kgd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + soc15_grbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); } -static void acquire_queue(struct amdgpu_device *adev, uint32_t pipe_id, +static void acquire_queue(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + uint32_t mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; uint32_t pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, queue_id, 0); + lock_srbm(kgd, mec, pipe, queue_id, 0); } static uint64_t get_queue_mask(struct amdgpu_device *adev, @@ -77,29 +88,33 @@ static uint64_t get_queue_mask(struct amdgpu_device *adev, return 1ull << bit; } -static void release_queue(struct amdgpu_device *adev) +static void release_queue(struct kgd_dev *kgd) { - unlock_srbm(adev); + unlock_srbm(kgd); } -void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid, +void kgd_gfx_v9_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG), sh_mem_config); WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmSH_MEM_BASES), sh_mem_bases); /* APE1 no longer exists on GFX9 */ - unlock_srbm(adev); + unlock_srbm(kgd); } -int kgd_gfx_v9_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, +int kgd_gfx_v9_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid, unsigned int vmid) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + /* * We have to assume that there is no outstanding mapping. * The ATC_VMID_PASID_MAPPING_UPDATE_STATUS bit could be 0 because @@ -156,21 +171,22 @@ int kgd_gfx_v9_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, * but still works */ -int kgd_gfx_v9_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id) +int kgd_gfx_v9_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t mec; uint32_t pipe; mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); - lock_srbm(adev, mec, pipe, 0, 0); + lock_srbm(kgd, mec, pipe, 0, 0); - WREG32_SOC15(GC, 0, mmCPC_INT_CNTL, + WREG32(SOC15_REG_OFFSET(GC, 0, mmCPC_INT_CNTL), CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK | CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK); - unlock_srbm(adev); + unlock_srbm(kgd); return 0; } @@ -217,18 +233,19 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd) return (struct v9_sdma_mqd *)mqd; } -int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd, - uint32_t pipe_id, uint32_t queue_id, - uint32_t __user *wptr, uint32_t wptr_shift, - uint32_t wptr_mask, struct mm_struct *mm) +int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, + uint32_t queue_id, uint32_t __user *wptr, + uint32_t wptr_shift, uint32_t wptr_mask, + struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_mqd *m; uint32_t *mqd_hqd; uint32_t reg, hqd_base, data; m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); /* HQD registers extend from CP_MQD_BASE_ADDR to CP_HQD_EOP_WPTR_MEM. */ mqd_hqd = &m->cp_mqd_base_addr_lo; @@ -279,7 +296,7 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd, lower_32_bits((uintptr_t)wptr)); WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_POLL_ADDR_HI), upper_32_bits((uintptr_t)wptr)); - WREG32_SOC15(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1, + WREG32(SOC15_REG_OFFSET(GC, 0, mmCP_PQ_WPTR_POLL_CNTL1), (uint32_t)get_queue_mask(adev, pipe_id, queue_id)); } @@ -291,15 +308,16 @@ int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd, data = REG_SET_FIELD(m->cp_hqd_active, CP_HQD_ACTIVE, ACTIVE, 1); WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE), data); - release_queue(adev); + release_queue(kgd); return 0; } -int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, +int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t doorbell_off) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; struct v9_mqd *m; uint32_t mec, pipe; @@ -307,7 +325,7 @@ int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, m = get_mqd(mqd); - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); mec = (pipe_id / adev->gfx.mec.num_pipe_per_mec) + 1; pipe = (pipe_id % adev->gfx.mec.num_pipe_per_mec); @@ -343,15 +361,16 @@ int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, out_unlock: spin_unlock(&adev->gfx.kiq.ring_lock); - release_queue(adev); + release_queue(kgd); return r; } -int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev, +int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t i = 0, reg; #define HQD_N_REGS 56 #define DUMP_REG(addr) do { \ @@ -365,13 +384,13 @@ int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev, if (*dump == NULL) return -ENOMEM; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); for (reg = SOC15_REG_OFFSET(GC, 0, mmCP_MQD_BASE_ADDR); reg <= SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_WPTR_HI); reg++) DUMP_REG(reg); - release_queue(adev); + release_queue(kgd); WARN_ON_ONCE(i != HQD_N_REGS); *n_regs = i; @@ -379,9 +398,10 @@ int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev, return 0; } -static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; unsigned long end_jiffies; @@ -448,10 +468,11 @@ static int kgd_hqd_sdma_load(struct amdgpu_device *adev, void *mqd, return 0; } -static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, +static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t sdma_rlc_reg_offset = get_sdma_rlc_reg_offset(adev, engine_id, queue_id); uint32_t i = 0, reg; @@ -479,30 +500,31 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, return 0; } -bool kgd_gfx_v9_hqd_is_occupied(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id) +bool kgd_gfx_v9_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t act; bool retval = false; uint32_t low, high; - acquire_queue(adev, pipe_id, queue_id); - act = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE); + acquire_queue(kgd, pipe_id, queue_id); + act = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE)); if (act) { low = lower_32_bits(queue_address >> 8); high = upper_32_bits(queue_address >> 8); - if (low == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE) && - high == RREG32_SOC15(GC, 0, mmCP_HQD_PQ_BASE_HI)) + if (low == RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_BASE)) && + high == RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_PQ_BASE_HI))) retval = true; } - release_queue(adev); + release_queue(kgd); return retval; } -static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) +static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t sdma_rlc_rb_cntl; @@ -519,11 +541,12 @@ static bool kgd_hqd_sdma_is_occupied(struct amdgpu_device *adev, void *mqd) return false; } -int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd, +int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); enum hqd_dequeue_request_type type; unsigned long end_jiffies; uint32_t temp; @@ -532,7 +555,7 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd, if (amdgpu_in_reset(adev)) return -EIO; - acquire_queue(adev, pipe_id, queue_id); + acquire_queue(kgd, pipe_id, queue_id); if (m->cp_hqd_vmid == 0) WREG32_FIELD15_RLC(GC, 0, RLC_CP_SCHEDULERS, scheduler1, 0); @@ -556,24 +579,25 @@ int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd, end_jiffies = (utimeout * HZ / 1000) + jiffies; while (true) { - temp = RREG32_SOC15(GC, 0, mmCP_HQD_ACTIVE); + temp = RREG32(SOC15_REG_OFFSET(GC, 0, mmCP_HQD_ACTIVE)); if (!(temp & CP_HQD_ACTIVE__ACTIVE_MASK)) break; if (time_after(jiffies, end_jiffies)) { pr_err("cp queue preemption time out.\n"); - release_queue(adev); + release_queue(kgd); return -ETIME; } usleep_range(500, 1000); } - release_queue(adev); + release_queue(kgd); return 0; } -static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, +static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, unsigned int utimeout) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct v9_sdma_mqd *m; uint32_t sdma_rlc_reg_offset; uint32_t temp; @@ -610,10 +634,11 @@ static int kgd_hqd_sdma_destroy(struct amdgpu_device *adev, void *mqd, return 0; } -bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, +bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid) { uint32_t value; + struct amdgpu_device *adev = (struct amdgpu_device *) kgd; value = RREG32(SOC15_REG_OFFSET(ATHUB, 0, mmATC_VMID0_PASID_MAPPING) + vmid); @@ -622,12 +647,12 @@ bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, return !!(value & ATC_VMID0_PASID_MAPPING__VALID_MASK); } -int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev) +int kgd_gfx_v9_address_watch_disable(struct kgd_dev *kgd) { return 0; } -int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev, +int kgd_gfx_v9_address_watch_execute(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, @@ -636,16 +661,17 @@ int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev, return 0; } -int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev, +int kgd_gfx_v9_wave_control_execute(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); uint32_t data = 0; mutex_lock(&adev->grbm_idx_mutex); WREG32_SOC15_RLC_SHADOW(GC, 0, mmGRBM_GFX_INDEX, gfx_index_val); - WREG32_SOC15(GC, 0, mmSQ_CMD, sq_cmd); + WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_CMD), sq_cmd); data = REG_SET_FIELD(data, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1); @@ -660,16 +686,18 @@ int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev, return 0; } -uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev, +uint32_t kgd_gfx_v9_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset) { return 0; } -void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev, +void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) { pr_err("trying to set page table base for wrong VMID %u\n", vmid); @@ -722,7 +750,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx, pipe_idx = queue_idx / adev->gfx.mec.num_queue_per_pipe; queue_slot = queue_idx % adev->gfx.mec.num_queue_per_pipe; soc15_grbm_select(adev, 1, pipe_idx, queue_slot, 0); - reg_val = RREG32_SOC15_IP(GC, SOC15_REG_OFFSET(GC, 0, mmSPI_CSQ_WF_ACTIVE_COUNT_0) + + reg_val = RREG32(SOC15_REG_OFFSET(GC, 0, mmSPI_CSQ_WF_ACTIVE_COUNT_0) + queue_slot); *wave_cnt = reg_val & SPI_CSQ_WF_ACTIVE_COUNT_0__COUNT_MASK; if (*wave_cnt != 0) @@ -776,7 +804,7 @@ static void get_wave_count(struct amdgpu_device *adev, int queue_idx, * * Reading registers referenced above involves programming GRBM appropriately */ -void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid, +void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid, int *pasid_wave_cnt, int *max_waves_per_cu) { int qidx; @@ -790,8 +818,10 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid, int pasid_tmp; int max_queue_cnt; int vmid_wave_cnt = 0; + struct amdgpu_device *adev; DECLARE_BITMAP(cp_queue_bitmap, KGD_MAX_QUEUES); + adev = get_amdgpu_device(kgd); lock_spi_csq_mutexes(adev); soc15_grbm_select(adev, 1, 0, 0, 0); @@ -809,7 +839,8 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid, for (sh_idx = 0; sh_idx < sh_cnt; sh_idx++) { gfx_v9_0_select_se_sh(adev, se_idx, sh_idx, 0xffffffff); - queue_map = RREG32_SOC15(GC, 0, mmSPI_CSQ_WF_ACTIVE_STATUS); + queue_map = RREG32(SOC15_REG_OFFSET(GC, 0, + mmSPI_CSQ_WF_ACTIVE_STATUS)); /* * Assumption: queue map encodes following schema: four @@ -851,28 +882,30 @@ void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid, adev->gfx.cu_info.max_waves_per_simd; } -void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev, +void kgd_gfx_v9_program_trap_handler_settings(struct kgd_dev *kgd, uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr) { - lock_srbm(adev, 0, 0, 0, vmid); + struct amdgpu_device *adev = get_amdgpu_device(kgd); + + lock_srbm(kgd, 0, 0, 0, vmid); /* * Program TBA registers */ - WREG32_SOC15(GC, 0, mmSQ_SHADER_TBA_LO, + WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TBA_LO), lower_32_bits(tba_addr >> 8)); - WREG32_SOC15(GC, 0, mmSQ_SHADER_TBA_HI, + WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TBA_HI), upper_32_bits(tba_addr >> 8)); /* * Program TMA registers */ - WREG32_SOC15(GC, 0, mmSQ_SHADER_TMA_LO, + WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_LO), lower_32_bits(tma_addr >> 8)); - WREG32_SOC15(GC, 0, mmSQ_SHADER_TMA_HI, + WREG32(SOC15_REG_OFFSET(GC, 0, mmSQ_SHADER_TMA_HI), upper_32_bits(tma_addr >> 8)); - unlock_srbm(adev); + unlock_srbm(kgd); } const struct kfd2kgd_calls gfx_v9_kfd2kgd = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h index 24be49df26..c635911068 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.h @@ -22,49 +22,48 @@ -void kgd_gfx_v9_program_sh_mem_settings(struct amdgpu_device *adev, uint32_t vmid, +void kgd_gfx_v9_program_sh_mem_settings(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases); -int kgd_gfx_v9_set_pasid_vmid_mapping(struct amdgpu_device *adev, u32 pasid, +int kgd_gfx_v9_set_pasid_vmid_mapping(struct kgd_dev *kgd, u32 pasid, unsigned int vmid); -int kgd_gfx_v9_init_interrupts(struct amdgpu_device *adev, uint32_t pipe_id); -int kgd_gfx_v9_hqd_load(struct amdgpu_device *adev, void *mqd, uint32_t pipe_id, +int kgd_gfx_v9_init_interrupts(struct kgd_dev *kgd, uint32_t pipe_id); +int kgd_gfx_v9_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t __user *wptr, uint32_t wptr_shift, uint32_t wptr_mask, struct mm_struct *mm); -int kgd_gfx_v9_hiq_mqd_load(struct amdgpu_device *adev, void *mqd, +int kgd_gfx_v9_hiq_mqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t doorbell_off); -int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev, +int kgd_gfx_v9_hqd_dump(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs); -bool kgd_gfx_v9_hqd_is_occupied(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id); -int kgd_gfx_v9_hqd_destroy(struct amdgpu_device *adev, void *mqd, +bool kgd_gfx_v9_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, + uint32_t pipe_id, uint32_t queue_id); +int kgd_gfx_v9_hqd_destroy(struct kgd_dev *kgd, void *mqd, enum kfd_preempt_type reset_type, unsigned int utimeout, uint32_t pipe_id, uint32_t queue_id); -int kgd_gfx_v9_address_watch_disable(struct amdgpu_device *adev); -int kgd_gfx_v9_address_watch_execute(struct amdgpu_device *adev, +int kgd_gfx_v9_address_watch_disable(struct kgd_dev *kgd); +int kgd_gfx_v9_address_watch_execute(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, uint32_t addr_lo); -int kgd_gfx_v9_wave_control_execute(struct amdgpu_device *adev, +int kgd_gfx_v9_wave_control_execute(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd); -uint32_t kgd_gfx_v9_address_watch_get_offset(struct amdgpu_device *adev, +uint32_t kgd_gfx_v9_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset); -bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct amdgpu_device *adev, +bool kgd_gfx_v9_get_atc_vmid_pasid_mapping_info(struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid); -void kgd_gfx_v9_set_vm_context_page_table_base(struct amdgpu_device *adev, +void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base); -void kgd_gfx_v9_get_cu_occupancy(struct amdgpu_device *adev, int pasid, +void kgd_gfx_v9_get_cu_occupancy(struct kgd_dev *kgd, int pasid, int *pasid_wave_cnt, int *max_waves_per_cu); -void kgd_gfx_v9_program_trap_handler_settings(struct amdgpu_device *adev, +void kgd_gfx_v9_program_trap_handler_settings(struct kgd_dev *kgd, uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index f9bab963a9..ab36cce59d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -60,6 +60,12 @@ static const char * const domain_bit_to_string[] = { static void amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work); + +static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd) +{ + return (struct amdgpu_device *)kgd; +} + static bool kfd_mem_is_attached(struct amdgpu_vm *avm, struct kgd_mem *mem) { @@ -120,19 +126,8 @@ static size_t amdgpu_amdkfd_acc_size(uint64_t size) PAGE_ALIGN(size); } -/** - * @amdgpu_amdkfd_reserve_mem_limit() - Decrease available memory by size - * of buffer including any reserved for control structures - * - * @adev: Device to which allocated BO belongs to - * @size: Size of buffer, in bytes, encapsulated by B0. This should be - * equivalent to amdgpu_bo_size(BO) - * @alloc_flag: Flag used in allocating a BO as noted above - * - * Return: returns -ENOMEM in case of error, ZERO otherwise - */ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev, - uint64_t size, u32 alloc_flag) + uint64_t size, u32 domain, bool sg) { uint64_t reserved_for_pt = ESTIMATE_PT_SIZE(amdgpu_amdkfd_total_mem_size); @@ -142,24 +137,20 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev, acc_size = amdgpu_amdkfd_acc_size(size); vram_needed = 0; - if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) { + if (domain == AMDGPU_GEM_DOMAIN_GTT) { + /* TTM GTT memory */ system_mem_needed = acc_size + size; ttm_mem_needed = acc_size + size; - } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { - system_mem_needed = acc_size; - ttm_mem_needed = acc_size; - vram_needed = size; - } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) { + } else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) { + /* Userptr */ system_mem_needed = acc_size + size; ttm_mem_needed = acc_size; - } else if (alloc_flag & - (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | - KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { + } else { + /* VRAM and SG */ system_mem_needed = acc_size; ttm_mem_needed = acc_size; - } else { - pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag); - return -ENOMEM; + if (domain == AMDGPU_GEM_DOMAIN_VRAM) + vram_needed = size; } spin_lock(&kfd_mem_limit.mem_limit_lock); @@ -175,72 +166,62 @@ static int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev, (adev->kfd.vram_used + vram_needed > adev->gmc.real_vram_size - reserved_for_pt)) { ret = -ENOMEM; - goto release; + } else { + kfd_mem_limit.system_mem_used += system_mem_needed; + kfd_mem_limit.ttm_mem_used += ttm_mem_needed; + adev->kfd.vram_used += vram_needed; } - /* Update memory accounting by decreasing available system - * memory, TTM memory and GPU memory as computed above - */ - adev->kfd.vram_used += vram_needed; - kfd_mem_limit.system_mem_used += system_mem_needed; - kfd_mem_limit.ttm_mem_used += ttm_mem_needed; - -release: spin_unlock(&kfd_mem_limit.mem_limit_lock); return ret; } static void unreserve_mem_limit(struct amdgpu_device *adev, - uint64_t size, u32 alloc_flag) + uint64_t size, u32 domain, bool sg) { size_t acc_size; acc_size = amdgpu_amdkfd_acc_size(size); spin_lock(&kfd_mem_limit.mem_limit_lock); - - if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_GTT) { + if (domain == AMDGPU_GEM_DOMAIN_GTT) { kfd_mem_limit.system_mem_used -= (acc_size + size); kfd_mem_limit.ttm_mem_used -= (acc_size + size); - } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { - kfd_mem_limit.system_mem_used -= acc_size; - kfd_mem_limit.ttm_mem_used -= acc_size; - adev->kfd.vram_used -= size; - } else if (alloc_flag & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) { + } else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) { kfd_mem_limit.system_mem_used -= (acc_size + size); kfd_mem_limit.ttm_mem_used -= acc_size; - } else if (alloc_flag & - (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | - KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { + } else { kfd_mem_limit.system_mem_used -= acc_size; kfd_mem_limit.ttm_mem_used -= acc_size; - } else { - pr_err("%s: Invalid BO type %#x\n", __func__, alloc_flag); - goto release; + if (domain == AMDGPU_GEM_DOMAIN_VRAM) { + adev->kfd.vram_used -= size; + WARN_ONCE(adev->kfd.vram_used < 0, + "kfd VRAM memory accounting unbalanced"); + } } - - WARN_ONCE(adev->kfd.vram_used < 0, - "KFD VRAM memory accounting unbalanced"); - WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0, - "KFD TTM memory accounting unbalanced"); WARN_ONCE(kfd_mem_limit.system_mem_used < 0, - "KFD system memory accounting unbalanced"); + "kfd system memory accounting unbalanced"); + WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0, + "kfd TTM memory accounting unbalanced"); -release: spin_unlock(&kfd_mem_limit.mem_limit_lock); } -void amdgpu_amdkfd_release_notify(struct amdgpu_bo *bo) +void amdgpu_amdkfd_unreserve_memory_limit(struct amdgpu_bo *bo) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); - u32 alloc_flags = bo->kfd_bo->alloc_flags; - u64 size = amdgpu_bo_size(bo); + u32 domain = bo->preferred_domains; + bool sg = (bo->preferred_domains == AMDGPU_GEM_DOMAIN_CPU); - unreserve_mem_limit(adev, size, alloc_flags); + if (bo->flags & AMDGPU_AMDKFD_CREATE_USERPTR_BO) { + domain = AMDGPU_GEM_DOMAIN_CPU; + sg = false; + } - kfree(bo->kfd_bo); + unreserve_mem_limit(adev, amdgpu_bo_size(bo), domain, sg); } + /* amdgpu_amdkfd_remove_eviction_fence - Removes eviction fence from BO's * reservation object. * @@ -663,6 +644,12 @@ kfd_mem_attach_dmabuf(struct amdgpu_device *adev, struct kgd_mem *mem, if (IS_ERR(gobj)) return PTR_ERR(gobj); + /* Import takes an extra reference on the dmabuf. Drop it now to + * avoid leaking it. We only need the one reference in + * kgd_mem->dmabuf. + */ + dma_buf_put(mem->dmabuf); + *bo = gem_to_amdgpu_bo(gobj); (*bo)->flags |= AMDGPU_GEM_CREATE_PREEMPTIBLE; (*bo)->parent = amdgpu_bo_ref(mem->bo); @@ -708,12 +695,10 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, pr_debug("\t add VA 0x%llx - 0x%llx to vm %p\n", va, va + bo_size, vm); - if (adev == bo_adev || - (amdgpu_ttm_tt_get_usermm(mem->bo->tbo.ttm) && adev->ram_is_direct_mapped) || - (mem->domain == AMDGPU_GEM_DOMAIN_VRAM && amdgpu_xgmi_same_hive(adev, bo_adev))) { - /* Mappings on the local GPU, or VRAM mappings in the - * local hive, or userptr mapping IOMMU direct map mode - * share the original BO + if (adev == bo_adev || (mem->domain == AMDGPU_GEM_DOMAIN_VRAM && + amdgpu_xgmi_same_hive(adev, bo_adev))) { + /* Mappings on the local GPU and VRAM mappings in the + * local hive share the original BO */ attachment[i]->type = KFD_MEM_ATT_SHARED; bo[i] = mem->bo; @@ -749,19 +734,14 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, } /* Add BO to VM internal data structures */ - ret = amdgpu_bo_reserve(bo[i], false); - if (ret) { - pr_debug("Unable to reserve BO during memory attach"); - goto unwind; - } attachment[i]->bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]); - amdgpu_bo_unreserve(bo[i]); if (unlikely(!attachment[i]->bo_va)) { ret = -ENOMEM; pr_err("Failed to add BO object to VM. ret == %d\n", ret); goto unwind; } + attachment[i]->va = va; attachment[i]->pte_flags = get_pte_flags(adev, mem); attachment[i]->adev = adev; @@ -777,9 +757,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, if (!attachment[i]) continue; if (attachment[i]->bo_va) { - amdgpu_bo_reserve(bo[i], true); amdgpu_vm_bo_rmv(adev, attachment[i]->bo_va); - amdgpu_bo_unreserve(bo[i]); list_del(&attachment[i]->list); } if (bo[i]) @@ -1291,60 +1269,12 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, return ret; } -/** - * amdgpu_amdkfd_gpuvm_pin_bo() - Pins a BO using following criteria - * @bo: Handle of buffer object being pinned - * @domain: Domain into which BO should be pinned - * - * - USERPTR BOs are UNPINNABLE and will return error - * - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their - * PIN count incremented. It is valid to PIN a BO multiple times - * - * Return: ZERO if successful in pinning, Non-Zero in case of error. - */ -static int amdgpu_amdkfd_gpuvm_pin_bo(struct amdgpu_bo *bo, u32 domain) -{ - int ret = 0; - - ret = amdgpu_bo_reserve(bo, false); - if (unlikely(ret)) - return ret; - - ret = amdgpu_bo_pin_restricted(bo, domain, 0, 0); - if (ret) - pr_err("Error in Pinning BO to domain: %d\n", domain); - - amdgpu_bo_sync_wait(bo, AMDGPU_FENCE_OWNER_KFD, false); - amdgpu_bo_unreserve(bo); - - return ret; -} - -/** - * amdgpu_amdkfd_gpuvm_unpin_bo() - Unpins BO using following criteria - * @bo: Handle of buffer object being unpinned - * - * - Is a illegal request for USERPTR BOs and is ignored - * - All other BO types (GTT, VRAM, MMIO and DOORBELL) will have their - * PIN count decremented. Calls to UNPIN must balance calls to PIN - */ -static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo) -{ - int ret = 0; - - ret = amdgpu_bo_reserve(bo, false); - if (unlikely(ret)) - return; - - amdgpu_bo_unpin(bo); - amdgpu_bo_unreserve(bo); -} - -int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd, struct file *filp, u32 pasid, void **process_info, struct dma_fence **ef) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_fpriv *drv_priv; struct amdgpu_vm *avm; int ret; @@ -1420,12 +1350,12 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev, } } -void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev, - void *drm_priv) +void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *drm_priv) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_vm *avm; - if (WARN_ON(!adev || !drm_priv)) + if (WARN_ON(!kgd || !drm_priv)) return; avm = drm_priv_to_vm(drm_priv); @@ -1453,10 +1383,11 @@ uint64_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *drm_priv) } int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( - struct amdgpu_device *adev, uint64_t va, uint64_t size, + struct kgd_dev *kgd, uint64_t va, uint64_t size, void *drm_priv, struct kgd_mem **mem, uint64_t *offset, uint32_t flags) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); enum ttm_bo_type bo_type = ttm_bo_type_device; struct sg_table *sg = NULL; @@ -1520,7 +1451,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( amdgpu_sync_create(&(*mem)->sync); - ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, flags); + ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, alloc_domain, !!sg); if (ret) { pr_debug("Insufficient memory\n"); goto err_reserve_limit; @@ -1561,15 +1492,6 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( ret = init_user_pages(*mem, user_addr); if (ret) goto allocate_init_user_pages_failed; - } else if (flags & (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | - KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { - ret = amdgpu_amdkfd_gpuvm_pin_bo(bo, AMDGPU_GEM_DOMAIN_GTT); - if (ret) { - pr_err("Pinning MMIO/DOORBELL BO during ALLOC FAILED\n"); - goto err_pin_bo; - } - bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; - bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT; } if (offset) @@ -1578,14 +1500,13 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( return 0; allocate_init_user_pages_failed: -err_pin_bo: remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); drm_vma_node_revoke(&gobj->vma_node, drm_priv); err_node_allow: /* Don't unreserve system mem limit twice */ goto err_reserve_limit; err_bo_create: - unreserve_mem_limit(adev, size, flags); + unreserve_mem_limit(adev, size, alloc_domain, !!sg); err_reserve_limit: mutex_destroy(&(*mem)->lock); if (gobj) @@ -1601,7 +1522,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( } int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv, + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, uint64_t *size) { struct amdkfd_process_info *process_info = mem->process_info; @@ -1614,14 +1535,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( bool is_imported = false; mutex_lock(&mem->lock); - - /* Unpin MMIO/DOORBELL BO's that were pinnned during allocation */ - if (mem->alloc_flags & - (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | - KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { - amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo); - } - mapped_to_gpu_memory = mem->mapped_to_gpu_memory; is_imported = mem->is_imported; mutex_unlock(&mem->lock); @@ -1657,12 +1570,12 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( pr_debug("Release VA 0x%llx - 0x%llx\n", mem->va, mem->va + bo_size * (1 + mem->aql_queue)); + ret = unreserve_bo_and_vms(&ctx, false, false); + /* Remove from VM internal data structures */ list_for_each_entry_safe(entry, tmp, &mem->attachments, list) kfd_mem_detach(entry); - ret = unreserve_bo_and_vms(&ctx, false, false); - /* Free the sync object */ amdgpu_sync_free(&mem->sync); @@ -1689,21 +1602,18 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( drm_vma_node_revoke(&mem->bo->tbo.base.vma_node, drm_priv); if (mem->dmabuf) dma_buf_put(mem->dmabuf); - mutex_destroy(&mem->lock); - - /* If this releases the last reference, it will end up calling - * amdgpu_amdkfd_release_notify and kfree the mem struct. That's why - * this needs to be the last call here. - */ drm_gem_object_put(&mem->bo->tbo.base); + mutex_destroy(&mem->lock); + kfree(mem); return ret; } int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, bool *table_freed) { + struct amdgpu_device *adev = get_amdgpu_device(kgd); struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); int ret; struct amdgpu_bo *bo; @@ -1830,7 +1740,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( } int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( - struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv) + struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv) { struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); struct amdkfd_process_info *process_info = avm->process_info; @@ -1891,7 +1801,7 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( } int amdgpu_amdkfd_gpuvm_sync_memory( - struct amdgpu_device *adev, struct kgd_mem *mem, bool intr) + struct kgd_dev *kgd, struct kgd_mem *mem, bool intr) { struct amdgpu_sync sync; int ret; @@ -1907,7 +1817,7 @@ int amdgpu_amdkfd_gpuvm_sync_memory( return ret; } -int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd, struct kgd_mem *mem, void **kptr, uint64_t *size) { int ret; @@ -1963,20 +1873,12 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev, return ret; } -void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(struct amdgpu_device *adev, - struct kgd_mem *mem) +int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd, + struct kfd_vm_fault_info *mem) { - struct amdgpu_bo *bo = mem->bo; + struct amdgpu_device *adev; - amdgpu_bo_reserve(bo, true); - amdgpu_bo_kunmap(bo); - amdgpu_bo_unpin(bo); - amdgpu_bo_unreserve(bo); -} - -int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev, - struct kfd_vm_fault_info *mem) -{ + adev = (struct amdgpu_device *)kgd; if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) { *mem = *adev->gmc.vm_fault_info; mb(); @@ -1985,12 +1887,13 @@ int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct amdgpu_device *adev, return 0; } -int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev, +int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd, struct dma_buf *dma_buf, uint64_t va, void *drm_priv, struct kgd_mem **mem, uint64_t *size, uint64_t *mmap_offset) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv); struct drm_gem_object *obj; struct amdgpu_bo *bo; @@ -2140,26 +2043,19 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info, /* Get updated user pages */ ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); if (ret) { - pr_debug("Failed %d to get user pages\n", ret); + pr_debug("%s: Failed to get user pages: %d\n", + __func__, ret); - /* Return -EFAULT bad address error as success. It will - * fail later with a VM fault if the GPU tries to access - * it. Better than hanging indefinitely with stalled - * user mode queues. - * - * Return other error -EBUSY or -ENOMEM to retry restore - */ - if (ret != -EFAULT) - return ret; - } else { - - /* - * FIXME: Cannot ignore the return code, must hold - * notifier_lock - */ - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + /* Return error -EBUSY or -ENOMEM, retry restore */ + return ret; } + /* + * FIXME: Cannot ignore the return code, must hold + * notifier_lock + */ + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + /* Mark the BO as valid unless it was invalidated * again concurrently. */ @@ -2617,9 +2513,11 @@ int amdgpu_amdkfd_remove_gws_from_process(void *info, void *mem) } /* Returns GPU-specific tiling mode information */ -int amdgpu_amdkfd_get_tile_config(struct amdgpu_device *adev, +int amdgpu_amdkfd_get_tile_config(struct kgd_dev *kgd, struct tile_config *config) { + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + config->gb_addr_config = adev->gfx.config.gb_addr_config; config->tile_config_ptr = adev->gfx.config.tile_mode_array; config->num_tile_configs = diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 12a6b1c99c..96b7bb13a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1569,18 +1569,6 @@ void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev, WREG32(adev->bios_scratch_reg_offset + 3, tmp); } -void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev, - u32 backlight_level) -{ - u32 tmp = RREG32(adev->bios_scratch_reg_offset + 2); - - tmp &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK; - tmp |= (backlight_level << ATOM_S2_CURRENT_BL_LEVEL_SHIFT) & - ATOM_S2_CURRENT_BL_LEVEL_MASK; - - WREG32(adev->bios_scratch_reg_offset + 2, tmp); -} - bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev) { u32 tmp = RREG32(adev->bios_scratch_reg_offset + 7); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h index 27e74b1fc2..8cc0222dba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h @@ -185,8 +185,6 @@ bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev); void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock); void amdgpu_atombios_scratch_regs_engine_hung(struct amdgpu_device *adev, bool hung); -void amdgpu_atombios_scratch_regs_set_backlight_level(struct amdgpu_device *adev, - u32 backlight_level); bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev); void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c index 4d4ddf026f..97178b307e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -470,8 +470,8 @@ bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *ade /** * amdgpu_atomfirmware_ras_rom_addr -- Get the RAS EEPROM addr from VBIOS - * @adev: amdgpu_device pointer - * @i2c_address: pointer to u8; if not NULL, will contain + * adev: amdgpu_device pointer + * i2c_address: pointer to u8; if not NULL, will contain * the RAS EEPROM address if the function returns true * * Return true if VBIOS supports RAS EEPROM address reporting, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index d6d986be90..7abe9500c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -11,7 +11,6 @@ #include #include -#include "amdgpu.h" #include "amd_acpi.h" #define AMDGPU_PX_QUIRK_FORCE_ATPX (1 << 0) @@ -166,7 +165,7 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas } /** - * amdgpu_atpx_validate - validate ATPX functions + * amdgpu_atpx_validate_functions - validate ATPX functions * * @atpx: amdgpu atpx struct * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index c16a2704ce..df1f9b88a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -108,7 +108,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_HDMIB: if (amdgpu_connector->use_digital) { - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -116,7 +116,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) break; case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_HDMIA: - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -125,7 +125,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) dig_connector = amdgpu_connector->con_priv; if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || - connector->display_info.is_hdmi) { + drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { if (connector->display_info.bpc) bpc = connector->display_info.bpc; } @@ -149,7 +149,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) break; } - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { /* * Pre DCE-8 hw can't handle > 12 bpc, and more than 12 bpc doesn't make * much sense without support for > 12 bpc framebuffers. RGB 4:4:4 at @@ -315,10 +315,8 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector) if (!amdgpu_connector->edid) { /* some laptops provide a hardcoded edid in rom for LCDs */ if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || - (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) { + (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev); - drm_connector_update_edid_property(connector, amdgpu_connector->edid); - } } } @@ -328,7 +326,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector) kfree(amdgpu_connector->edid); amdgpu_connector->edid = NULL; - drm_connector_update_edid_property(connector, NULL); } static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) @@ -1180,7 +1177,7 @@ static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connector (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || (amdgpu_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) { return MODE_OK; - } else if (connector->display_info.is_hdmi) { + } else if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { /* HDMI 1.3+ supports max clock of 340 Mhz */ if (mode->clock > 340000) return MODE_CLOCK_HIGH; @@ -1472,7 +1469,7 @@ static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { return amdgpu_atombios_dp_mode_valid_helper(connector, mode); } else { - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { /* HDMI 1.3+ supports max clock of 340 Mhz */ if (mode->clock > 340000) return MODE_CLOCK_HIGH; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 06d07502a1..913f9eaa9c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -298,6 +298,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, { s64 time_us, increment_us; u64 free_vram, total_vram, used_vram; + struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); /* Allow a maximum of 200 accumulated ms. This is basically per-IB * throttling. * @@ -314,7 +315,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, } total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size); - used_vram = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr); + used_vram = amdgpu_vram_mgr_usage(vram_man); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; spin_lock(&adev->mm_stats.lock); @@ -361,7 +362,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, if (!amdgpu_gmc_vram_full_visible(&adev->gmc)) { u64 total_vis_vram = adev->gmc.visible_vram_size; u64 used_vis_vram = - amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr); + amdgpu_vram_mgr_vis_usage(vram_man); if (used_vis_vram < total_vis_vram) { u64 free_vis_vram = total_vis_vram - used_vis_vram; @@ -1221,8 +1222,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, if (r) goto error_unlock; - drm_sched_job_arm(&job->base); - /* No memory allocation is allowed while holding the notifier lock. * The lock is held until amdgpu_cs_submit is finished and fence is * added to BOs. @@ -1260,7 +1259,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, trace_amdgpu_cs_ioctl(job); amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket); - drm_sched_entity_push_job(&job->base); + drm_sched_entity_push_job(&job->base, entity); amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 468003583b..e7a010b7ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -43,61 +43,14 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = { [AMDGPU_HW_IP_VCN_JPEG] = 1, }; -bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio) -{ - switch (ctx_prio) { - case AMDGPU_CTX_PRIORITY_UNSET: - case AMDGPU_CTX_PRIORITY_VERY_LOW: - case AMDGPU_CTX_PRIORITY_LOW: - case AMDGPU_CTX_PRIORITY_NORMAL: - case AMDGPU_CTX_PRIORITY_HIGH: - case AMDGPU_CTX_PRIORITY_VERY_HIGH: - return true; - default: - return false; - } -} - -static enum drm_sched_priority -amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio) -{ - switch (ctx_prio) { - case AMDGPU_CTX_PRIORITY_UNSET: - return DRM_SCHED_PRIORITY_UNSET; - - case AMDGPU_CTX_PRIORITY_VERY_LOW: - return DRM_SCHED_PRIORITY_MIN; - - case AMDGPU_CTX_PRIORITY_LOW: - return DRM_SCHED_PRIORITY_MIN; - - case AMDGPU_CTX_PRIORITY_NORMAL: - return DRM_SCHED_PRIORITY_NORMAL; - - case AMDGPU_CTX_PRIORITY_HIGH: - return DRM_SCHED_PRIORITY_HIGH; - - case AMDGPU_CTX_PRIORITY_VERY_HIGH: - return DRM_SCHED_PRIORITY_HIGH; - - /* This should not happen as we sanitized userspace provided priority - * already, WARN if this happens. - */ - default: - WARN(1, "Invalid context priority %d\n", ctx_prio); - return DRM_SCHED_PRIORITY_NORMAL; - } - -} - static int amdgpu_ctx_priority_permit(struct drm_file *filp, - int32_t priority) + enum drm_sched_priority priority) { - if (!amdgpu_ctx_priority_is_valid(priority)) + if (priority < 0 || priority >= DRM_SCHED_PRIORITY_COUNT) return -EINVAL; /* NORMAL and below are accessible by everyone */ - if (priority <= AMDGPU_CTX_PRIORITY_NORMAL) + if (priority <= DRM_SCHED_PRIORITY_NORMAL) return 0; if (capable(CAP_SYS_NICE)) @@ -109,51 +62,26 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp, return -EACCES; } -static enum amdgpu_gfx_pipe_priority amdgpu_ctx_prio_to_compute_prio(int32_t prio) +static enum gfx_pipe_priority amdgpu_ctx_sched_prio_to_compute_prio(enum drm_sched_priority prio) { switch (prio) { - case AMDGPU_CTX_PRIORITY_HIGH: - case AMDGPU_CTX_PRIORITY_VERY_HIGH: + case DRM_SCHED_PRIORITY_HIGH: + case DRM_SCHED_PRIORITY_KERNEL: return AMDGPU_GFX_PIPE_PRIO_HIGH; default: return AMDGPU_GFX_PIPE_PRIO_NORMAL; } } -static enum amdgpu_ring_priority_level amdgpu_ctx_sched_prio_to_ring_prio(int32_t prio) +static unsigned int amdgpu_ctx_prio_sched_to_hw(struct amdgpu_device *adev, + enum drm_sched_priority prio, + u32 hw_ip) { - switch (prio) { - case AMDGPU_CTX_PRIORITY_HIGH: - return AMDGPU_RING_PRIO_1; - case AMDGPU_CTX_PRIORITY_VERY_HIGH: - return AMDGPU_RING_PRIO_2; - default: - return AMDGPU_RING_PRIO_0; - } -} - -static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip) -{ - struct amdgpu_device *adev = ctx->adev; - int32_t ctx_prio; unsigned int hw_prio; - ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ? - ctx->init_priority : ctx->override_priority; - - switch (hw_ip) { - case AMDGPU_HW_IP_COMPUTE: - hw_prio = amdgpu_ctx_prio_to_compute_prio(ctx_prio); - break; - case AMDGPU_HW_IP_VCE: - case AMDGPU_HW_IP_VCN_ENC: - hw_prio = amdgpu_ctx_sched_prio_to_ring_prio(ctx_prio); - break; - default: - hw_prio = AMDGPU_RING_PRIO_DEFAULT; - break; - } - + hw_prio = (hw_ip == AMDGPU_HW_IP_COMPUTE) ? + amdgpu_ctx_sched_prio_to_compute_prio(prio) : + AMDGPU_RING_PRIO_DEFAULT; hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM); if (adev->gpu_sched[hw_ip][hw_prio].num_scheds == 0) hw_prio = AMDGPU_RING_PRIO_DEFAULT; @@ -161,17 +89,15 @@ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip) return hw_prio; } - static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, - const u32 ring) + const u32 ring) { struct amdgpu_device *adev = ctx->adev; struct amdgpu_ctx_entity *entity; struct drm_gpu_scheduler **scheds = NULL, *sched = NULL; unsigned num_scheds = 0; - int32_t ctx_prio; unsigned int hw_prio; - enum drm_sched_priority drm_prio; + enum drm_sched_priority priority; int r; entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs), @@ -179,11 +105,10 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, if (!entity) return -ENOMEM; - ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ? - ctx->init_priority : ctx->override_priority; entity->sequence = 1; - hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip); - drm_prio = amdgpu_ctx_to_drm_sched_prio(ctx_prio); + priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ? + ctx->init_priority : ctx->override_priority; + hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, hw_ip); hw_ip = array_index_nospec(hw_ip, AMDGPU_HW_IP_NUM); scheds = adev->gpu_sched[hw_ip][hw_prio].sched; @@ -199,7 +124,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, num_scheds = 1; } - r = drm_sched_entity_init(&entity->entity, drm_prio, scheds, num_scheds, + r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds, &ctx->guilty); if (r) goto error_free_entity; @@ -214,7 +139,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, } static int amdgpu_ctx_init(struct amdgpu_device *adev, - int32_t priority, + enum drm_sched_priority priority, struct drm_file *filp, struct amdgpu_ctx *ctx) { @@ -236,7 +161,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, ctx->reset_counter_query = ctx->reset_counter; ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter); ctx->init_priority = priority; - ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET; + ctx->override_priority = DRM_SCHED_PRIORITY_UNSET; return 0; } @@ -309,7 +234,7 @@ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance, static int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv, struct drm_file *filp, - int32_t priority, + enum drm_sched_priority priority, uint32_t *id) { struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; @@ -472,19 +397,19 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, { int r; uint32_t id; - int32_t priority; + enum drm_sched_priority priority; union drm_amdgpu_ctx *args = data; struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_fpriv *fpriv = filp->driver_priv; id = args->in.ctx_id; - priority = args->in.priority; + r = amdgpu_to_sched_priority(args->in.priority, &priority); /* For backwards compatibility reasons, we need to accept * ioctls with garbage in the priority field */ - if (!amdgpu_ctx_priority_is_valid(priority)) - priority = AMDGPU_CTX_PRIORITY_NORMAL; + if (r == -EINVAL) + priority = DRM_SCHED_PRIORITY_NORMAL; switch (args->in.op) { case AMDGPU_CTX_OP_ALLOC_CTX: @@ -590,9 +515,9 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, } static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx, - struct amdgpu_ctx_entity *aentity, - int hw_ip, - int32_t priority) + struct amdgpu_ctx_entity *aentity, + int hw_ip, + enum drm_sched_priority priority) { struct amdgpu_device *adev = ctx->adev; unsigned int hw_prio; @@ -600,12 +525,12 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx, unsigned num_scheds; /* set sw priority */ - drm_sched_entity_set_priority(&aentity->entity, - amdgpu_ctx_to_drm_sched_prio(priority)); + drm_sched_entity_set_priority(&aentity->entity, priority); /* set hw priority */ if (hw_ip == AMDGPU_HW_IP_COMPUTE) { - hw_prio = amdgpu_ctx_get_hw_prio(ctx, hw_ip); + hw_prio = amdgpu_ctx_prio_sched_to_hw(adev, priority, + AMDGPU_HW_IP_COMPUTE); hw_prio = array_index_nospec(hw_prio, AMDGPU_RING_PRIO_MAX); scheds = adev->gpu_sched[hw_ip][hw_prio].sched; num_scheds = adev->gpu_sched[hw_ip][hw_prio].num_scheds; @@ -615,14 +540,14 @@ static void amdgpu_ctx_set_entity_priority(struct amdgpu_ctx *ctx, } void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, - int32_t priority) + enum drm_sched_priority priority) { - int32_t ctx_prio; + enum drm_sched_priority ctx_prio; unsigned i, j; ctx->override_priority = priority; - ctx_prio = (ctx->override_priority == AMDGPU_CTX_PRIORITY_UNSET) ? + ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ? ctx->init_priority : ctx->override_priority; for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) { for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h index a44b8b8ed3..14db16bc33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h @@ -47,8 +47,8 @@ struct amdgpu_ctx { spinlock_t ring_lock; struct amdgpu_ctx_entity *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM]; bool preamble_presented; - int32_t init_priority; - int32_t override_priority; + enum drm_sched_priority init_priority; + enum drm_sched_priority override_priority; struct mutex lock; atomic_t guilty; unsigned long ras_counter_ce; @@ -75,8 +75,8 @@ void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx, struct drm_sched_entity *entity, uint64_t seq); -bool amdgpu_ctx_priority_is_valid(int32_t ctx_prio); -void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, int32_t ctx_prio); +void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx, + enum drm_sched_priority priority); int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 25e2e5bf90..ec30d81586 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -35,7 +35,6 @@ #include "amdgpu_rap.h" #include "amdgpu_securedisplay.h" #include "amdgpu_fw_attestation.h" -#include "amdgpu_umr.h" #if defined(CONFIG_DEBUG_FS) @@ -201,145 +200,6 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, return amdgpu_debugfs_process_reg_op(false, f, (char __user *)buf, size, pos); } -static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file) -{ - struct amdgpu_debugfs_regs2_data *rd; - - rd = kzalloc(sizeof *rd, GFP_KERNEL); - if (!rd) - return -ENOMEM; - rd->adev = file_inode(file)->i_private; - file->private_data = rd; - mutex_init(&rd->lock); - - return 0; -} - -static int amdgpu_debugfs_regs2_release(struct inode *inode, struct file *file) -{ - struct amdgpu_debugfs_regs2_data *rd = file->private_data; - mutex_destroy(&rd->lock); - kfree(file->private_data); - return 0; -} - -static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 offset, size_t size, int write_en) -{ - struct amdgpu_debugfs_regs2_data *rd = f->private_data; - struct amdgpu_device *adev = rd->adev; - ssize_t result = 0; - int r; - uint32_t value; - - if (size & 0x3 || offset & 0x3) - return -EINVAL; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - r = amdgpu_virt_enable_access_debugfs(adev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - mutex_lock(&rd->lock); - - if (rd->id.use_grbm) { - if ((rd->id.grbm.sh != 0xFFFFFFFF && rd->id.grbm.sh >= adev->gfx.config.max_sh_per_se) || - (rd->id.grbm.se != 0xFFFFFFFF && rd->id.grbm.se >= adev->gfx.config.max_shader_engines)) { - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - amdgpu_virt_disable_access_debugfs(adev); - mutex_unlock(&rd->lock); - return -EINVAL; - } - mutex_lock(&adev->grbm_idx_mutex); - amdgpu_gfx_select_se_sh(adev, rd->id.grbm.se, - rd->id.grbm.sh, - rd->id.grbm.instance); - } - - if (rd->id.use_srbm) { - mutex_lock(&adev->srbm_mutex); - amdgpu_gfx_select_me_pipe_q(adev, rd->id.srbm.me, rd->id.srbm.pipe, - rd->id.srbm.queue, rd->id.srbm.vmid); - } - - if (rd->id.pg_lock) - mutex_lock(&adev->pm.mutex); - - while (size) { - if (!write_en) { - value = RREG32(offset >> 2); - r = put_user(value, (uint32_t *)buf); - } else { - r = get_user(value, (uint32_t *)buf); - if (!r) - amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value); - } - if (r) { - result = r; - goto end; - } - offset += 4; - size -= 4; - result += 4; - buf += 4; - } -end: - if (rd->id.use_grbm) { - amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); - mutex_unlock(&adev->grbm_idx_mutex); - } - - if (rd->id.use_srbm) { - amdgpu_gfx_select_me_pipe_q(adev, 0, 0, 0, 0); - mutex_unlock(&adev->srbm_mutex); - } - - if (rd->id.pg_lock) - mutex_unlock(&adev->pm.mutex); - - mutex_unlock(&rd->lock); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - - amdgpu_virt_disable_access_debugfs(adev); - return result; -} - -static long amdgpu_debugfs_regs2_ioctl(struct file *f, unsigned int cmd, unsigned long data) -{ - struct amdgpu_debugfs_regs2_data *rd = f->private_data; - int r; - - switch (cmd) { - case AMDGPU_DEBUGFS_REGS2_IOC_SET_STATE: - mutex_lock(&rd->lock); - r = copy_from_user(&rd->id, (struct amdgpu_debugfs_regs2_iocdata *)data, sizeof rd->id); - mutex_unlock(&rd->lock); - return r ? -EINVAL : 0; - default: - return -EINVAL; - } - return 0; -} - -static ssize_t amdgpu_debugfs_regs2_read(struct file *f, char __user *buf, size_t size, loff_t *pos) -{ - return amdgpu_debugfs_regs2_op(f, buf, *pos, size, 0); -} - -static ssize_t amdgpu_debugfs_regs2_write(struct file *f, const char __user *buf, size_t size, loff_t *pos) -{ - return amdgpu_debugfs_regs2_op(f, (char __user *)buf, *pos, size, 1); -} - /** * amdgpu_debugfs_regs_pcie_read - Read from a PCIE register @@ -1152,16 +1012,6 @@ static ssize_t amdgpu_debugfs_gfxoff_read(struct file *f, char __user *buf, return result; } -static const struct file_operations amdgpu_debugfs_regs2_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = amdgpu_debugfs_regs2_ioctl, - .read = amdgpu_debugfs_regs2_read, - .write = amdgpu_debugfs_regs2_write, - .open = amdgpu_debugfs_regs2_open, - .release = amdgpu_debugfs_regs2_release, - .llseek = default_llseek -}; - static const struct file_operations amdgpu_debugfs_regs_fops = { .owner = THIS_MODULE, .read = amdgpu_debugfs_regs_read, @@ -1219,7 +1069,6 @@ static const struct file_operations amdgpu_debugfs_gfxoff_fops = { static const struct file_operations *debugfs_regs[] = { &amdgpu_debugfs_regs_fops, - &amdgpu_debugfs_regs2_fops, &amdgpu_debugfs_regs_didt_fops, &amdgpu_debugfs_regs_pcie_fops, &amdgpu_debugfs_regs_smc_fops, @@ -1232,7 +1081,6 @@ static const struct file_operations *debugfs_regs[] = { static const char *debugfs_regs_names[] = { "amdgpu_regs", - "amdgpu_regs2", "amdgpu_regs_didt", "amdgpu_regs_pcie", "amdgpu_regs_smc", @@ -1279,7 +1127,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) } /* Avoid accidently unparking the sched thread during GPU reset */ - r = down_write_killable(&adev->reset_sem); + r = down_read_killable(&adev->reset_sem); if (r) return r; @@ -1308,7 +1156,7 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) kthread_unpark(ring->sched.thread); } - up_write(&adev->reset_sem); + up_read(&adev->reset_sem); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); @@ -1328,7 +1176,7 @@ static int amdgpu_debugfs_evict_vram(void *data, u64 *val) return r; } - *val = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM); + *val = amdgpu_bo_evict_vram(adev); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); @@ -1341,15 +1189,17 @@ static int amdgpu_debugfs_evict_gtt(void *data, u64 *val) { struct amdgpu_device *adev = (struct amdgpu_device *)data; struct drm_device *dev = adev_to_drm(adev); + struct ttm_resource_manager *man; int r; r = pm_runtime_get_sync(dev->dev); if (r < 0) { - pm_runtime_put_autosuspend(dev->dev); + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); return r; } - *val = amdgpu_ttm_evict_resources(adev, TTM_PL_TT); + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); + *val = ttm_resource_manager_evict_all(&adev->mman.bdev, man); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); @@ -1615,12 +1465,6 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) struct dentry *ent; int r, i; - if (!debugfs_initialized()) - return 0; - - debugfs_create_x32("amdgpu_smu_debug", 0600, root, - &adev->pm.smu_debug_mask); - ent = debugfs_create_file("amdgpu_preempt_ib", 0600, root, adev, &fops_ib_preempt); if (IS_ERR(ent)) { @@ -1659,7 +1503,9 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) if (!ring) continue; - amdgpu_debugfs_ring_init(adev, ring); + if (amdgpu_debugfs_ring_init(adev, ring)) { + DRM_ERROR("Failed to register debugfs file for rings !\n"); + } } amdgpu_ras_debugfs_create_all(adev); @@ -1681,11 +1527,6 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) debugfs_create_blob("amdgpu_vbios", 0444, root, &adev->debugfs_vbios_blob); - adev->debugfs_discovery_blob.data = adev->mman.discovery_bin; - adev->debugfs_discovery_blob.size = adev->mman.discovery_tmr_size; - debugfs_create_blob("amdgpu_discovery", 0444, root, - &adev->debugfs_discovery_blob); - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h index 371a6f0deb..8b641f40fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.h @@ -22,6 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. * */ + /* * Debugfs */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ed077de426..1545884dc7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -126,7 +125,6 @@ const char *amdgpu_asic_name[] = { "DIMGREY_CAVEFISH", "BEIGE_GOBY", "YELLOW_CARP", - "IP DISCOVERY", "LAST", }; @@ -307,7 +305,7 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos, uint64_t last; int idx; - if (!drm_dev_enter(adev_to_drm(adev), &idx)) + if (!drm_dev_enter(&adev->ddev, &idx)) return; BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4)); @@ -332,7 +330,7 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos, } /** - * amdgpu_device_aper_access - access vram by vram aperature + * amdgpu_device_vram_access - access vram by vram aperature * * @adev: amdgpu_device pointer * @pos: offset of the buffer in vram @@ -551,11 +549,11 @@ void amdgpu_device_wreg(struct amdgpu_device *adev, trace_amdgpu_device_wreg(adev->pdev->device, reg, v); } -/** - * amdgpu_mm_wreg_mmio_rlc - write register either with direct/indirect mmio or with RLC path if in range +/* + * amdgpu_mm_wreg_mmio_rlc - write register either with mmio or with RLC path if in range * * this function is invoked only the debugfs register access - */ + * */ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, uint32_t reg, uint32_t v) { @@ -567,8 +565,6 @@ void amdgpu_mm_wreg_mmio_rlc(struct amdgpu_device *adev, adev->gfx.rlc.funcs->is_rlcg_access_range) { if (adev->gfx.rlc.funcs->is_rlcg_access_range(adev, reg)) return adev->gfx.rlc.funcs->sriov_wreg(adev, reg, v, 0, 0); - } else if ((reg * 4) >= adev->rmmio_size) { - adev->pcie_wreg(adev, reg * 4, v); } else { writel(v, ((void __iomem *)adev->rmmio) + (reg * 4)); } @@ -1103,7 +1099,7 @@ static void amdgpu_device_wb_fini(struct amdgpu_device *adev) } /** - * amdgpu_device_wb_init - Init Writeback driver info and allocate memory + * amdgpu_device_wb_init- Init Writeback driver info and allocate memory * * @adev: amdgpu_device pointer * @@ -1450,7 +1446,7 @@ static int amdgpu_device_init_apu_flags(struct amdgpu_device *adev) adev->apu_flags |= AMD_APU_IS_CYAN_SKILLFISH2; break; default: - break; + return -EINVAL; } return 0; @@ -2130,11 +2126,46 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) if (r) return r; break; - default: - r = amdgpu_discovery_set_ip_blocks(adev); + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_ARCTURUS: + case CHIP_RENOIR: + case CHIP_ALDEBARAN: + if (adev->flags & AMD_IS_APU) + adev->family = AMDGPU_FAMILY_RV; + else + adev->family = AMDGPU_FAMILY_AI; + + r = soc15_set_ip_blocks(adev); if (r) return r; break; + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + if (adev->asic_type == CHIP_VANGOGH) + adev->family = AMDGPU_FAMILY_VGH; + else if (adev->asic_type == CHIP_YELLOW_CARP) + adev->family = AMDGPU_FAMILY_YC; + else + adev->family = AMDGPU_FAMILY_NV; + + r = nv_set_ip_blocks(adev); + if (r) + return r; + break; + default: + /* FIXME: not supported yet */ + return -EINVAL; } amdgpu_amdkfd_device_probe(adev); @@ -2319,10 +2350,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) /* need to do gmc hw init early so we can allocate gpu mem */ if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { - /* Try to reserve bad pages early */ - if (amdgpu_sriov_vf(adev)) - amdgpu_virt_exchange_data(adev); - r = amdgpu_device_vram_scratch_init(adev); if (r) { DRM_ERROR("amdgpu_vram_scratch_init failed %d\n", r); @@ -2367,6 +2394,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) if (r) goto init_failed; + r = amdgpu_amdkfd_resume_iommu(adev); + if (r) + goto init_failed; + r = amdgpu_device_ip_hw_init_phase1(adev); if (r) goto init_failed; @@ -2621,10 +2652,11 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) if (r) DRM_ERROR("enable mgpu fan boost failed (%d).\n", r); - /* For passthrough configuration on arcturus and aldebaran, enable special handling SBR */ - if (amdgpu_passthrough(adev) && ((adev->asic_type == CHIP_ARCTURUS && adev->gmc.xgmi.num_physical_nodes > 1)|| - adev->asic_type == CHIP_ALDEBARAN )) - smu_handle_passthrough_sbr(&adev->smu, true); + /* For XGMI + passthrough configuration on arcturus, enable light SBR */ + if (adev->asic_type == CHIP_ARCTURUS && + amdgpu_passthrough(adev) && + adev->gmc.xgmi.num_physical_nodes > 1) + smu_set_light_sbr(&adev->smu, true); if (adev->gmc.xgmi.num_physical_nodes > 1) { mutex_lock(&mgpu_info.mutex); @@ -2663,36 +2695,6 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) return 0; } -/** - * amdgpu_device_smu_fini_early - smu hw_fini wrapper - * - * @adev: amdgpu_device pointer - * - * For ASICs need to disable SMC first - */ -static void amdgpu_device_smu_fini_early(struct amdgpu_device *adev) -{ - int i, r; - - if (adev->ip_versions[GC_HWIP][0] > IP_VERSION(9, 0, 0)) - return; - - for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.hw) - continue; - if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) { - r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev); - /* XXX handle errors */ - if (r) { - DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - } - adev->ip_blocks[i].status.hw = false; - break; - } - } -} - static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) { int i, r; @@ -2713,8 +2715,21 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); - /* Workaroud for ASICs need to disable SMC first */ - amdgpu_device_smu_fini_early(adev); + /* need to disable SMC first */ + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.hw) + continue; + if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) { + r = adev->ip_blocks[i].version->funcs->hw_fini((void *)adev); + /* XXX handle errors */ + if (r) { + DRM_DEBUG("hw_fini of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + } + adev->ip_blocks[i].status.hw = false; + break; + } + } for (i = adev->num_ip_blocks - 1; i >= 0; i--) { if (!adev->ip_blocks[i].status.hw) @@ -2756,6 +2771,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done) amdgpu_virt_release_ras_err_handler_data(adev); + amdgpu_ras_pre_fini(adev); + if (adev->gmc.xgmi.num_physical_nodes > 1) amdgpu_xgmi_remove_device(adev); @@ -3187,28 +3204,12 @@ static void amdgpu_device_detect_sriov_bios(struct amdgpu_device *adev) bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) { switch (asic_type) { -#ifdef CONFIG_DRM_AMDGPU_SI - case CHIP_HAINAN: -#endif - case CHIP_TOPAZ: - /* chips with no display hardware */ - return false; #if defined(CONFIG_DRM_AMD_DC) +#if defined(CONFIG_DRM_AMD_DC_SI) case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: case CHIP_OLAND: - /* - * We have systems in the wild with these ASICs that require - * LVDS and VGA support which is not supported with DC. - * - * Fallback to the non-DC driver here by default so as not to - * cause regressions. - */ -#if defined(CONFIG_DRM_AMD_DC_SI) - return amdgpu_dc > 0; -#else - return false; #endif case CHIP_BONAIRE: case CHIP_KAVERI: @@ -3240,7 +3241,6 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) case CHIP_NAVI14: case CHIP_NAVI12: case CHIP_RENOIR: - case CHIP_CYAN_SKILLFISH: case CHIP_SIENNA_CICHLID: case CHIP_NAVY_FLOUNDER: case CHIP_DIMGREY_CAVEFISH: @@ -3248,15 +3248,13 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) case CHIP_VANGOGH: case CHIP_YELLOW_CARP: #endif - default: return amdgpu_dc != 0; -#else +#endif default: if (amdgpu_dc > 0) DRM_INFO_ONCE("Display Core has been requested via kernel parameter " "but isn't supported by ASIC, ignoring\n"); return false; -#endif } } @@ -3357,8 +3355,6 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) continue; } else if (timeout < 0) { timeout = MAX_SCHEDULE_TIMEOUT; - dev_warn(adev->dev, "lockup timeout disabled"); - add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK); } else { timeout = msecs_to_jiffies(timeout); } @@ -3394,22 +3390,6 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev) return ret; } -/** - * amdgpu_device_check_iommu_direct_map - check if RAM direct mapped to GPU - * - * @adev: amdgpu_device pointer - * - * RAM direct mapped to GPU if IOMMU is not enabled or is pass through mode - */ -static void amdgpu_device_check_iommu_direct_map(struct amdgpu_device *adev) -{ - struct iommu_domain *domain; - - domain = iommu_get_domain_for_dev(adev->dev); - if (!domain || domain->type == IOMMU_DOMAIN_IDENTITY) - adev->ram_is_direct_mapped = true; -} - static const struct attribute *amdgpu_dev_attributes[] = { &dev_attr_product_name.attr, &dev_attr_product_number.attr, @@ -3498,7 +3478,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->psp.mutex); mutex_init(&adev->notifier_lock); - amdgpu_device_init_apu_flags(adev); + r = amdgpu_device_init_apu_flags(adev); + if (r) + return r; r = amdgpu_device_check_arguments(adev); if (r) @@ -3560,6 +3542,17 @@ int amdgpu_device_init(struct amdgpu_device *adev, DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)adev->rmmio_base); DRM_INFO("register mmio size: %u\n", (unsigned)adev->rmmio_size); + /* enable PCIE atomic ops */ + r = pci_enable_atomic_ops_to_root(adev->pdev, + PCI_EXP_DEVCAP2_ATOMIC_COMP32 | + PCI_EXP_DEVCAP2_ATOMIC_COMP64); + if (r) { + adev->have_atomics_support = false; + DRM_INFO("PCIE atomic ops is not supported\n"); + } else { + adev->have_atomics_support = true; + } + amdgpu_device_get_pcie_info(adev); if (amdgpu_mcbp) @@ -3582,26 +3575,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (r) return r; - /* Need to get xgmi info early to decide the reset behavior*/ - if (adev->gmc.xgmi.supported) { - r = adev->gfxhub.funcs->get_xgmi_info(adev); - if (r) - return r; - } - - /* enable PCIE atomic ops */ - if (amdgpu_sriov_vf(adev)) - adev->have_atomics_support = ((struct amd_sriov_msg_pf2vf_info *) - adev->virt.fw_reserve.p_pf2vf)->pcie_atomic_ops_enabled_flags == - (PCI_EXP_DEVCAP2_ATOMIC_COMP32 | PCI_EXP_DEVCAP2_ATOMIC_COMP64); - else - adev->have_atomics_support = - !pci_enable_atomic_ops_to_root(adev->pdev, - PCI_EXP_DEVCAP2_ATOMIC_COMP32 | - PCI_EXP_DEVCAP2_ATOMIC_COMP64); - if (!adev->have_atomics_support) - dev_info(adev->dev, "PCIE atomic ops is not supported\n"); - /* doorbell bar mapping and doorbell index init*/ amdgpu_device_doorbell_init(adev); @@ -3735,6 +3708,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* Get a log2 for easy divisions. */ adev->mm_stats.log2_max_MBps = ilog2(max(1u, max_MBps)); + amdgpu_fbdev_init(adev); + r = amdgpu_pm_sysfs_init(adev); if (r) { adev->pm_sysfs_en = false; @@ -3818,8 +3793,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, queue_delayed_work(system_wq, &mgpu_info.delayed_reset_work, msecs_to_jiffies(AMDGPU_RESUME_MS)); - amdgpu_device_check_iommu_direct_map(adev); - return 0; release_ras_con: @@ -3833,7 +3806,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev) { - /* Clear all CPU mappings pointing to this device */ unmap_mapping_range(adev->ddev.anon_inode->i_mapping, 0, 0, 1); @@ -3854,7 +3826,7 @@ static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev) } /** - * amdgpu_device_fini_hw - tear down the driver + * amdgpu_device_fini - tear down the driver * * @adev: amdgpu_device pointer * @@ -3895,27 +3867,19 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_ucode_sysfs_fini(adev); sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes); - /* disable ras feature must before hw fini */ - amdgpu_ras_pre_fini(adev); - - amdgpu_device_ip_fini_early(adev); + amdgpu_fbdev_fini(adev); amdgpu_irq_fini_hw(adev); - if (adev->mman.initialized) - ttm_device_clear_dma_mappings(&adev->mman.bdev); + amdgpu_device_ip_fini_early(adev); amdgpu_gart_dummy_page_fini(adev); - if (drm_dev_is_unplugged(adev_to_drm(adev))) - amdgpu_device_unmap_mmio(adev); - + amdgpu_device_unmap_mmio(adev); } void amdgpu_device_fini_sw(struct amdgpu_device *adev) { - int idx; - amdgpu_fence_driver_sw_fini(adev); amdgpu_device_ip_fini(adev); release_firmware(adev->firmware.gpu_info_fw); @@ -3940,14 +3904,6 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) vga_client_unregister(adev->pdev); - if (drm_dev_enter(adev_to_drm(adev), &idx)) { - - iounmap(adev->rmmio); - adev->rmmio = NULL; - amdgpu_device_doorbell_fini(adev); - drm_dev_exit(idx); - } - if (IS_ENABLED(CONFIG_PERF_EVENTS)) amdgpu_pmu_fini(adev); if (adev->mman.discovery_bin) @@ -3957,25 +3913,6 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) } -/** - * amdgpu_device_evict_resources - evict device resources - * @adev: amdgpu device object - * - * Evicts all ttm device resources(vram BOs, gart table) from the lru list - * of the vram memory type. Mainly used for evicting device resources - * at suspend time. - * - */ -static void amdgpu_device_evict_resources(struct amdgpu_device *adev) -{ - /* No need to evict vram on APUs for suspend to ram or s2idle */ - if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU)) - return; - - if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM)) - DRM_WARN("evicting device resources failed\n"); - -} /* * Suspend & resume. @@ -4005,7 +3942,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) drm_kms_helper_poll_disable(dev); if (fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); + amdgpu_fbdev_set_suspend(adev, 1); cancel_delayed_work_sync(&adev->delayed_init_work); @@ -4016,11 +3953,17 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) if (!adev->in_s0ix) amdgpu_amdkfd_suspend(adev, adev->in_runpm); - amdgpu_device_evict_resources(adev); + /* evict vram memory */ + amdgpu_bo_evict_vram(adev); amdgpu_fence_driver_hw_fini(adev); amdgpu_device_ip_suspend_phase2(adev); + /* evict remaining vram memory + * This second call to evict vram is to evict the gart page table + * using the CPU. + */ + amdgpu_bo_evict_vram(adev); return 0; } @@ -4077,7 +4020,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) flush_delayed_work(&adev->delayed_init_work); if (fbcon) - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); + amdgpu_fbdev_set_suspend(adev, 0); drm_kms_helper_poll_enable(dev); @@ -4346,11 +4289,6 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, bool from_hypervisor) { int r; - struct amdgpu_hive_info *hive = NULL; - - amdgpu_amdkfd_pre_reset(adev); - - amdgpu_amdkfd_pre_reset(adev); if (from_hypervisor) r = amdgpu_virt_request_full_gpu(adev, true); @@ -4359,12 +4297,16 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, if (r) return r; + amdgpu_amdkfd_pre_reset(adev); + /* Resume IP prior to SMC */ r = amdgpu_device_ip_reinit_early_sriov(adev); if (r) goto error; amdgpu_virt_init_data_exchange(adev); + /* we need recover gart prior to run SMC/CP/SDMA resume */ + amdgpu_gtt_mgr_recover(ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)); r = amdgpu_device_fw_loading(adev); if (r) @@ -4375,19 +4317,9 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, if (r) goto error; - hive = amdgpu_get_xgmi_hive(adev); - /* Update PSP FW topology after reset */ - if (hive && adev->gmc.xgmi.num_physical_nodes > 1) - r = amdgpu_xgmi_update_topology(hive, adev); - - if (hive) - amdgpu_put_xgmi_hive(hive); - - if (!r) { - amdgpu_irq_gpu_reset_resume_helper(adev); - r = amdgpu_ib_ring_tests(adev); - amdgpu_amdkfd_post_reset(adev); - } + amdgpu_irq_gpu_reset_resume_helper(adev); + r = amdgpu_ib_ring_tests(adev); + amdgpu_amdkfd_post_reset(adev); error: if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) { @@ -4450,24 +4382,33 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev) if (amdgpu_gpu_recovery == -1) { switch (adev->asic_type) { -#ifdef CONFIG_DRM_AMDGPU_SI - case CHIP_VERDE: - case CHIP_TAHITI: - case CHIP_PITCAIRN: - case CHIP_OLAND: - case CHIP_HAINAN: -#endif -#ifdef CONFIG_DRM_AMDGPU_CIK - case CHIP_KAVERI: - case CHIP_KABINI: - case CHIP_MULLINS: -#endif - case CHIP_CARRIZO: - case CHIP_STONEY: - case CHIP_CYAN_SKILLFISH: - goto disabled; - default: + case CHIP_BONAIRE: + case CHIP_HAWAII: + case CHIP_TOPAZ: + case CHIP_TONGA: + case CHIP_FIJI: + case CHIP_POLARIS10: + case CHIP_POLARIS11: + case CHIP_POLARIS12: + case CHIP_VEGAM: + case CHIP_VEGA20: + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_RAVEN: + case CHIP_ARCTURUS: + case CHIP_RENOIR: + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_VANGOGH: + case CHIP_ALDEBARAN: break; + default: + goto disabled; } } @@ -4521,7 +4462,7 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev) int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, struct amdgpu_reset_context *reset_context) { - int i, r = 0; + int i, j, r = 0; struct amdgpu_job *job = NULL; bool need_full_reset = test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags); @@ -4543,8 +4484,15 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, /*clear job fence from fence drv to avoid force_completion *leave NULL and vm flush fence in fence drv */ - amdgpu_fence_driver_clear_job_fences(ring); + for (j = 0; j <= ring->fence_drv.num_fences_mask; j++) { + struct dma_fence *old, **ptr; + ptr = &ring->fence_drv.fences[j]; + old = rcu_dereference_protected(*ptr, 1); + if (old && test_bit(AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT, &old->flags)) { + RCU_INIT_POINTER(*ptr, NULL); + } + } /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ amdgpu_fence_driver_force_completion(ring); } @@ -4675,6 +4623,10 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, amdgpu_inc_vram_lost(tmp_adev); } + r = amdgpu_gtt_mgr_recover(ttm_manager_type(&tmp_adev->mman.bdev, TTM_PL_TT)); + if (r) + goto out; + r = amdgpu_device_fw_loading(tmp_adev); if (r) return r; @@ -4700,7 +4652,7 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, if (r) goto out; - drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, false); + amdgpu_fbdev_set_suspend(tmp_adev, 0); /* * The GPU enters bad state once faulty pages @@ -4799,7 +4751,7 @@ static int amdgpu_device_lock_hive_adev(struct amdgpu_device *adev, struct amdgp { struct amdgpu_device *tmp_adev = NULL; - if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { + if (adev->gmc.xgmi.num_physical_nodes > 1) { if (!hive) { dev_err(adev->dev, "Hive is NULL while device has multiple xgmi nodes"); return -ENODEV; @@ -4908,9 +4860,6 @@ static void amdgpu_device_recheck_guilty_jobs( /* clear job's guilty and depend the folowing step to decide the real one */ drm_sched_reset_karma(s_job); - /* for the real bad job, it will be resubmitted twice, adding a dma_fence_get - * to make sure fence is balanced */ - dma_fence_get(s_job->s_fence->parent); drm_sched_resubmit_jobs_ext(&ring->sched, 1); ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout); @@ -4946,7 +4895,6 @@ static void amdgpu_device_recheck_guilty_jobs( /* got the hw fence, signal finished fence */ atomic_dec(ring->sched.score); - dma_fence_put(s_job->s_fence->parent); dma_fence_get(&s_job->s_fence->finished); dma_fence_signal(&s_job->s_fence->finished); dma_fence_put(&s_job->s_fence->finished); @@ -5011,8 +4959,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * We always reset all schedulers for device and all devices for XGMI * hive so that should take care of them too. */ - if (!amdgpu_sriov_vf(adev)) - hive = amdgpu_get_xgmi_hive(adev); + hive = amdgpu_get_xgmi_hive(adev); if (hive) { if (atomic_cmpxchg(&hive->in_reset, 0, 1) != 0) { DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress", @@ -5053,7 +5000,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, * to put adev in the 1st position. */ INIT_LIST_HEAD(&device_list); - if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { + if (adev->gmc.xgmi.num_physical_nodes > 1) { list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) list_add_tail(&tmp_adev->reset_list, &device_list); if (!list_is_first(&adev->reset_list, &device_list)) @@ -5092,7 +5039,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, */ amdgpu_unregister_gpu_instance(tmp_adev); - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); + amdgpu_fbdev_set_suspend(tmp_adev, 1); /* disable ras on ALL IPs */ if (!need_emergency_restart && @@ -5142,7 +5089,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, tmp_vram_lost_counter = atomic_read(&((adev)->vram_lost_counter)); /* Actual ASIC resets if needed.*/ - /* Host driver will handle XGMI hive reset for SRIOV */ + /* TODO Implement XGMI hive reset logic for SRIOV */ if (amdgpu_sriov_vf(adev)) { r = amdgpu_device_reset_sriov(adev, job ? false : true); if (r) @@ -5204,7 +5151,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, list_for_each_entry(tmp_adev, device_list_handle, reset_list) { /* unlock kfd: SRIOV would do it separately */ if (!need_emergency_restart && !amdgpu_sriov_vf(tmp_adev)) - amdgpu_amdkfd_post_reset(tmp_adev); + amdgpu_amdkfd_post_reset(tmp_adev); /* kfd_post_reset will do nothing if kfd device is not initialized, * need to bring up kfd here if it's not be initialized before @@ -5687,42 +5634,3 @@ void amdgpu_device_invalidate_hdp(struct amdgpu_device *adev, amdgpu_asic_invalidate_hdp(adev, ring); } - -/** - * amdgpu_device_halt() - bring hardware to some kind of halt state - * - * @adev: amdgpu_device pointer - * - * Bring hardware to some kind of halt state so that no one can touch it - * any more. It will help to maintain error context when error occurred. - * Compare to a simple hang, the system will keep stable at least for SSH - * access. Then it should be trivial to inspect the hardware state and - * see what's going on. Implemented as following: - * - * 1. drm_dev_unplug() makes device inaccessible to user space(IOCTLs, etc), - * clears all CPU mappings to device, disallows remappings through page faults - * 2. amdgpu_irq_disable_all() disables all interrupts - * 3. amdgpu_fence_driver_hw_fini() signals all HW fences - * 4. set adev->no_hw_access to avoid potential crashes after setp 5 - * 5. amdgpu_device_unmap_mmio() clears all MMIO mappings - * 6. pci_disable_device() and pci_wait_for_pending_transaction() - * flush any in flight DMA operations - */ -void amdgpu_device_halt(struct amdgpu_device *adev) -{ - struct pci_dev *pdev = adev->pdev; - struct drm_device *ddev = adev_to_drm(adev); - - drm_dev_unplug(ddev); - - amdgpu_irq_disable_all(adev); - - amdgpu_fence_driver_hw_fini(adev); - - adev->no_hw_access = true; - - amdgpu_device_unmap_mmio(adev); - - pci_disable_device(pdev); - pci_wait_for_pending_transaction(pdev); -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h index 6b25837955..52488bb451 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_df.h @@ -52,7 +52,6 @@ struct amdgpu_df_funcs { uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val); void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val, uint32_t ficadl_val, uint32_t ficadh_val); - bool (*query_ras_poison_mode)(struct amdgpu_device *adev); }; struct amdgpu_df { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 81bfee978b..a919f5daac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -21,59 +21,16 @@ * */ -#include - #include "amdgpu.h" #include "amdgpu_discovery.h" #include "soc15_hw_ip.h" #include "discovery.h" -#include "soc15.h" -#include "gfx_v9_0.h" -#include "gmc_v9_0.h" -#include "df_v1_7.h" -#include "df_v3_6.h" -#include "nbio_v6_1.h" -#include "nbio_v7_0.h" -#include "nbio_v7_4.h" -#include "hdp_v4_0.h" -#include "vega10_ih.h" -#include "vega20_ih.h" -#include "sdma_v4_0.h" -#include "uvd_v7_0.h" -#include "vce_v4_0.h" -#include "vcn_v1_0.h" -#include "vcn_v2_5.h" -#include "jpeg_v2_5.h" -#include "smuio_v9_0.h" -#include "gmc_v10_0.h" -#include "gfxhub_v2_0.h" -#include "mmhub_v2_0.h" -#include "nbio_v2_3.h" -#include "nbio_v7_2.h" -#include "hdp_v5_0.h" -#include "nv.h" -#include "navi10_ih.h" -#include "gfx_v10_0.h" -#include "sdma_v5_0.h" -#include "sdma_v5_2.h" -#include "vcn_v2_0.h" -#include "jpeg_v2_0.h" -#include "vcn_v3_0.h" -#include "jpeg_v3_0.h" -#include "amdgpu_vkms.h" -#include "mes_v10_1.h" -#include "smuio_v11_0.h" -#include "smuio_v11_0_6.h" -#include "smuio_v13_0.h" - -#define FIRMWARE_IP_DISCOVERY "amdgpu/ip_discovery.bin" -MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY); - #define mmRCC_CONFIG_MEMSIZE 0xde3 #define mmMM_INDEX 0x0 #define mmMM_INDEX_HI 0x6 #define mmMM_DATA 0x1 +#define HW_ID_MAX 300 static const char *hw_id_names[HW_ID_MAX] = { [MP1_HWID] = "MP1", @@ -109,8 +66,6 @@ static const char *hw_id_names[HW_ID_MAX] = { [HDP_HWID] = "HDP", [SDMA0_HWID] = "SDMA0", [SDMA1_HWID] = "SDMA1", - [SDMA2_HWID] = "SDMA2", - [SDMA3_HWID] = "SDMA3", [ISP_HWID] = "ISP", [DBGU_IO_HWID] = "DBGU_IO", [DF_HWID] = "DF", @@ -158,8 +113,6 @@ static int hw_id_map[MAX_HWIP] = { [HDP_HWIP] = HDP_HWID, [SDMA0_HWIP] = SDMA0_HWID, [SDMA1_HWIP] = SDMA1_HWID, - [SDMA2_HWIP] = SDMA2_HWID, - [SDMA3_HWIP] = SDMA3_HWID, [MMHUB_HWIP] = MMHUB_HWID, [ATHUB_HWIP] = ATHUB_HWID, [NBIO_HWIP] = NBIF_HWID, @@ -176,11 +129,9 @@ static int hw_id_map[MAX_HWIP] = { [THM_HWIP] = THM_HWID, [CLK_HWIP] = CLKA_HWID, [UMC_HWIP] = UMC_HWID, - [XGMI_HWIP] = XGMI_HWID, - [DCI_HWIP] = DCI_HWID, }; -static int amdgpu_discovery_read_binary_from_vram(struct amdgpu_device *adev, uint8_t *binary) +static int amdgpu_discovery_read_binary(struct amdgpu_device *adev, uint8_t *binary) { uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET; @@ -190,34 +141,6 @@ static int amdgpu_discovery_read_binary_from_vram(struct amdgpu_device *adev, ui return 0; } -static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, uint8_t *binary) -{ - const struct firmware *fw; - const char *fw_name; - int r; - - switch (amdgpu_discovery) { - case 2: - fw_name = FIRMWARE_IP_DISCOVERY; - break; - default: - dev_warn(adev->dev, "amdgpu_discovery is not set properly\n"); - return -EINVAL; - } - - r = request_firmware(&fw, fw_name, adev->dev); - if (r) { - dev_err(adev->dev, "can't load firmware \"%s\"\n", - fw_name); - return r; - } - - memcpy((u8 *)binary, (u8 *)fw->data, adev->mman.discovery_tmr_size); - release_firmware(fw); - - return 0; -} - static uint16_t amdgpu_discovery_calculate_checksum(uint8_t *data, uint32_t size) { uint16_t checksum = 0; @@ -235,38 +158,6 @@ static inline bool amdgpu_discovery_verify_checksum(uint8_t *data, uint32_t size return !!(amdgpu_discovery_calculate_checksum(data, size) == expected); } -static inline bool amdgpu_discovery_verify_binary_signature(uint8_t *binary) -{ - struct binary_header *bhdr; - bhdr = (struct binary_header *)binary; - - return (le32_to_cpu(bhdr->binary_signature) == BINARY_SIGNATURE); -} - -static void amdgpu_discovery_harvest_config_quirk(struct amdgpu_device *adev) -{ - /* - * So far, apply this quirk only on those Navy Flounder boards which - * have a bad harvest table of VCN config. - */ - if ((adev->ip_versions[UVD_HWIP][1] == IP_VERSION(3, 0, 1)) && - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 2))) { - switch (adev->pdev->revision) { - case 0xC1: - case 0xC2: - case 0xC3: - case 0xC5: - case 0xC7: - case 0xCF: - case 0xDF: - adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1; - break; - default: - break; - } - } -} - static int amdgpu_discovery_init(struct amdgpu_device *adev) { struct table_info *info; @@ -283,40 +174,28 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) if (!adev->mman.discovery_bin) return -ENOMEM; - r = amdgpu_discovery_read_binary_from_vram(adev, adev->mman.discovery_bin); + r = amdgpu_discovery_read_binary(adev, adev->mman.discovery_bin); if (r) { - dev_err(adev->dev, "failed to read ip discovery binary from vram\n"); - r = -EINVAL; + DRM_ERROR("failed to read ip discovery binary\n"); goto out; } - if(!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) { - dev_warn(adev->dev, "get invalid ip discovery binary signature from vram\n"); - /* retry read ip discovery binary from file */ - r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin); - if (r) { - dev_err(adev->dev, "failed to read ip discovery binary from file\n"); - r = -EINVAL; - goto out; - } - /* check the ip discovery binary signature */ - if(!amdgpu_discovery_verify_binary_signature(adev->mman.discovery_bin)) { - dev_warn(adev->dev, "get invalid ip discovery binary signature from file\n"); - r = -EINVAL; - goto out; - } - } - bhdr = (struct binary_header *)adev->mman.discovery_bin; + if (le32_to_cpu(bhdr->binary_signature) != BINARY_SIGNATURE) { + DRM_ERROR("invalid ip discovery binary signature\n"); + r = -EINVAL; + goto out; + } + offset = offsetof(struct binary_header, binary_checksum) + sizeof(bhdr->binary_checksum); - size = le16_to_cpu(bhdr->binary_size) - offset; - checksum = le16_to_cpu(bhdr->binary_checksum); + size = bhdr->binary_size - offset; + checksum = bhdr->binary_checksum; if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, size, checksum)) { - dev_err(adev->dev, "invalid ip discovery binary checksum\n"); + DRM_ERROR("invalid ip discovery binary checksum\n"); r = -EINVAL; goto out; } @@ -327,14 +206,14 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + offset); if (le32_to_cpu(ihdr->signature) != DISCOVERY_TABLE_SIGNATURE) { - dev_err(adev->dev, "invalid ip discovery data table signature\n"); + DRM_ERROR("invalid ip discovery data table signature\n"); r = -EINVAL; goto out; } if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, - le16_to_cpu(ihdr->size), checksum)) { - dev_err(adev->dev, "invalid ip discovery data table checksum\n"); + ihdr->size, checksum)) { + DRM_ERROR("invalid ip discovery data table checksum\n"); r = -EINVAL; goto out; } @@ -345,8 +224,8 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) ghdr = (struct gpu_info_header *)(adev->mman.discovery_bin + offset); if (!amdgpu_discovery_verify_checksum(adev->mman.discovery_bin + offset, - le32_to_cpu(ghdr->size), checksum)) { - dev_err(adev->dev, "invalid gc data table checksum\n"); + ghdr->size, checksum)) { + DRM_ERROR("invalid gc data table checksum\n"); r = -EINVAL; goto out; } @@ -366,22 +245,6 @@ void amdgpu_discovery_fini(struct amdgpu_device *adev) adev->mman.discovery_bin = NULL; } -static int amdgpu_discovery_validate_ip(const struct ip *ip) -{ - if (ip->number_instance >= HWIP_MAX_INSTANCE) { - DRM_ERROR("Unexpected number_instance (%d) from ip discovery blob\n", - ip->number_instance); - return -EINVAL; - } - if (le16_to_cpu(ip->hw_id) >= HW_ID_MAX) { - DRM_ERROR("Unexpected hw_id (%d) from ip discovery blob\n", - le16_to_cpu(ip->hw_id)); - return -EINVAL; - } - - return 0; -} - int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) { struct binary_header *bhdr; @@ -427,10 +290,6 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) for (j = 0; j < num_ips; j++) { ip = (struct ip *)(adev->mman.discovery_bin + ip_offset); - - if (amdgpu_discovery_validate_ip(ip)) - goto next_ip; - num_base_address = ip->num_base_address; DRM_DEBUG("%s(%d) #%d v%d.%d.%d:\n", @@ -440,23 +299,8 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) ip->major, ip->minor, ip->revision); - if (le16_to_cpu(ip->hw_id) == VCN_HWID) { - /* Bit [5:0]: original revision value - * Bit [7:6]: en/decode capability: - * 0b00 : VCN function normally - * 0b10 : encode is disabled - * 0b01 : decode is disabled - */ - adev->vcn.vcn_config[adev->vcn.num_vcn_inst] = - ip->revision & 0xc0; - ip->revision &= ~0xc0; + if (le16_to_cpu(ip->hw_id) == VCN_HWID) adev->vcn.num_vcn_inst++; - } - if (le16_to_cpu(ip->hw_id) == SDMA0_HWID || - le16_to_cpu(ip->hw_id) == SDMA1_HWID || - le16_to_cpu(ip->hw_id) == SDMA2_HWID || - le16_to_cpu(ip->hw_id) == SDMA3_HWID) - adev->sdma.num_instances++; for (k = 0; k < num_base_address; k++) { /* @@ -473,21 +317,10 @@ int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) hw_id_names[le16_to_cpu(ip->hw_id)]); adev->reg_offset[hw_ip][ip->number_instance] = ip->base_address; - /* Instance support is somewhat inconsistent. - * SDMA is a good example. Sienna cichlid has 4 total - * SDMA instances, each enumerated separately (HWIDs - * 42, 43, 68, 69). Arcturus has 8 total SDMA instances, - * but they are enumerated as multiple instances of the - * same HWIDs (4x HWID 42, 4x HWID 43). UMC is another - * example. On most chips there are multiple instances - * with the same HWID. - */ - adev->ip_versions[hw_ip][ip->number_instance] = - IP_VERSION(ip->major, ip->minor, ip->revision); } + } -next_ip: ip_offset += sizeof(*ip) + 4 * (ip->num_base_address - 1); } } @@ -543,6 +376,14 @@ int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, int n return -EINVAL; } + +int amdgpu_discovery_get_vcn_version(struct amdgpu_device *adev, int vcn_instance, + int *major, int *minor, int *revision) +{ + return amdgpu_discovery_get_ip_version(adev, VCN_HWID, + vcn_instance, major, minor, revision); +} + void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) { struct binary_header *bhdr; @@ -554,16 +395,12 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) le16_to_cpu(bhdr->table_list[HARVEST_INFO].offset)); for (i = 0; i < 32; i++) { - if (le16_to_cpu(harvest_info->list[i].hw_id) == 0) + if (le32_to_cpu(harvest_info->list[i].hw_id) == 0) break; - switch (le16_to_cpu(harvest_info->list[i].hw_id)) { + switch (le32_to_cpu(harvest_info->list[i].hw_id)) { case VCN_HWID: vcn_harvest_count++; - if (harvest_info->list[i].number_instance == 0) - adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0; - else - adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN1; break; case DMU_HWID: adev->harvest_ip_mask |= AMD_HARVEST_IP_DMU_MASK; @@ -572,20 +409,10 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev) break; } } - - amdgpu_discovery_harvest_config_quirk(adev); - if (vcn_harvest_count == adev->vcn.num_vcn_inst) { adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK; adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK; } - if ((adev->pdev->device == 0x731E && - (adev->pdev->revision == 0xC6 || adev->pdev->revision == 0xC7)) || - (adev->pdev->device == 0x7340 && adev->pdev->revision == 0xC9) || - (adev->pdev->device == 0x7360 && adev->pdev->revision == 0xC7)) { - adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK; - adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK; - } } union gc_info { @@ -655,791 +482,3 @@ int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev) } return 0; } - -static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev) -{ - /* what IP to use for this? */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 4, 2): - amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); - break; - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 3): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - amdgpu_device_ip_block_add(adev, &nv_common_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add common ip block(GC_HWIP:0x%x)\n", - adev->ip_versions[GC_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev) -{ - /* use GC or MMHUB IP version */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 4, 2): - amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); - break; - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 3): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add gmc ip block(GC_HWIP:0x%x)\n", - adev->ip_versions[GC_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_ih_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[OSSSYS_HWIP][0]) { - case IP_VERSION(4, 0, 0): - case IP_VERSION(4, 0, 1): - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - case IP_VERSION(4, 3, 0): - amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); - break; - case IP_VERSION(4, 2, 0): - case IP_VERSION(4, 2, 1): - case IP_VERSION(4, 4, 0): - amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); - break; - case IP_VERSION(5, 0, 0): - case IP_VERSION(5, 0, 1): - case IP_VERSION(5, 0, 2): - case IP_VERSION(5, 0, 3): - case IP_VERSION(5, 2, 0): - case IP_VERSION(5, 2, 1): - amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add ih ip block(OSSSYS_HWIP:0x%x)\n", - adev->ip_versions[OSSSYS_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(9, 0, 0): - amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); - break; - case IP_VERSION(10, 0, 0): - case IP_VERSION(10, 0, 1): - amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block); - break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 2): - case IP_VERSION(11, 0, 4): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - case IP_VERSION(11, 5, 0): - amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); - break; - case IP_VERSION(11, 0, 8): - amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block); - break; - case IP_VERSION(11, 0, 3): - case IP_VERSION(12, 0, 1): - amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block); - break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 2): - case IP_VERSION(13, 0, 3): - amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add psp ip block(MP0_HWIP:0x%x)\n", - adev->ip_versions[MP0_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(9, 0, 0): - case IP_VERSION(10, 0, 0): - case IP_VERSION(10, 0, 1): - case IP_VERSION(11, 0, 2): - if (adev->asic_type == CHIP_ARCTURUS) - amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); - else - amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); - break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 8): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - case IP_VERSION(11, 5, 0): - amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); - break; - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): - amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block); - break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 2): - case IP_VERSION(13, 0, 3): - amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add smu ip block(MP1_HWIP:0x%x)\n", - adev->ip_versions[MP1_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev) -{ - if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) { - amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); -#if defined(CONFIG_DRM_AMD_DC) - } else if (adev->ip_versions[DCE_HWIP][0]) { - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 3): - case IP_VERSION(2, 1, 0): - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 2): - case IP_VERSION(3, 0, 3): - case IP_VERSION(3, 0, 1): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - amdgpu_device_ip_block_add(adev, &dm_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add dm ip block(DCE_HWIP:0x%x)\n", - adev->ip_versions[DCE_HWIP][0]); - return -EINVAL; - } - } else if (adev->ip_versions[DCI_HWIP][0]) { - switch (adev->ip_versions[DCI_HWIP][0]) { - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): - case IP_VERSION(12, 1, 0): - amdgpu_device_ip_block_add(adev, &dm_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add dm ip block(DCI_HWIP:0x%x)\n", - adev->ip_versions[DCI_HWIP][0]); - return -EINVAL; - } -#endif - } - return 0; -} - -static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 4, 2): - amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); - break; - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): - amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add gfx ip block(GC_HWIP:0x%x)\n", - adev->ip_versions[GC_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): - case IP_VERSION(4, 0, 1): - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - case IP_VERSION(4, 1, 2): - case IP_VERSION(4, 2, 0): - case IP_VERSION(4, 2, 2): - case IP_VERSION(4, 4, 0): - amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); - break; - case IP_VERSION(5, 0, 0): - case IP_VERSION(5, 0, 1): - case IP_VERSION(5, 0, 2): - case IP_VERSION(5, 0, 5): - amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); - break; - case IP_VERSION(5, 2, 0): - case IP_VERSION(5, 2, 2): - case IP_VERSION(5, 2, 4): - case IP_VERSION(5, 2, 5): - case IP_VERSION(5, 2, 3): - case IP_VERSION(5, 2, 1): - amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add sdma ip block(SDMA0_HWIP:0x%x)\n", - adev->ip_versions[SDMA0_HWIP][0]); - return -EINVAL; - } - return 0; -} - -static int amdgpu_discovery_set_mm_ip_blocks(struct amdgpu_device *adev) -{ - if (adev->ip_versions[VCE_HWIP][0]) { - switch (adev->ip_versions[UVD_HWIP][0]) { - case IP_VERSION(7, 0, 0): - case IP_VERSION(7, 2, 0): - /* UVD is not supported on vega20 SR-IOV */ - if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) - amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add uvd v7 ip block(UVD_HWIP:0x%x)\n", - adev->ip_versions[UVD_HWIP][0]); - return -EINVAL; - } - switch (adev->ip_versions[VCE_HWIP][0]) { - case IP_VERSION(4, 0, 0): - case IP_VERSION(4, 1, 0): - /* VCE is not supported on vega20 SR-IOV */ - if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) - amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add VCE v4 ip block(VCE_HWIP:0x%x)\n", - adev->ip_versions[VCE_HWIP][0]); - return -EINVAL; - } - } else { - switch (adev->ip_versions[UVD_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block); - break; - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 2, 0): - amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); - if (!amdgpu_sriov_vf(adev)) - amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); - break; - case IP_VERSION(2, 0, 3): - break; - case IP_VERSION(2, 5, 0): - amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); - amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block); - break; - case IP_VERSION(2, 6, 0): - amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block); - amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block); - break; - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 16): - case IP_VERSION(3, 1, 1): - case IP_VERSION(3, 0, 2): - case IP_VERSION(3, 0, 192): - amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); - if (!amdgpu_sriov_vf(adev)) - amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); - break; - case IP_VERSION(3, 0, 33): - amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); - break; - default: - dev_err(adev->dev, - "Failed to add vcn/jpeg ip block(UVD_HWIP:0x%x)\n", - adev->ip_versions[UVD_HWIP][0]); - return -EINVAL; - } - } - return 0; -} - -static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev) -{ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 3): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); - break; - default: - break; - } - return 0; -} - -int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) -{ - int r; - - switch (adev->asic_type) { - case CHIP_VEGA10: - vega10_reg_base_init(adev); - adev->sdma.num_instances = 2; - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 1, 0); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 0, 0); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 0, 1); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0); - adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 0); - break; - case CHIP_VEGA12: - vega10_reg_base_init(adev); - adev->sdma.num_instances = 2; - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 3, 0); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 3, 0); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 0, 1); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 0, 1); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 0, 1); - adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 0, 1); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 5, 0); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(6, 2, 0); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 0); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(9, 0, 0); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(9, 0, 1); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 1); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 0, 0); - adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 0, 0); - adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 0, 1); - break; - case CHIP_RAVEN: - vega10_reg_base_init(adev); - adev->sdma.num_instances = 1; - adev->vcn.num_vcn_inst = 1; - if (adev->apu_flags & AMD_APU_IS_RAVEN2) { - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 2, 0); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 2, 0); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 1); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 1); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 1); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 1); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 1); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 5, 0); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 1); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 1); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 1, 0); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 1); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 2, 2); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 1); - adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 1); - } else { - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 1, 0); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 1, 0); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 1, 0); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 1, 0); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 1, 0); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(2, 1, 0); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 0, 0); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(7, 0, 0); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(10, 0, 0); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(10, 0, 0); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(10, 0, 0); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(10, 0, 0); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 1, 0); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(1, 0, 0); - adev->ip_versions[DCE_HWIP][0] = IP_VERSION(1, 0, 0); - } - break; - case CHIP_VEGA20: - vega20_reg_base_init(adev); - adev->sdma.num_instances = 2; - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 0); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 0); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 0); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 0); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 0); - adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 0); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 0); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 0); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 1); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 2); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 2); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 2); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 0); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(7, 2, 0); - adev->ip_versions[UVD_HWIP][1] = IP_VERSION(7, 2, 0); - adev->ip_versions[VCE_HWIP][0] = IP_VERSION(4, 1, 0); - adev->ip_versions[DCI_HWIP][0] = IP_VERSION(12, 1, 0); - break; - case CHIP_ARCTURUS: - arct_reg_base_init(adev); - adev->sdma.num_instances = 8; - adev->vcn.num_vcn_inst = 2; - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 1); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 1); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 2, 1); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 2, 1); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][0] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][1] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][2] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][3] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][4] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][5] = IP_VERSION(4, 2, 2); - adev->ip_versions[SDMA1_HWIP][6] = IP_VERSION(4, 2, 2); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 1); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 1); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 1, 2); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(11, 0, 4); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(11, 0, 2); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(11, 0, 3); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(11, 0, 3); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 1); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 5, 0); - adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 5, 0); - break; - case CHIP_ALDEBARAN: - aldebaran_reg_base_init(adev); - adev->sdma.num_instances = 5; - adev->vcn.num_vcn_inst = 2; - adev->ip_versions[MMHUB_HWIP][0] = IP_VERSION(9, 4, 2); - adev->ip_versions[ATHUB_HWIP][0] = IP_VERSION(9, 4, 2); - adev->ip_versions[OSSSYS_HWIP][0] = IP_VERSION(4, 4, 0); - adev->ip_versions[HDP_HWIP][0] = IP_VERSION(4, 4, 0); - adev->ip_versions[SDMA0_HWIP][0] = IP_VERSION(4, 4, 0); - adev->ip_versions[SDMA0_HWIP][1] = IP_VERSION(4, 4, 0); - adev->ip_versions[SDMA0_HWIP][2] = IP_VERSION(4, 4, 0); - adev->ip_versions[SDMA0_HWIP][3] = IP_VERSION(4, 4, 0); - adev->ip_versions[SDMA0_HWIP][4] = IP_VERSION(4, 4, 0); - adev->ip_versions[DF_HWIP][0] = IP_VERSION(3, 6, 2); - adev->ip_versions[NBIO_HWIP][0] = IP_VERSION(7, 4, 4); - adev->ip_versions[UMC_HWIP][0] = IP_VERSION(6, 7, 0); - adev->ip_versions[MP0_HWIP][0] = IP_VERSION(13, 0, 2); - adev->ip_versions[MP1_HWIP][0] = IP_VERSION(13, 0, 2); - adev->ip_versions[THM_HWIP][0] = IP_VERSION(13, 0, 2); - adev->ip_versions[SMUIO_HWIP][0] = IP_VERSION(13, 0, 2); - adev->ip_versions[GC_HWIP][0] = IP_VERSION(9, 4, 2); - adev->ip_versions[UVD_HWIP][0] = IP_VERSION(2, 6, 0); - adev->ip_versions[UVD_HWIP][1] = IP_VERSION(2, 6, 0); - adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0); - break; - default: - r = amdgpu_discovery_reg_base_init(adev); - if (r) - return -EINVAL; - - amdgpu_discovery_harvest_ip(adev); - - if (!adev->mman.discovery_bin) { - DRM_ERROR("ip discovery uninitialized\n"); - return -EINVAL; - } - break; - } - - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 4, 2): - adev->family = AMDGPU_FAMILY_AI; - break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 3, 0): - adev->family = AMDGPU_FAMILY_RV; - break; - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - adev->family = AMDGPU_FAMILY_NV; - break; - case IP_VERSION(10, 3, 1): - adev->family = AMDGPU_FAMILY_VGH; - break; - case IP_VERSION(10, 3, 3): - adev->family = AMDGPU_FAMILY_YC; - break; - default: - return -EINVAL; - } - - if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(4, 8, 0)) - adev->gmc.xgmi.supported = true; - - /* set NBIO version */ - switch (adev->ip_versions[NBIO_HWIP][0]) { - case IP_VERSION(6, 1, 0): - case IP_VERSION(6, 2, 0): - adev->nbio.funcs = &nbio_v6_1_funcs; - adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg; - break; - case IP_VERSION(7, 0, 0): - case IP_VERSION(7, 0, 1): - case IP_VERSION(2, 5, 0): - adev->nbio.funcs = &nbio_v7_0_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg; - break; - case IP_VERSION(7, 4, 0): - case IP_VERSION(7, 4, 1): - adev->nbio.funcs = &nbio_v7_4_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; - break; - case IP_VERSION(7, 4, 4): - adev->nbio.funcs = &nbio_v7_4_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg_ald; - break; - case IP_VERSION(7, 2, 0): - case IP_VERSION(7, 2, 1): - case IP_VERSION(7, 5, 0): - adev->nbio.funcs = &nbio_v7_2_funcs; - adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg; - break; - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 3, 0): - case IP_VERSION(2, 3, 1): - case IP_VERSION(2, 3, 2): - adev->nbio.funcs = &nbio_v2_3_funcs; - adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; - break; - case IP_VERSION(3, 3, 0): - case IP_VERSION(3, 3, 1): - case IP_VERSION(3, 3, 2): - case IP_VERSION(3, 3, 3): - adev->nbio.funcs = &nbio_v2_3_funcs; - adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg_sc; - break; - default: - break; - } - - switch (adev->ip_versions[HDP_HWIP][0]) { - case IP_VERSION(4, 0, 0): - case IP_VERSION(4, 0, 1): - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - case IP_VERSION(4, 1, 2): - case IP_VERSION(4, 2, 0): - case IP_VERSION(4, 2, 1): - case IP_VERSION(4, 4, 0): - adev->hdp.funcs = &hdp_v4_0_funcs; - break; - case IP_VERSION(5, 0, 0): - case IP_VERSION(5, 0, 1): - case IP_VERSION(5, 0, 2): - case IP_VERSION(5, 0, 3): - case IP_VERSION(5, 0, 4): - case IP_VERSION(5, 2, 0): - adev->hdp.funcs = &hdp_v5_0_funcs; - break; - default: - break; - } - - switch (adev->ip_versions[DF_HWIP][0]) { - case IP_VERSION(3, 6, 0): - case IP_VERSION(3, 6, 1): - case IP_VERSION(3, 6, 2): - adev->df.funcs = &df_v3_6_funcs; - break; - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 5, 0): - case IP_VERSION(3, 5, 1): - case IP_VERSION(3, 5, 2): - adev->df.funcs = &df_v1_7_funcs; - break; - default: - break; - } - - switch (adev->ip_versions[SMUIO_HWIP][0]) { - case IP_VERSION(9, 0, 0): - case IP_VERSION(9, 0, 1): - case IP_VERSION(10, 0, 0): - case IP_VERSION(10, 0, 1): - case IP_VERSION(10, 0, 2): - adev->smuio.funcs = &smuio_v9_0_funcs; - break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 2): - case IP_VERSION(11, 0, 3): - case IP_VERSION(11, 0, 4): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 8): - adev->smuio.funcs = &smuio_v11_0_funcs; - break; - case IP_VERSION(11, 0, 6): - case IP_VERSION(11, 0, 10): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 5, 0): - case IP_VERSION(13, 0, 1): - adev->smuio.funcs = &smuio_v11_0_6_funcs; - break; - case IP_VERSION(13, 0, 2): - adev->smuio.funcs = &smuio_v13_0_funcs; - break; - default: - break; - } - - r = amdgpu_discovery_set_common_ip_blocks(adev); - if (r) - return r; - - r = amdgpu_discovery_set_gmc_ip_blocks(adev); - if (r) - return r; - - /* For SR-IOV, PSP needs to be initialized before IH */ - if (amdgpu_sriov_vf(adev)) { - r = amdgpu_discovery_set_psp_ip_blocks(adev); - if (r) - return r; - r = amdgpu_discovery_set_ih_ip_blocks(adev); - if (r) - return r; - } else { - r = amdgpu_discovery_set_ih_ip_blocks(adev); - if (r) - return r; - - if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { - r = amdgpu_discovery_set_psp_ip_blocks(adev); - if (r) - return r; - } - } - - if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { - r = amdgpu_discovery_set_smu_ip_blocks(adev); - if (r) - return r; - } - - r = amdgpu_discovery_set_display_ip_blocks(adev); - if (r) - return r; - - r = amdgpu_discovery_set_gc_ip_blocks(adev); - if (r) - return r; - - r = amdgpu_discovery_set_sdma_ip_blocks(adev); - if (r) - return r; - - if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && - !amdgpu_sriov_vf(adev)) { - r = amdgpu_discovery_set_smu_ip_blocks(adev); - if (r) - return r; - } - - r = amdgpu_discovery_set_mm_ip_blocks(adev); - if (r) - return r; - - if (adev->enable_mes) { - r = amdgpu_discovery_set_mes_ip_blocks(adev); - if (r) - return r; - } - - return 0; -} - diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h index 14537cec19..48e6b88cfd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h @@ -33,7 +33,8 @@ void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev); int amdgpu_discovery_get_ip_version(struct amdgpu_device *adev, int hw_id, int number_instance, int *major, int *minor, int *revision); +int amdgpu_discovery_get_vcn_version(struct amdgpu_device *adev, int vcn_instance, + int *major, int *minor, int *revision); int amdgpu_discovery_get_gfx_info(struct amdgpu_device *adev); -int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev); #endif /* __AMDGPU_DISCOVERY__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index c4387b3822..dc50c05f23 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -83,6 +83,9 @@ static void amdgpu_display_flip_work_func(struct work_struct *__work) unsigned i; int vpos, hpos; + if (amdgpu_display_flip_handle_fence(work, &work->excl)) + return; + for (i = 0; i < work->shared_count; ++i) if (amdgpu_display_flip_handle_fence(work, &work->shared[i])) return; @@ -200,7 +203,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, goto unpin; } - r = dma_resv_get_fences(new_abo->tbo.base.resv, NULL, + r = dma_resv_get_fences(new_abo->tbo.base.resv, &work->excl, &work->shared_count, &work->shared); if (unlikely(r != 0)) { DRM_ERROR("failed to get fences for buffer\n"); @@ -250,6 +253,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, cleanup: amdgpu_bo_unref(&work->old_abo); + dma_fence_put(work->excl); for (i = 0; i < work->shared_count; ++i) dma_fence_put(work->shared[i]); kfree(work->shared); @@ -1141,7 +1145,7 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev, if (ret) return ret; - if (!dev->mode_config.allow_fb_modifiers && !adev->enable_virtual_display) { + if (!dev->mode_config.allow_fb_modifiers) { drm_WARN_ONCE(dev, adev->family >= AMDGPU_FAMILY_AI, "GFX9+ requires FB check based on format modifier\n"); ret = check_tiling_flags_gfx6(rfb); @@ -1360,7 +1364,7 @@ bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc, if ((!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) || ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) && - connector->display_info.is_hdmi && + drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) && amdgpu_display_is_hdtv_mode(mode)))) { if (amdgpu_encoder->underscan_hborder != 0) amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder; @@ -1599,10 +1603,13 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev) continue; } robj = gem_to_amdgpu_bo(fb->obj[0]); - r = amdgpu_bo_reserve(robj, true); - if (r == 0) { - amdgpu_bo_unpin(robj); - amdgpu_bo_unreserve(robj); + /* don't unpin kernel fb objects */ + if (!amdgpu_fbdev_robj_is_fb(adev, robj)) { + r = amdgpu_bo_reserve(robj, true); + if (r == 0) { + amdgpu_bo_unpin(robj); + amdgpu_bo_unreserve(robj); + } } } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 579adfafe4..7444484a12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -61,6 +61,9 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, if (pci_p2pdma_distance_many(adev->pdev, &attach->dev, 1, true) < 0) attach->peer2peer = false; + if (attach->dev->driver == adev->dev->driver) + return 0; + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); if (r < 0) goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0ead08ba58..5a7fef324c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -31,13 +31,13 @@ #include "amdgpu_drv.h" #include +#include #include #include #include #include #include #include -#include #include #include "amdgpu.h" @@ -97,11 +97,9 @@ * - 3.40.0 - Add AMDGPU_IDS_FLAGS_TMZ * - 3.41.0 - Add video codec query * - 3.42.0 - Add 16bpc fixed point display support - * - 3.43.0 - Add device hot plug/unplug support - * - 3.44.0 - DCN3 supports DCC independent block settings: !64B && 128B, 64B && 128B */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 44 +#define KMS_DRIVER_MINOR 42 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit; @@ -314,12 +312,9 @@ module_param_named(dpm, amdgpu_dpm, int, 0444); /** * DOC: fw_load_type (int) - * Set different firmware loading type for debugging, if supported. - * Set to 0 to force direct loading if supported by the ASIC. Set - * to -1 to select the default loading mode for the ASIC, as defined - * by the driver. The default is -1 (auto). + * Set different firmware loading type for debugging (0 = direct, 1 = SMU, 2 = PSP). The default is -1 (auto). */ -MODULE_PARM_DESC(fw_load_type, "firmware loading type (0 = force direct if supported, -1 = auto)"); +MODULE_PARM_DESC(fw_load_type, "firmware loading type (0 = direct, 1 = SMU, 2 = PSP, -1 = auto)"); module_param_named(fw_load_type, amdgpu_fw_load_type, int, 0444); /** @@ -331,11 +326,10 @@ module_param_named(aspm, amdgpu_aspm, int, 0444); /** * DOC: runpm (int) - * Override for runtime power management control for dGPUs. The amdgpu driver can dynamically power down - * the dGPUs when they are idle if supported. The default is -1 (auto enable). - * Setting the value to 0 disables this functionality. + * Override for runtime power management control for dGPUs in PX/HG laptops. The amdgpu driver can dynamically power down + * the dGPU on PX/HG laptops when it is idle. The default is -1 (auto enable). Setting the value to 0 disables this functionality. */ -MODULE_PARM_DESC(runpm, "PX runtime pm (2 = force enable with BAMACO, 1 = force enable with BACO, 0 = disable, -1 = auto)"); +MODULE_PARM_DESC(runpm, "PX runtime pm (2 = force enable with BAMACO, 1 = force enable with BACO, 0 = disable, -1 = PX only default)"); module_param_named(runpm, amdgpu_runtime_pm, int, 0444); /** @@ -634,7 +628,7 @@ module_param_named(mcbp, amdgpu_mcbp, int, 0444); /** * DOC: discovery (int) * Allow driver to discover hardware IP information from IP Discovery table at the top of VRAM. - * (-1 = auto (default), 0 = disabled, 1 = enabled, 2 = use ip_discovery table from file) + * (-1 = auto (default), 0 = disabled, 1 = enabled) */ MODULE_PARM_DESC(discovery, "Allow driver to discover hardware IPs from IP Discovery table at the top of VRAM"); @@ -882,7 +876,7 @@ module_param_named(reset_method, amdgpu_reset_method, int, 0444); * result in the GPU entering bad status when the number of total * faulty pages by ECC exceeds the threshold value. */ -MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement, -2 = ignore bad page threshold)"); +MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement)"); module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444); MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)"); @@ -1957,16 +1951,6 @@ static const struct pci_device_id pciidlist[] = { {0x1002, 0x7423, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, {0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, - { PCI_DEVICE(0x1002, PCI_ANY_ID), - .class = PCI_CLASS_DISPLAY_VGA << 8, - .class_mask = 0xffffff, - .driver_data = CHIP_IP_DISCOVERY }, - - { PCI_DEVICE(0x1002, PCI_ANY_ID), - .class = PCI_CLASS_DISPLAY_OTHER << 8, - .class_mask = 0xffffff, - .driver_data = CHIP_IP_DISCOVERY }, - {0, 0, 0} }; @@ -2005,15 +1989,15 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, bool is_fw_fb; resource_size_t base, size; + if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev)) + amdgpu_aspm = 0; + /* skip devices which are owned by radeon */ for (i = 0; i < ARRAY_SIZE(amdgpu_unsupported_pciidlist); i++) { if (amdgpu_unsupported_pciidlist[i] == pdev->device) return -ENODEV; } - if (amdgpu_aspm == -1 && !pcie_aspm_enabled(pdev)) - amdgpu_aspm = 0; - if (amdgpu_virtual_display || amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK)) supports_atomic = true; @@ -2028,8 +2012,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, * however, SME requires an indirect IOMMU mapping because the encryption * bit is beyond the DMA mask of the chip. */ - if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) && - ((flags & AMD_ASIC_MASK) == CHIP_RAVEN)) { + if (mem_encrypt_active() && ((flags & AMD_ASIC_MASK) == CHIP_RAVEN)) { dev_info(&pdev->dev, "SME is not compatible with RAVEN\n"); return -ENOTSUPP; @@ -2112,19 +2095,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, goto err_pci; } - /* - * 1. don't init fbdev on hw without DCE - * 2. don't init fbdev if there are no connectors - */ - if (adev->mode_info.mode_config_initialized && - !list_empty(&adev_to_drm(adev)->mode_config.connector_list)) { - /* select 8 bpp console on low vram cards */ - if (adev->gmc.real_vram_size <= (32*1024*1024)) - drm_fbdev_generic_setup(adev_to_drm(adev), 8); - else - drm_fbdev_generic_setup(adev_to_drm(adev), 32); - } - ret = amdgpu_debugfs_init(adev); if (ret) DRM_ERROR("Creating debugfs files failed (%d).\n", ret); @@ -2280,9 +2250,9 @@ static int amdgpu_pmops_suspend(struct device *dev) if (amdgpu_acpi_is_s0ix_active(adev)) adev->in_s0ix = true; - else - adev->in_s3 = true; + adev->in_s3 = true; r = amdgpu_device_suspend(drm_dev, true); + adev->in_s3 = false; if (r) return r; if (!adev->in_s0ix) @@ -2296,15 +2266,9 @@ static int amdgpu_pmops_resume(struct device *dev) struct amdgpu_device *adev = drm_to_adev(drm_dev); int r; - /* Avoids registers access if device is physically gone */ - if (!pci_device_is_present(adev->pdev)) - adev->no_hw_access = true; - r = amdgpu_device_resume(drm_dev, true); if (amdgpu_acpi_is_s0ix_active(adev)) adev->in_s0ix = false; - else - adev->in_s3 = false; return r; } @@ -2666,8 +2630,10 @@ static int __init amdgpu_init(void) { int r; - if (drm_firmware_drivers_only()) + if (vgacon_text_force()) { + DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); return -EINVAL; + } r = amdgpu_sync_init(); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h index 8178323e4b..e3a4f70480 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h @@ -45,7 +45,4 @@ long amdgpu_drm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -long amdgpu_kms_compat_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); - #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c index c96e458ed0..af4ef84e27 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_encoders.c @@ -222,7 +222,7 @@ bool amdgpu_dig_monitor_is_duallink(struct drm_encoder *encoder, case DRM_MODE_CONNECTOR_HDMIB: if (amdgpu_connector->use_digital) { /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { if (pixel_clock > 340000) return true; else @@ -244,7 +244,7 @@ bool amdgpu_dig_monitor_is_duallink(struct drm_encoder *encoder, return false; else { /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (connector->display_info.is_hdmi) { + if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector))) { if (pixel_clock > 340000) return true; else diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 45977a72b5..14499f0de3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -77,13 +77,11 @@ void amdgpu_fence_slab_fini(void) * Cast helper */ static const struct dma_fence_ops amdgpu_fence_ops; -static const struct dma_fence_ops amdgpu_job_fence_ops; static inline struct amdgpu_fence *to_amdgpu_fence(struct dma_fence *f) { struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, base); - if (__f->base.ops == &amdgpu_fence_ops || - __f->base.ops == &amdgpu_job_fence_ops) + if (__f->base.ops == &amdgpu_fence_ops) return __f; return NULL; @@ -160,18 +158,19 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd } seq = ++ring->fence_drv.sync_seq; - if (job && job->job_run_counter) { + if (job != NULL && job->job_run_counter) { /* reinit seq for resubmitted jobs */ fence->seqno = seq; } else { - if (job) - dma_fence_init(fence, &amdgpu_job_fence_ops, - &ring->fence_drv.lock, - adev->fence_context + ring->idx, seq); - else - dma_fence_init(fence, &amdgpu_fence_ops, - &ring->fence_drv.lock, - adev->fence_context + ring->idx, seq); + dma_fence_init(fence, &amdgpu_fence_ops, + &ring->fence_drv.lock, + adev->fence_context + ring->idx, + seq); + } + + if (job != NULL) { + /* mark this fence has a parent job */ + set_bit(AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT, &fence->flags); } amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, @@ -267,6 +266,7 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) struct amdgpu_fence_driver *drv = &ring->fence_drv; struct amdgpu_device *adev = ring->adev; uint32_t seq, last_seq; + int r; do { last_seq = atomic_read(&ring->fence_drv.last_seq); @@ -298,7 +298,12 @@ bool amdgpu_fence_process(struct amdgpu_ring *ring) if (!fence) continue; - dma_fence_signal(fence); + r = dma_fence_signal(fence); + if (!r) + DMA_FENCE_TRACE(fence, "signaled from irq context\n"); + else + BUG(); + dma_fence_put(fence); pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); @@ -548,7 +553,7 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) continue; /* You can't wait for HW to signal if it's gone */ - if (!drm_dev_is_unplugged(adev_to_drm(adev))) + if (!drm_dev_is_unplugged(&adev->ddev)) r = amdgpu_fence_wait_empty(ring); else r = -ENODEV; @@ -613,25 +618,6 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) } } -/** - * amdgpu_fence_driver_clear_job_fences - clear job embedded fences of ring - * - * @ring: fence of the ring to be cleared - * - */ -void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring) -{ - int i; - struct dma_fence *old, **ptr; - - for (i = 0; i <= ring->fence_drv.num_fences_mask; i++) { - ptr = &ring->fence_drv.fences[i]; - old = rcu_dereference_protected(*ptr, 1); - if (old && old->ops == &amdgpu_job_fence_ops) - RCU_INIT_POINTER(*ptr, NULL); - } -} - /** * amdgpu_fence_driver_force_completion - force signal latest fence of ring * @@ -655,14 +641,16 @@ static const char *amdgpu_fence_get_driver_name(struct dma_fence *fence) static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f) { - return (const char *)to_amdgpu_fence(f)->ring->name; -} + struct amdgpu_ring *ring; -static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f) -{ - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + if (test_bit(AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT, &f->flags)) { + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); - return (const char *)to_amdgpu_ring(job->base.sched)->name; + ring = to_amdgpu_ring(job->base.sched); + } else { + ring = to_amdgpu_fence(f)->ring; + } + return (const char *)ring->name; } /** @@ -675,25 +663,20 @@ static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f) */ static bool amdgpu_fence_enable_signaling(struct dma_fence *f) { - if (!timer_pending(&to_amdgpu_fence(f)->ring->fence_drv.fallback_timer)) - amdgpu_fence_schedule_fallback(to_amdgpu_fence(f)->ring); + struct amdgpu_ring *ring; - return true; -} + if (test_bit(AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT, &f->flags)) { + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); -/** - * amdgpu_job_fence_enable_signaling - enable signalling on job fence - * @f: fence - * - * This is the simliar function with amdgpu_fence_enable_signaling above, it - * only handles the job embedded fence. - */ -static bool amdgpu_job_fence_enable_signaling(struct dma_fence *f) -{ - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + ring = to_amdgpu_ring(job->base.sched); + } else { + ring = to_amdgpu_fence(f)->ring; + } - if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer)) - amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched)); + if (!timer_pending(&ring->fence_drv.fallback_timer)) + amdgpu_fence_schedule_fallback(ring); + + DMA_FENCE_TRACE(f, "armed on ring %i!\n", ring->idx); return true; } @@ -709,23 +692,19 @@ static void amdgpu_fence_free(struct rcu_head *rcu) { struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); - /* free fence_slab if it's separated fence*/ - kmem_cache_free(amdgpu_fence_slab, to_amdgpu_fence(f)); -} - -/** - * amdgpu_job_fence_free - free up the job with embedded fence - * - * @rcu: RCU callback head - * - * Free up the job with embedded fence after the RCU grace period. - */ -static void amdgpu_job_fence_free(struct rcu_head *rcu) -{ - struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); - + if (test_bit(AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT, &f->flags)) { /* free job if fence has a parent job */ - kfree(container_of(f, struct amdgpu_job, hw_fence)); + struct amdgpu_job *job; + + job = container_of(f, struct amdgpu_job, hw_fence); + kfree(job); + } else { + /* free fence_slab if it's separated fence*/ + struct amdgpu_fence *fence; + + fence = to_amdgpu_fence(f); + kmem_cache_free(amdgpu_fence_slab, fence); + } } /** @@ -741,19 +720,6 @@ static void amdgpu_fence_release(struct dma_fence *f) call_rcu(&f->rcu, amdgpu_fence_free); } -/** - * amdgpu_job_fence_release - callback that job embedded fence can be freed - * - * @f: fence - * - * This is the simliar function with amdgpu_fence_release above, it - * only handles the job embedded fence. - */ -static void amdgpu_job_fence_release(struct dma_fence *f) -{ - call_rcu(&f->rcu, amdgpu_job_fence_free); -} - static const struct dma_fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, @@ -761,12 +727,6 @@ static const struct dma_fence_ops amdgpu_fence_ops = { .release = amdgpu_fence_release, }; -static const struct dma_fence_ops amdgpu_job_fence_ops = { - .get_driver_name = amdgpu_fence_get_driver_name, - .get_timeline_name = amdgpu_job_fence_get_timeline_name, - .enable_signaling = amdgpu_job_fence_enable_signaling, - .release = amdgpu_job_fence_release, -}; /* * Fence debugfs diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c index 2a786e7886..7709caeb23 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c @@ -56,9 +56,6 @@ static bool is_fru_eeprom_supported(struct amdgpu_device *adev) return true; else return false; - case CHIP_ALDEBARAN: - /* All Aldebaran SKUs have the FRU */ - return true; default: return false; } @@ -91,17 +88,13 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr, int amdgpu_fru_get_product_info(struct amdgpu_device *adev) { - unsigned char buff[AMDGPU_PRODUCT_NAME_LEN+2]; + unsigned char buff[34]; u32 addrptr; int size, len; - int offset = 2; if (!is_fru_eeprom_supported(adev)) return 0; - if (adev->asic_type == CHIP_ALDEBARAN) - offset = 0; - /* If algo exists, it means that the i2c_adapter's initialized */ if (!adev->pm.smu_i2c.algo) { DRM_WARN("Cannot access FRU, EEPROM accessor not initialized"); @@ -138,13 +131,15 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) } len = size; - if (len >= AMDGPU_PRODUCT_NAME_LEN) { - DRM_WARN("FRU Product Name is larger than %d characters. This is likely a mistake", - AMDGPU_PRODUCT_NAME_LEN); - len = AMDGPU_PRODUCT_NAME_LEN - 1; + /* Product name should only be 32 characters. Any more, + * and something could be wrong. Cap it at 32 to be safe + */ + if (len >= sizeof(adev->product_name)) { + DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake"); + len = sizeof(adev->product_name) - 1; } /* Start at 2 due to buff using fields 0 and 1 for the address */ - memcpy(adev->product_name, &buff[offset], len); + memcpy(adev->product_name, &buff[2], len); adev->product_name[len] = '\0'; addrptr += size + 1; @@ -162,7 +157,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake"); len = sizeof(adev->product_number) - 1; } - memcpy(adev->product_number, &buff[offset], len); + memcpy(adev->product_number, &buff[2], len); adev->product_number[len] = '\0'; addrptr += size + 1; @@ -189,7 +184,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake"); len = sizeof(adev->serial) - 1; } - memcpy(adev->serial, &buff[offset], len); + memcpy(adev->serial, &buff[2], len); adev->serial[len] = '\0'; return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 645950a653..76efd5f895 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -34,7 +34,6 @@ #include #endif #include "amdgpu.h" -#include /* * GART @@ -114,12 +113,80 @@ void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev) */ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) { - if (adev->gart.bo != NULL) - return 0; + int r; - return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.bo, - NULL, (void *)&adev->gart.ptr); + if (adev->gart.bo == NULL) { + struct amdgpu_bo_param bp; + + memset(&bp, 0, sizeof(bp)); + bp.size = adev->gart.table_size; + bp.byte_align = PAGE_SIZE; + bp.domain = AMDGPU_GEM_DOMAIN_VRAM; + bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; + bp.type = ttm_bo_type_kernel; + bp.resv = NULL; + bp.bo_ptr_size = sizeof(struct amdgpu_bo); + + r = amdgpu_bo_create(adev, &bp, &adev->gart.bo); + if (r) { + return r; + } + } + return 0; +} + +/** + * amdgpu_gart_table_vram_pin - pin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Pin the GART page table in vram so it will not be moved + * by the memory manager (pcie r4xx, r5xx+). These asics require the + * gart table to be in video memory. + * Returns 0 for success, error for failure. + */ +int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) +{ + int r; + + r = amdgpu_bo_reserve(adev->gart.bo, false); + if (unlikely(r != 0)) + return r; + r = amdgpu_bo_pin(adev->gart.bo, AMDGPU_GEM_DOMAIN_VRAM); + if (r) { + amdgpu_bo_unreserve(adev->gart.bo); + return r; + } + r = amdgpu_bo_kmap(adev->gart.bo, &adev->gart.ptr); + if (r) + amdgpu_bo_unpin(adev->gart.bo); + amdgpu_bo_unreserve(adev->gart.bo); + return r; +} + +/** + * amdgpu_gart_table_vram_unpin - unpin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Unpin the GART page table in vram (pcie r4xx, r5xx+). + * These asics require the gart table to be in video memory. + */ +void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) +{ + int r; + + if (adev->gart.bo == NULL) { + return; + } + r = amdgpu_bo_reserve(adev->gart.bo, true); + if (likely(r == 0)) { + amdgpu_bo_kunmap(adev->gart.bo); + amdgpu_bo_unpin(adev->gart.bo); + amdgpu_bo_unreserve(adev->gart.bo); + adev->gart.ptr = NULL; + } } /** @@ -133,7 +200,11 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) */ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) { - amdgpu_bo_free_kernel(&adev->gart.bo, NULL, (void *)&adev->gart.ptr); + if (adev->gart.bo == NULL) { + return; + } + amdgpu_bo_unref(&adev->gart.bo); + adev->gart.ptr = NULL; } /* @@ -159,16 +230,12 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, u64 page_base; /* Starting from VEGA10, system bit must be 0 to mean invalid. */ uint64_t flags = 0; - int idx; if (!adev->gart.ready) { WARN(1, "trying to unbind memory from uninitialized GART !\n"); return -EINVAL; } - if (!drm_dev_enter(adev_to_drm(adev), &idx)) - return 0; - t = offset / AMDGPU_GPU_PAGE_SIZE; p = t / AMDGPU_GPU_PAGES_IN_CPU_PAGE; for (i = 0; i < pages; i++, p++) { @@ -187,7 +254,6 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, for (i = 0; i < adev->num_vmhubs; i++) amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); - drm_dev_exit(idx); return 0; } @@ -210,16 +276,12 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, { uint64_t page_base; unsigned i, j, t; - int idx; if (!adev->gart.ready) { WARN(1, "trying to bind memory to uninitialized GART !\n"); return -EINVAL; } - if (!drm_dev_enter(adev_to_drm(adev), &idx)) - return 0; - t = offset / AMDGPU_GPU_PAGE_SIZE; for (i = 0; i < pages; i++) { @@ -229,7 +291,6 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, page_base += AMDGPU_GPU_PAGE_SIZE; } } - drm_dev_exit(idx); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index c0d8f40a5b..a1e63ba4c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -877,32 +877,6 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, return r; } -static int amdgpu_gem_align_pitch(struct amdgpu_device *adev, - int width, - int cpp, - bool tiled) -{ - int aligned = width; - int pitch_mask = 0; - - switch (cpp) { - case 1: - pitch_mask = 255; - break; - case 2: - pitch_mask = 127; - break; - case 3: - case 4: - pitch_mask = 63; - break; - } - - aligned += pitch_mask; - aligned &= ~pitch_mask; - return aligned * cpp; -} - int amdgpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) @@ -911,8 +885,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, struct drm_gem_object *gobj; uint32_t handle; u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | - AMDGPU_GEM_CREATE_CPU_GTT_USWC | - AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; + AMDGPU_GEM_CREATE_CPU_GTT_USWC; u32 domain; int r; @@ -924,8 +897,8 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, if (adev->mman.buffer_funcs_enabled) flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED; - args->pitch = amdgpu_gem_align_pitch(adev, args->width, - DIV_ROUND_UP(args->bpp, 8), 0); + args->pitch = amdgpu_align_pitch(adev, args->width, + DIV_ROUND_UP(args->bpp, 8), 0); args->size = (u64)args->pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); domain = amdgpu_bo_get_preferred_domain(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index f851196c83..d43fe2ed81 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h @@ -42,9 +42,10 @@ #define AMDGPU_MAX_GFX_QUEUES KGD_MAX_QUEUES #define AMDGPU_MAX_COMPUTE_QUEUES KGD_MAX_QUEUES -enum amdgpu_gfx_pipe_priority { - AMDGPU_GFX_PIPE_PRIO_NORMAL = AMDGPU_RING_PRIO_1, - AMDGPU_GFX_PIPE_PRIO_HIGH = AMDGPU_RING_PRIO_2 +enum gfx_pipe_priority { + AMDGPU_GFX_PIPE_PRIO_NORMAL = 1, + AMDGPU_GFX_PIPE_PRIO_HIGH, + AMDGPU_GFX_PIPE_PRIO_MAX }; /* Argument for PPSMC_MSG_GpuChangeState */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 2430d6223c..9ff600a385 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -153,6 +153,10 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr, { void __iomem *ptr = (void *)cpu_pt_addr; uint64_t value; + int idx; + + if (!drm_dev_enter(&adev->ddev, &idx)) + return 0; /* * The following is for PTE only. GART does not have PDEs. @@ -161,6 +165,8 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr, value |= flags; writeq(value, ptr + (gpu_page_idx * 8)); + drm_dev_exit(idx); + return 0; } @@ -350,7 +356,6 @@ static inline uint64_t amdgpu_gmc_fault_key(uint64_t addr, uint16_t pasid) * amdgpu_gmc_filter_faults - filter VM faults * * @adev: amdgpu device structure - * @ih: interrupt ring that the fault received from * @addr: address of the VM fault * @pasid: PASID of the process causing the fault * @timestamp: timestamp of the fault @@ -359,8 +364,7 @@ static inline uint64_t amdgpu_gmc_fault_key(uint64_t addr, uint16_t pasid) * True if the fault was filtered and should not be processed further. * False if the fault is a new one and needs to be handled. */ -bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, - struct amdgpu_ih_ring *ih, uint64_t addr, +bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, uint64_t addr, uint16_t pasid, uint64_t timestamp) { struct amdgpu_gmc *gmc = &adev->gmc; @@ -368,10 +372,6 @@ bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, struct amdgpu_gmc_fault *fault; uint32_t hash; - /* Stale retry fault if timestamp goes backward */ - if (amdgpu_ih_ts_after(timestamp, ih->processed_timestamp)) - return true; - /* If we don't have space left in the ring buffer return immediately */ stamp = max(timestamp, AMDGPU_GMC_FAULT_TIMEOUT + 1) - AMDGPU_GMC_FAULT_TIMEOUT; @@ -749,10 +749,6 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev) adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size; u64 vram_end = vram_addr + vram_size; u64 gart_ptb_gpu_pa = amdgpu_gmc_vram_pa(adev, adev->gart.bo); - int idx; - - if (!drm_dev_enter(adev_to_drm(adev), &idx)) - return; flags |= AMDGPU_PTE_VALID | AMDGPU_PTE_READABLE; flags |= AMDGPU_PTE_WRITEABLE; @@ -774,7 +770,6 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev) flags |= AMDGPU_PDE_BFS(0) | AMDGPU_PTE_SNOOPED; /* Requires gart_ptb_gpu_pa to be 4K aligned */ amdgpu_gmc_set_pte_pde(adev, adev->gmc.ptr_pdb0, i, gart_ptb_gpu_pa, flags); - drm_dev_exit(idx); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index 8458cebc6d..e55201134a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -316,8 +316,7 @@ void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc); void amdgpu_gmc_agp_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc); -bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, - struct amdgpu_ih_ring *ih, uint64_t addr, +bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev, uint64_t addr, uint16_t pasid, uint64_t timestamp); void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr, uint16_t pasid); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 72022df264..675a72ef30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -77,8 +77,10 @@ static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); + struct ttm_resource_manager *man; - return sysfs_emit(buf, "%llu\n", amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr)); + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); + return sysfs_emit(buf, "%llu\n", amdgpu_gtt_mgr_usage(man)); } static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO, @@ -204,27 +206,30 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man, /** * amdgpu_gtt_mgr_usage - return usage of GTT domain * - * @mgr: amdgpu_gtt_mgr pointer + * @man: TTM memory type manager * * Return how many bytes are used in the GTT domain */ -uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr) +uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man) { + struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); + return atomic64_read(&mgr->used) * PAGE_SIZE; } /** * amdgpu_gtt_mgr_recover - re-init gart * - * @mgr: amdgpu_gtt_mgr pointer + * @man: TTM memory type manager * * Re-init the gart for each known BO in the GTT. */ -int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr) +int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man) { + struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); + struct amdgpu_device *adev; struct amdgpu_gtt_node *node; struct drm_mm_node *mm_node; - struct amdgpu_device *adev; int r = 0; adev = container_of(mgr, typeof(*adev), mman.gtt_mgr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index bc1297dcdf..c076a6b9a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -300,15 +300,20 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, */ int amdgpu_ib_pool_init(struct amdgpu_device *adev) { + unsigned size; int r, i; if (adev->ib_pool_ready) return 0; for (i = 0; i < AMDGPU_IB_POOL_MAX; i++) { + if (i == AMDGPU_IB_POOL_DIRECT) + size = PAGE_SIZE * 6; + else + size = AMDGPU_IB_POOL_SIZE; + r = amdgpu_sa_bo_manager_init(adev, &adev->ib_pools[i], - AMDGPU_IB_POOL_SIZE, - AMDGPU_GPU_PAGE_SIZE, + size, AMDGPU_GPU_PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT); if (r) goto error; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 3df146579a..0c7963dfac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -164,32 +164,52 @@ void amdgpu_ih_ring_write(struct amdgpu_ih_ring *ih, const uint32_t *iv, } } +/* Waiter helper that checks current rptr matches or passes checkpoint wptr */ +static bool amdgpu_ih_has_checkpoint_processed(struct amdgpu_device *adev, + struct amdgpu_ih_ring *ih, + uint32_t checkpoint_wptr, + uint32_t *prev_rptr) +{ + uint32_t cur_rptr = ih->rptr | (*prev_rptr & ~ih->ptr_mask); + + /* rptr has wrapped. */ + if (cur_rptr < *prev_rptr) + cur_rptr += ih->ptr_mask + 1; + *prev_rptr = cur_rptr; + + /* check ring is empty to workaround missing wptr overflow flag */ + return cur_rptr >= checkpoint_wptr || + (cur_rptr & ih->ptr_mask) == amdgpu_ih_get_wptr(adev, ih); +} + /** - * amdgpu_ih_wait_on_checkpoint_process_ts - wait to process IVs up to checkpoint + * amdgpu_ih_wait_on_checkpoint_process - wait to process IVs up to checkpoint * * @adev: amdgpu_device pointer * @ih: ih ring to process * * Used to ensure ring has processed IVs up to the checkpoint write pointer. */ -int amdgpu_ih_wait_on_checkpoint_process_ts(struct amdgpu_device *adev, +int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) { - uint32_t checkpoint_wptr; - uint64_t checkpoint_ts; - long timeout = HZ; + uint32_t checkpoint_wptr, rptr; if (!ih->enabled || adev->shutdown) return -ENODEV; checkpoint_wptr = amdgpu_ih_get_wptr(adev, ih); - /* Order wptr with ring data. */ + /* Order wptr with rptr. */ rmb(); - checkpoint_ts = amdgpu_ih_decode_iv_ts(adev, ih, checkpoint_wptr, -1); + rptr = READ_ONCE(ih->rptr); - return wait_event_interruptible_timeout(ih->wait_process, - amdgpu_ih_ts_after(checkpoint_ts, ih->processed_timestamp) || - ih->rptr == amdgpu_ih_get_wptr(adev, ih), timeout); + /* wptr has wrapped. */ + if (rptr > checkpoint_wptr) + checkpoint_wptr += ih->ptr_mask + 1; + + return wait_event_interruptible(ih->wait_process, + amdgpu_ih_has_checkpoint_processed(adev, ih, + checkpoint_wptr, &rptr)); } /** @@ -279,18 +299,3 @@ void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev, /* wptr/rptr are in bytes! */ ih->rptr += 32; } - -uint64_t amdgpu_ih_decode_iv_ts_helper(struct amdgpu_ih_ring *ih, u32 rptr, - signed int offset) -{ - uint32_t iv_size = 32; - uint32_t ring_index; - uint32_t dw1, dw2; - - rptr += iv_size * offset; - ring_index = (rptr & ih->ptr_mask) >> 2; - - dw1 = le32_to_cpu(ih->ring[ring_index + 1]); - dw2 = le32_to_cpu(ih->ring[ring_index + 2]); - return dw1 | ((u64)(dw2 & 0xffff) << 32); -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index dd1c2eded6..0649b59830 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -68,30 +68,20 @@ struct amdgpu_ih_ring { /* For waiting on IH processing at checkpoint. */ wait_queue_head_t wait_process; - uint64_t processed_timestamp; }; -/* return true if time stamp t2 is after t1 with 48bit wrap around */ -#define amdgpu_ih_ts_after(t1, t2) \ - (((int64_t)((t2) << 16) - (int64_t)((t1) << 16)) > 0LL) - /* provided by the ih block */ struct amdgpu_ih_funcs { /* ring read/write ptr handling, called from interrupt context */ u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, struct amdgpu_iv_entry *entry); - uint64_t (*decode_iv_ts)(struct amdgpu_ih_ring *ih, u32 rptr, - signed int offset); void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); }; #define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih)) #define amdgpu_ih_decode_iv(adev, iv) \ (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv)) -#define amdgpu_ih_decode_iv_ts(adev, ih, rptr, offset) \ - (WARN_ON_ONCE(!(adev)->irq.ih_funcs->decode_iv_ts) ? 0 : \ - (adev)->irq.ih_funcs->decode_iv_ts((ih), (rptr), (offset))) #define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih)) int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, @@ -99,12 +89,10 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); void amdgpu_ih_ring_write(struct amdgpu_ih_ring *ih, const uint32_t *iv, unsigned int num_dw); -int amdgpu_ih_wait_on_checkpoint_process_ts(struct amdgpu_device *adev, - struct amdgpu_ih_ring *ih); +int amdgpu_ih_wait_on_checkpoint_process(struct amdgpu_device *adev, + struct amdgpu_ih_ring *ih); int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, struct amdgpu_iv_entry *entry); -uint64_t amdgpu_ih_decode_iv_ts_helper(struct amdgpu_ih_ring *ih, u32 rptr, - signed int offset); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c index a1cbd7c3de..5cf142e849 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ioc32.c @@ -1,4 +1,4 @@ -/* +/** * \file amdgpu_ioc32.c * * 32-bit ioctl compatibility routines for the AMDGPU DRM. @@ -37,9 +37,12 @@ long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int nr = DRM_IOCTL_NR(cmd); + int ret; if (nr < DRM_COMMAND_BASE) return drm_compat_ioctl(filp, cmd, arg); - return amdgpu_drm_ioctl(filp, cmd, arg); + ret = amdgpu_drm_ioctl(filp, cmd, arg); + + return ret; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index f5cbc2747a..4f3c62adcc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -390,7 +390,7 @@ void amdgpu_irq_fini_hw(struct amdgpu_device *adev) } /** - * amdgpu_irq_fini_sw - shut down interrupt handling + * amdgpu_irq_fini - shut down interrupt handling * * @adev: amdgpu device pointer * @@ -528,9 +528,6 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, /* Send it to amdkfd as well if it isn't already handled */ if (!handled) amdgpu_amdkfd_interrupt(adev, entry.iv_entry); - - if (amdgpu_ih_ts_after(ih->processed_timestamp, entry.timestamp)) - ih->processed_timestamp = entry.timestamp; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index bfc47bea23..de29518673 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -38,7 +38,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) struct amdgpu_device *adev = ring->adev; int idx; - if (!drm_dev_enter(adev_to_drm(adev), &idx)) { + if (!drm_dev_enter(&adev->ddev, &idx)) { DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s", __func__, s_job->sched->name); @@ -182,11 +182,9 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, if (r) return r; - drm_sched_job_arm(&job->base); - *f = dma_fence_get(&job->base.s_fence->finished); amdgpu_job_free_resources(job); - drm_sched_entity_push_job(&job->base); + drm_sched_entity_push_job(&job->base, entity); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1ebb91db22..09a2fe8390 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -346,35 +346,28 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, case AMDGPU_INFO_FW_TA: switch (query_fw->index) { case TA_FW_TYPE_PSP_XGMI: - fw_info->ver = adev->psp.xgmi_context.context.bin_desc.fw_version; - fw_info->feature = adev->psp.xgmi_context.context - .bin_desc.feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.xgmi.feature_version; break; case TA_FW_TYPE_PSP_RAS: - fw_info->ver = adev->psp.ras_context.context.bin_desc.fw_version; - fw_info->feature = adev->psp.ras_context.context - .bin_desc.feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.ras.feature_version; break; case TA_FW_TYPE_PSP_HDCP: - fw_info->ver = adev->psp.hdcp_context.context.bin_desc.fw_version; - fw_info->feature = adev->psp.hdcp_context.context - .bin_desc.feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.hdcp.feature_version; break; case TA_FW_TYPE_PSP_DTM: - fw_info->ver = adev->psp.dtm_context.context.bin_desc.fw_version; - fw_info->feature = adev->psp.dtm_context.context - .bin_desc.feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.dtm.feature_version; break; case TA_FW_TYPE_PSP_RAP: - fw_info->ver = adev->psp.rap_context.context.bin_desc.fw_version; - fw_info->feature = adev->psp.rap_context.context - .bin_desc.feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.rap.feature_version; break; case TA_FW_TYPE_PSP_SECUREDISPLAY: - fw_info->ver = adev->psp.securedisplay_context.context.bin_desc.fw_version; - fw_info->feature = - adev->psp.securedisplay_context.context.bin_desc - .feature_version; + fw_info->ver = adev->psp.ta_fw_version; + fw_info->feature = adev->psp.securedisplay.feature_version; break; default: return -EINVAL; @@ -391,8 +384,8 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, fw_info->feature = adev->psp.sos.feature_version; break; case AMDGPU_INFO_FW_ASD: - fw_info->ver = adev->psp.asd_context.bin_desc.fw_version; - fw_info->feature = adev->psp.asd_context.bin_desc.feature_version; + fw_info->ver = adev->psp.asd.fw_version; + fw_info->feature = adev->psp.asd.feature_version; break; case AMDGPU_INFO_FW_DMCU: fw_info->ver = adev->dm.dmcu_fw_version; @@ -678,13 +671,13 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ui64 = atomic64_read(&adev->num_vram_cpu_page_faults); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_VRAM_USAGE: - ui64 = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr); + ui64 = amdgpu_vram_mgr_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_VIS_VRAM_USAGE: - ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr); + ui64 = amdgpu_vram_mgr_vis_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_GTT_USAGE: - ui64 = amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr); + ui64 = amdgpu_gtt_mgr_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_GDS_CONFIG: { struct drm_amdgpu_info_gds gds_info; @@ -715,6 +708,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } case AMDGPU_INFO_MEMORY: { struct drm_amdgpu_memory_info mem; + struct ttm_resource_manager *vram_man = + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); struct ttm_resource_manager *gtt_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); memset(&mem, 0, sizeof(mem)); @@ -723,7 +718,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) atomic64_read(&adev->vram_pin_size) - AMDGPU_VM_RESERVED_VRAM; mem.vram.heap_usage = - amdgpu_vram_mgr_usage(&adev->mman.vram_mgr); + amdgpu_vram_mgr_usage(vram_man); mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; mem.cpu_accessible_vram.total_heap_size = @@ -733,7 +728,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) atomic64_read(&adev->visible_pin_size), mem.vram.usable_heap_size); mem.cpu_accessible_vram.heap_usage = - amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr); + amdgpu_vram_mgr_vis_usage(vram_man); mem.cpu_accessible_vram.max_allocation = mem.cpu_accessible_vram.usable_heap_size * 3 / 4; @@ -742,7 +737,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) mem.gtt.usable_heap_size = mem.gtt.total_heap_size - atomic64_read(&adev->gart_pin_size); mem.gtt.heap_usage = - amdgpu_gtt_mgr_usage(&adev->mman.gtt_mgr); + amdgpu_gtt_mgr_usage(gtt_man); mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4; return copy_to_user(out, &mem, @@ -1427,8 +1422,6 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused) struct drm_amdgpu_info_firmware fw_info; struct drm_amdgpu_query_fw query_fw; struct atom_context *ctx = adev->mode_info.atom_context; - uint8_t smu_minor, smu_debug; - uint16_t smu_major; int ret, i; static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = { @@ -1574,11 +1567,8 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused) ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); if (ret) return ret; - smu_major = (fw_info.ver >> 16) & 0xffff; - smu_minor = (fw_info.ver >> 8) & 0xff; - smu_debug = (fw_info.ver >> 0) & 0xff; - seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x (%d.%d.%d)\n", - fw_info.feature, fw_info.ver, smu_major, smu_minor, smu_debug); + seq_printf(m, "SMC feature version: %u, firmware version: 0x%08x\n", + fw_info.feature, fw_info.ver); /* SDMA */ query_fw.fw_type = AMDGPU_INFO_FW_SDMA; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index ce538f4819..a2d3dbbf7d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -31,7 +31,7 @@ void amdgpu_mca_query_correctable_error_count(struct amdgpu_device *adev, uint64_t mc_status_addr, unsigned long *error_count) { - uint64_t mc_status = RREG64_PCIE(mc_status_addr); + uint64_t mc_status = RREG64_PCIE(mc_status_addr * 4); if (REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 && REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1) @@ -42,7 +42,7 @@ void amdgpu_mca_query_uncorrectable_error_count(struct amdgpu_device *adev, uint64_t mc_status_addr, unsigned long *error_count) { - uint64_t mc_status = RREG64_PCIE(mc_status_addr); + uint64_t mc_status = RREG64_PCIE(mc_status_addr * 4); if ((REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && (REG_GET_FIELD(mc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 || @@ -56,7 +56,7 @@ void amdgpu_mca_query_uncorrectable_error_count(struct amdgpu_device *adev, void amdgpu_mca_reset_error_count(struct amdgpu_device *adev, uint64_t mc_status_addr) { - WREG64_PCIE(mc_status_addr, 0x0ULL); + WREG64_PCIE(mc_status_addr * 4, 0x0ULL); } void amdgpu_mca_query_ras_error_count(struct amdgpu_device *adev, @@ -87,8 +87,8 @@ int amdgpu_mca_ras_late_init(struct amdgpu_device *adev, if (!mca_dev->ras_if) return -ENOMEM; mca_dev->ras_if->block = mca_dev->ras_funcs->ras_block; - mca_dev->ras_if->sub_block_index = mca_dev->ras_funcs->ras_sub_block; mca_dev->ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE; + mca_dev->ras_if->sub_block_index = 0; } ih_info.head = fs_info.head = *mca_dev->ras_if; r = amdgpu_ras_late_init(adev, mca_dev->ras_if, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index c74bc71770..f860f2f0e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -29,7 +29,6 @@ struct amdgpu_mca_ras_funcs { void (*query_ras_error_address)(struct amdgpu_device *adev, void *ras_error_status); uint32_t ras_block; - uint32_t ras_sub_block; const char* sysfs_name; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 6043bf6fd4..89fb372ed4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -232,6 +232,8 @@ struct amdgpu_i2c_chan { struct mutex mutex; }; +struct amdgpu_fbdev; + struct amdgpu_afmt { bool enabled; int offset; @@ -307,6 +309,13 @@ struct amdgpu_framebuffer { uint64_t address; }; +struct amdgpu_fbdev { + struct drm_fb_helper helper; + struct amdgpu_framebuffer rfb; + struct list_head fbdev_list; + struct amdgpu_device *adev; +}; + struct amdgpu_mode_info { struct atom_context *atom_context; struct card_info *atom_card_info; @@ -332,6 +341,8 @@ struct amdgpu_mode_info { struct edid *bios_hardcoded_edid; int bios_hardcoded_edid_size; + /* pointer to fbdev info structure */ + struct amdgpu_fbdev *rfbdev; /* firmware flags */ u32 firmware_flags; /* pointer to backlight encoder */ @@ -620,6 +631,15 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); +/* fbdev layer */ +int amdgpu_fbdev_init(struct amdgpu_device *adev); +void amdgpu_fbdev_fini(struct amdgpu_device *adev); +void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state); +int amdgpu_fbdev_total_size(struct amdgpu_device *adev); +bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj); + +int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled); + /* amdgpu_display.c */ void amdgpu_display_print_display_setup(struct drm_device *dev); int amdgpu_display_modeset_create_props(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 5661b82d84..01a78c7865 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include "amdgpu.h" @@ -695,6 +694,40 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev, return r; } +/** + * amdgpu_bo_validate - validate an &amdgpu_bo buffer object + * @bo: pointer to the buffer object + * + * Sets placement according to domain; and changes placement and caching + * policy of the buffer object according to the placement. + * This is used for validating shadow bos. It calls ttm_bo_validate() to + * make sure the buffer is resident where it needs to be. + * + * Returns: + * 0 for success or a negative error code on failure. + */ +int amdgpu_bo_validate(struct amdgpu_bo *bo) +{ + struct ttm_operation_ctx ctx = { false, false }; + uint32_t domain; + int r; + + if (bo->tbo.pin_count) + return 0; + + domain = bo->preferred_domains; + +retry: + amdgpu_bo_placement_from_domain(bo, domain); + r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); + if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { + domain = bo->allowed_domains; + goto retry; + } + + return r; +} + /** * amdgpu_bo_add_to_shadow_list - add a BO to the shadow list * @@ -1005,6 +1038,29 @@ void amdgpu_bo_unpin(struct amdgpu_bo *bo) } } +/** + * amdgpu_bo_evict_vram - evict VRAM buffers + * @adev: amdgpu device object + * + * Evicts all VRAM buffers on the lru list of the memory type. + * Mainly used for evicting vram at suspend time. + * + * Returns: + * 0 for success or a negative error code on failure. + */ +int amdgpu_bo_evict_vram(struct amdgpu_device *adev) +{ + struct ttm_resource_manager *man; + + if (adev->in_s3 && (adev->flags & AMD_IS_APU)) { + /* No need to evict vram on APUs for suspend to ram */ + return 0; + } + + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + return ttm_resource_manager_evict_all(&adev->mman.bdev, man); +} + static const char *amdgpu_vram_names[] = { "UNKNOWN", "GDDR1", @@ -1033,14 +1089,9 @@ int amdgpu_bo_init(struct amdgpu_device *adev) /* On A+A platform, VRAM can be mapped as WB */ if (!adev->gmc.xgmi.connected_to_cpu) { /* reserve PAT memory space to WC for VRAM */ - int r = arch_io_reserve_memtype_wc(adev->gmc.aper_base, + arch_io_reserve_memtype_wc(adev->gmc.aper_base, adev->gmc.aper_size); - if (r) { - DRM_ERROR("Unable to set WC memtype for the aperture base\n"); - return r; - } - /* Add an MTRR for the VRAM */ adev->gmc.vram_mtrr = arch_phys_wc_add(adev->gmc.aper_base, adev->gmc.aper_size); @@ -1062,18 +1113,7 @@ int amdgpu_bo_init(struct amdgpu_device *adev) */ void amdgpu_bo_fini(struct amdgpu_device *adev) { - int idx; - amdgpu_ttm_fini(adev); - - if (drm_dev_enter(adev_to_drm(adev), &idx)) { - - if (!adev->gmc.xgmi.connected_to_cpu) { - arch_phys_wc_del(adev->gmc.vram_mtrr); - arch_io_free_memtype_wc(adev->gmc.aper_base, adev->gmc.aper_size); - } - drm_dev_exit(idx); - } } /** @@ -1291,7 +1331,7 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo) abo = ttm_to_amdgpu_bo(bo); if (abo->kfd_bo) - amdgpu_amdkfd_release_notify(abo); + amdgpu_amdkfd_unreserve_memory_limit(abo); /* We only remove the fence if the resv has individualized. */ WARN_ON_ONCE(bo->type == ttm_bo_type_kernel diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 4c9cbdc669..9d6c001c15 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -304,6 +304,7 @@ int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain); int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 min_offset, u64 max_offset); void amdgpu_bo_unpin(struct amdgpu_bo *bo); +int amdgpu_bo_evict_vram(struct amdgpu_device *adev); int amdgpu_bo_init(struct amdgpu_device *adev); void amdgpu_bo_fini(struct amdgpu_device *adev); int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags); @@ -326,6 +327,7 @@ int amdgpu_bo_sync_wait_resv(struct amdgpu_device *adev, struct dma_resv *resv, int amdgpu_bo_sync_wait(struct amdgpu_bo *bo, void *owner, bool intr); u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo); +int amdgpu_bo_validate(struct amdgpu_bo *bo); void amdgpu_bo_get_memory(struct amdgpu_bo *bo, uint64_t *vram_mem, uint64_t *gtt_mem, uint64_t *cpu_mem); void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c index 0bb2466d53..4eaec446b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pll.c @@ -69,7 +69,6 @@ static void amdgpu_pll_reduce_ratio(unsigned *nom, unsigned *den, /** * amdgpu_pll_get_fb_ref_div - feedback and ref divider calculation * - * @adev: amdgpu_device pointer * @nom: nominator * @den: denominator * @post_div: post divider @@ -107,7 +106,6 @@ static void amdgpu_pll_get_fb_ref_div(struct amdgpu_device *adev, unsigned int n /** * amdgpu_pll_compute - compute PLL paramaters * - * @adev: amdgpu_device pointer * @pll: information about the PLL * @freq: requested frequency * @dot_clock_p: resulting pixel clock diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c index 71ee361d09..82e9ecf843 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c @@ -233,10 +233,6 @@ static void amdgpu_perf_start(struct perf_event *event, int flags) if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) return; - if ((!pe->adev->df.funcs) || - (!pe->adev->df.funcs->pmc_start)) - return; - WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); hwc->state = 0; @@ -272,10 +268,6 @@ static void amdgpu_perf_read(struct perf_event *event) pmu); u64 count, prev; - if ((!pe->adev->df.funcs) || - (!pe->adev->df.funcs->pmc_get_count)) - return; - do { prev = local64_read(&hwc->prev_count); @@ -305,10 +297,6 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags) if (hwc->state & PERF_HES_UPTODATE) return; - if ((!pe->adev->df.funcs) || - (!pe->adev->df.funcs->pmc_stop)) - return; - switch (hwc->config_base) { case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: @@ -338,10 +326,6 @@ static int amdgpu_perf_add(struct perf_event *event, int flags) struct amdgpu_pmu_entry, pmu); - if ((!pe->adev->df.funcs) || - (!pe->adev->df.funcs->pmc_start)) - return -EINVAL; - switch (pe->pmu_perf_type) { case AMDGPU_PMU_PERF_TYPE_DF: hwc->config_base = AMDGPU_PMU_EVENT_CONFIG_TYPE_DF; @@ -387,9 +371,6 @@ static void amdgpu_perf_del(struct perf_event *event, int flags) struct amdgpu_pmu_entry *pe = container_of(event->pmu, struct amdgpu_pmu_entry, pmu); - if ((!pe->adev->df.funcs) || - (!pe->adev->df.funcs->pmc_stop)) - return; amdgpu_perf_stop(event, PERF_EF_UPDATE); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c index 786afe4f58..d02c8637f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c @@ -59,7 +59,7 @@ static DEVICE_ATTR_RO(mem_info_preempt_used); * @man: TTM memory type manager * @tbo: TTM BO we need this range for * @place: placement flags and restrictions - * @res: TTM memory object + * @mem: the resulting mem object * * Dummy, just count the space used without allocating resources or any limit. */ @@ -85,7 +85,7 @@ static int amdgpu_preempt_mgr_new(struct ttm_resource_manager *man, * amdgpu_preempt_mgr_del - free ranges * * @man: TTM memory type manager - * @res: TTM memory object + * @mem: TTM memory object * * Free the allocated GTT again. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index dee17a0e11..86e2090bbd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -46,10 +46,6 @@ static int psp_sysfs_init(struct amdgpu_device *adev); static void psp_sysfs_fini(struct amdgpu_device *adev); static int psp_load_smu_fw(struct psp_context *psp); -static int psp_ta_unload(struct psp_context *psp, struct ta_context *context); -static int psp_ta_load(struct psp_context *psp, struct ta_context *context); -static int psp_rap_terminate(struct psp_context *psp); -static int psp_securedisplay_terminate(struct psp_context *psp); /* * Due to DF Cstate management centralized to PMFW, the firmware @@ -65,32 +61,23 @@ static int psp_securedisplay_terminate(struct psp_context *psp); * * This new sequence is required for * - Arcturus and onwards + * - Navi12 and onwards */ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; - if (amdgpu_sriov_vf(adev)) { - psp->pmfw_centralized_cstate_management = false; - return; - } + psp->pmfw_centralized_cstate_management = false; - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 4): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - case IP_VERSION(13, 0, 2): + if (amdgpu_sriov_vf(adev)) + return; + + if (adev->flags & AMD_IS_APU) + return; + + if ((adev->asic_type >= CHIP_ARCTURUS) || + (adev->asic_type >= CHIP_NAVI12)) psp->pmfw_centralized_cstate_management = true; - break; - default: - psp->pmfw_centralized_cstate_management = false; - break; - } } static int psp_early_init(void *handle) @@ -98,45 +85,43 @@ static int psp_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct psp_context *psp = &adev->psp; - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(9, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: psp_v3_1_set_psp_funcs(psp); psp->autoload_supported = false; break; - case IP_VERSION(10, 0, 0): - case IP_VERSION(10, 0, 1): + case CHIP_RAVEN: psp_v10_0_set_psp_funcs(psp); psp->autoload_supported = false; break; - case IP_VERSION(11, 0, 2): - case IP_VERSION(11, 0, 4): + case CHIP_VEGA20: + case CHIP_ARCTURUS: psp_v11_0_set_psp_funcs(psp); psp->autoload_supported = false; break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 5, 0): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: psp_v11_0_set_psp_funcs(psp); psp->autoload_supported = true; break; - case IP_VERSION(11, 0, 3): - case IP_VERSION(12, 0, 1): + case CHIP_RENOIR: psp_v12_0_set_psp_funcs(psp); break; - case IP_VERSION(13, 0, 2): + case CHIP_ALDEBARAN: psp_v13_0_set_psp_funcs(psp); break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + case CHIP_YELLOW_CARP: psp_v13_0_set_psp_funcs(psp); psp->autoload_supported = true; break; - case IP_VERSION(11, 0, 8): + case CHIP_CYAN_SKILLFISH: if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) { psp_v11_0_8_set_psp_funcs(psp); psp->autoload_supported = false; @@ -279,8 +264,7 @@ static int psp_sw_init(void *handle) DRM_ERROR("Failed to load psp firmware!\n"); return ret; } - } else if (amdgpu_sriov_vf(adev) && - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2)) { + } else if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_ALDEBARAN) { ret = psp_init_ta_microcode(psp, "aldebaran"); if (ret) { DRM_ERROR("Failed to initialize ta microcode!\n"); @@ -323,8 +307,7 @@ static int psp_sw_init(void *handle) } } - if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) || - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7)) { + if (adev->asic_type == CHIP_NAVI10 || adev->asic_type == CHIP_SIENNA_CICHLID) { ret= psp_sysfs_init(adev); if (ret) { return ret; @@ -354,8 +337,8 @@ static int psp_sw_fini(void *handle) psp->ta_fw = NULL; } - if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) || - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7)) + if (adev->asic_type == CHIP_NAVI10 || + adev->asic_type == CHIP_SIENNA_CICHLID) psp_sysfs_fini(adev); kfree(cmd); @@ -441,7 +424,7 @@ psp_cmd_submit_buf(struct psp_context *psp, if (psp->adev->no_hw_access) return 0; - if (!drm_dev_enter(adev_to_drm(psp->adev), &idx)) + if (!drm_dev_enter(&psp->adev->ddev, &idx)) return 0; memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); @@ -518,7 +501,7 @@ static struct psp_gfx_cmd_resp *acquire_psp_cmd_buf(struct psp_context *psp) return cmd; } -static void release_psp_cmd_buf(struct psp_context *psp) +void release_psp_cmd_buf(struct psp_context *psp) { mutex_unlock(&psp->mutex); } @@ -614,10 +597,10 @@ static int psp_tmr_init(struct psp_context *psp) static bool psp_skip_tmr(struct psp_context *psp) { - switch (psp->adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(13, 0, 2): + switch (psp->adev->asic_type) { + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_ALDEBARAN: return true; default: return false; @@ -795,29 +778,46 @@ static int psp_rl_load(struct amdgpu_device *adev) return ret; } -static int psp_asd_load(struct psp_context *psp) +static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, + uint64_t asd_mc, uint32_t size) { - return psp_ta_load(psp, &psp->asd_context); + cmd->cmd_id = GFX_CMD_ID_LOAD_ASD; + cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(asd_mc); + cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(asd_mc); + cmd->cmd.cmd_load_ta.app_len = size; + + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = 0; + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = 0; + cmd->cmd.cmd_load_ta.cmd_buf_len = 0; } -static int psp_asd_initialize(struct psp_context *psp) +static int psp_asd_load(struct psp_context *psp) { int ret; + struct psp_gfx_cmd_resp *cmd; /* If PSP version doesn't match ASD version, asd loading will be failed. * add workaround to bypass it for sriov now. * TODO: add version check to make it common */ - if (amdgpu_sriov_vf(psp->adev) || !psp->asd_context.bin_desc.size_bytes) + if (amdgpu_sriov_vf(psp->adev) || !psp->asd.size_bytes) return 0; - psp->asd_context.mem_context.shared_mc_addr = 0; - psp->asd_context.mem_context.shared_mem_size = PSP_ASD_SHARED_MEM_SIZE; - psp->asd_context.ta_load_type = GFX_CMD_ID_LOAD_ASD; + cmd = acquire_psp_cmd_buf(psp); - ret = psp_asd_load(psp); - if (!ret) - psp->asd_context.initialized = true; + psp_copy_fw(psp, psp->asd.start_addr, psp->asd.size_bytes); + + psp_prep_asd_load_cmd_buf(cmd, psp->fw_pri_mc_addr, + psp->asd.size_bytes); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + if (!ret) { + psp->asd_context.asd_initialized = true; + psp->asd_context.session_id = cmd->resp.session_id; + } + + release_psp_cmd_buf(psp); return ret; } @@ -829,39 +829,27 @@ static void psp_prep_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd, cmd->cmd.cmd_unload_ta.session_id = session_id; } -static int psp_ta_unload(struct psp_context *psp, struct ta_context *context) -{ - int ret; - struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); - - psp_prep_ta_unload_cmd_buf(cmd, context->session_id); - - ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); - - release_psp_cmd_buf(psp); - - return ret; -} - static int psp_asd_unload(struct psp_context *psp) -{ - return psp_ta_unload(psp, &psp->asd_context); -} - -static int psp_asd_terminate(struct psp_context *psp) { int ret; + struct psp_gfx_cmd_resp *cmd; if (amdgpu_sriov_vf(psp->adev)) return 0; - if (!psp->asd_context.initialized) + if (!psp->asd_context.asd_initialized) return 0; - ret = psp_asd_unload(psp); + cmd = acquire_psp_cmd_buf(psp); + psp_prep_ta_unload_cmd_buf(cmd, psp->asd_context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); if (!ret) - psp->asd_context.initialized = false; + psp->asd_context.asd_initialized = false; + + release_psp_cmd_buf(psp); return ret; } @@ -897,22 +885,23 @@ int psp_reg_program(struct psp_context *psp, enum psp_reg_prog_id reg, static void psp_prep_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, uint64_t ta_bin_mc, - struct ta_context *context) + uint32_t ta_bin_size, + uint64_t ta_shared_mc, + uint32_t ta_shared_size) { - cmd->cmd_id = context->ta_load_type; + cmd->cmd_id = GFX_CMD_ID_LOAD_TA; cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ta_bin_mc); cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ta_bin_mc); - cmd->cmd.cmd_load_ta.app_len = context->bin_desc.size_bytes; + cmd->cmd.cmd_load_ta.app_len = ta_bin_size; - cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = - lower_32_bits(context->mem_context.shared_mc_addr); - cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = - upper_32_bits(context->mem_context.shared_mc_addr); - cmd->cmd.cmd_load_ta.cmd_buf_len = context->mem_context.shared_mem_size; + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc); + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc); + cmd->cmd.cmd_load_ta.cmd_buf_len = ta_shared_size; } static int psp_ta_init_shared_buf(struct psp_context *psp, - struct ta_mem_context *mem_ctx) + struct ta_mem_context *mem_ctx, + uint32_t shared_mem_size) { int ret; @@ -920,8 +909,8 @@ static int psp_ta_init_shared_buf(struct psp_context *psp, * Allocate 16k memory aligned to 4k from Frame Buffer (local * physical) for ta to host memory */ - ret = amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, + ret = amdgpu_bo_create_kernel(psp->adev, shared_mem_size, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, &mem_ctx->shared_bo, &mem_ctx->shared_mc_addr, &mem_ctx->shared_buf); @@ -937,7 +926,8 @@ static void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx) static int psp_xgmi_init_shared_buf(struct psp_context *psp) { - return psp_ta_init_shared_buf(psp, &psp->xgmi_context.context.mem_context); + return psp_ta_init_shared_buf(psp, &psp->xgmi_context.context.mem_context, + PSP_XGMI_SHARED_MEM_SIZE); } static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, @@ -951,12 +941,12 @@ static void psp_prep_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd, static int psp_ta_invoke(struct psp_context *psp, uint32_t ta_cmd_id, - struct ta_context *context) + uint32_t session_id) { int ret; struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); - psp_prep_ta_invoke_cmd_buf(cmd, ta_cmd_id, context->session_id); + psp_prep_ta_invoke_cmd_buf(cmd, ta_cmd_id, session_id); ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); @@ -966,55 +956,73 @@ static int psp_ta_invoke(struct psp_context *psp, return ret; } -static int psp_ta_load(struct psp_context *psp, struct ta_context *context) -{ - int ret; - struct psp_gfx_cmd_resp *cmd; - - cmd = acquire_psp_cmd_buf(psp); - - psp_copy_fw(psp, context->bin_desc.start_addr, - context->bin_desc.size_bytes); - - psp_prep_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr, context); - - ret = psp_cmd_submit_buf(psp, NULL, cmd, - psp->fence_buf_mc_addr); - - if (!ret) { - context->session_id = cmd->resp.session_id; - } - - release_psp_cmd_buf(psp); - - return ret; -} - static int psp_xgmi_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->xgmi_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + + /* + * TODO: bypass the loading in sriov for now + */ + + cmd = acquire_psp_cmd_buf(psp); + + psp_copy_fw(psp, psp->xgmi.start_addr, psp->xgmi.size_bytes); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->xgmi.size_bytes, + psp->xgmi_context.context.mem_context.shared_mc_addr, + PSP_XGMI_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + + if (!ret) { + psp->xgmi_context.context.initialized = true; + psp->xgmi_context.context.session_id = cmd->resp.session_id; + } + + release_psp_cmd_buf(psp); + + return ret; } static int psp_xgmi_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->xgmi_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + struct amdgpu_device *adev = psp->adev; + + /* XGMI TA unload currently is not supported on Arcturus/Aldebaran A+A */ + if (adev->asic_type == CHIP_ARCTURUS || + (adev->asic_type == CHIP_ALDEBARAN && adev->gmc.xgmi.connected_to_cpu)) + return 0; + + /* + * TODO: bypass the unloading in sriov for now + */ + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->xgmi_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id) { - return psp_ta_invoke(psp, ta_cmd_id, &psp->xgmi_context.context); + return psp_ta_invoke(psp, ta_cmd_id, psp->xgmi_context.context.session_id); } int psp_xgmi_terminate(struct psp_context *psp) { int ret; - struct amdgpu_device *adev = psp->adev; - - /* XGMI TA unload currently is not supported on Arcturus/Aldebaran A+A */ - if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 4) || - (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2) && - adev->gmc.xgmi.connected_to_cpu)) - return 0; if (!psp->xgmi_context.context.initialized) return 0; @@ -1037,16 +1045,13 @@ int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool lo int ret; if (!psp->ta_fw || - !psp->xgmi_context.context.bin_desc.size_bytes || - !psp->xgmi_context.context.bin_desc.start_addr) + !psp->xgmi.size_bytes || + !psp->xgmi.start_addr) return -ENOENT; if (!load_ta) goto invoke; - psp->xgmi_context.context.mem_context.shared_mem_size = PSP_XGMI_SHARED_MEM_SIZE; - psp->xgmi_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->xgmi_context.context.initialized) { ret = psp_xgmi_init_shared_buf(psp); if (ret) @@ -1055,9 +1060,7 @@ int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool lo /* Load XGMI TA */ ret = psp_xgmi_load(psp); - if (!ret) - psp->xgmi_context.context.initialized = true; - else + if (ret) return ret; invoke: @@ -1114,8 +1117,8 @@ int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id) static bool psp_xgmi_peer_link_info_supported(struct psp_context *psp) { - return psp->adev->ip_versions[MP0_HWIP][0] == IP_VERSION(13, 0, 2) && - psp->xgmi_context.context.bin_desc.fw_version >= 0x2000000b; + return psp->adev->asic_type == CHIP_ALDEBARAN && + psp->xgmi.feature_version >= 0x2000000b; } /* @@ -1279,40 +1282,80 @@ int psp_xgmi_set_topology_info(struct psp_context *psp, // ras begin static int psp_ras_init_shared_buf(struct psp_context *psp) { - return psp_ta_init_shared_buf(psp, &psp->ras_context.context.mem_context); + return psp_ta_init_shared_buf(psp, &psp->ras_context.context.mem_context, + PSP_RAS_SHARED_MEM_SIZE); } static int psp_ras_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->ras_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + struct ta_ras_shared_memory *ras_cmd; + + /* + * TODO: bypass the loading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; + + psp_copy_fw(psp, psp->ras.start_addr, psp->ras.size_bytes); + + ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; + + if (psp->adev->gmc.xgmi.connected_to_cpu) + ras_cmd->ras_in_message.init_flags.poison_mode_en = 1; + else + ras_cmd->ras_in_message.init_flags.dgpu_mode = 1; + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->ras.size_bytes, + psp->ras_context.context.mem_context.shared_mc_addr, + PSP_RAS_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + + if (!ret) { + psp->ras_context.context.session_id = cmd->resp.session_id; + + if (!ras_cmd->ras_status) + psp->ras_context.context.initialized = true; + else + dev_warn(psp->adev->dev, "RAS Init Status: 0x%X\n", ras_cmd->ras_status); + } + + release_psp_cmd_buf(psp); + + if (ret || ras_cmd->ras_status) + amdgpu_ras_fini(psp->adev); + + return ret; } static int psp_ras_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->ras_context.context); -} + int ret; + struct psp_gfx_cmd_resp *cmd; -static void psp_ras_ta_check_status(struct psp_context *psp) -{ - struct ta_ras_shared_memory *ras_cmd = - (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; + /* + * TODO: bypass the unloading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; - switch (ras_cmd->ras_status) { - case TA_RAS_STATUS__ERROR_UNSUPPORTED_IP: - dev_warn(psp->adev->dev, - "RAS WARNING: cmd failed due to unsupported ip\n"); - break; - case TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ: - dev_warn(psp->adev->dev, - "RAS WARNING: cmd failed due to unsupported error injection\n"); - break; - case TA_RAS_STATUS__SUCCESS: - break; - default: - dev_warn(psp->adev->dev, - "RAS WARNING: ras status = 0x%X\n", ras_cmd->ras_status); - break; - } + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->ras_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, + psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id) @@ -1328,7 +1371,7 @@ int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id) if (amdgpu_sriov_vf(psp->adev)) return 0; - ret = psp_ta_invoke(psp, ta_cmd_id, &psp->ras_context.context); + ret = psp_ta_invoke(psp, ta_cmd_id, psp->ras_context.context.session_id); if (amdgpu_ras_intr_triggered()) return ret; @@ -1348,8 +1391,31 @@ int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id) else if (ras_cmd->ras_out_message.flags.reg_access_failure_flag) dev_warn(psp->adev->dev, "RAS internal register access blocked\n"); + } - psp_ras_ta_check_status(psp); + return ret; +} + +static int psp_ras_status_to_errno(struct amdgpu_device *adev, + enum ta_ras_status ras_status) +{ + int ret = -EINVAL; + + switch (ras_status) { + case TA_RAS_STATUS__SUCCESS: + ret = 0; + break; + case TA_RAS_STATUS__RESET_NEEDED: + ret = -EAGAIN; + break; + case TA_RAS_STATUS__ERROR_RAS_NOT_AVAILABLE: + dev_warn(adev->dev, "RAS WARN: ras function unavailable\n"); + break; + case TA_RAS_STATUS__ERROR_ASD_READ_WRITE: + dev_warn(adev->dev, "RAS WARN: asd read or write failed\n"); + break; + default: + dev_err(adev->dev, "RAS ERROR: ras function failed ret 0x%X\n", ret); } return ret; @@ -1378,7 +1444,7 @@ int psp_ras_enable_features(struct psp_context *psp, if (ret) return -EINVAL; - return 0; + return psp_ras_status_to_errno(psp->adev, ras_cmd->ras_status); } static int psp_ras_terminate(struct psp_context *psp) @@ -1411,7 +1477,6 @@ static int psp_ras_initialize(struct psp_context *psp) int ret; uint32_t boot_cfg = 0xFF; struct amdgpu_device *adev = psp->adev; - struct ta_ras_shared_memory *ras_cmd; /* * TODO: bypass the initialize in sriov for now @@ -1419,8 +1484,8 @@ static int psp_ras_initialize(struct psp_context *psp) if (amdgpu_sriov_vf(adev)) return 0; - if (!adev->psp.ras_context.context.bin_desc.size_bytes || - !adev->psp.ras_context.context.bin_desc.start_addr) { + if (!adev->psp.ras.size_bytes || + !adev->psp.ras.start_addr) { dev_info(adev->dev, "RAS: optional ras ta ucode is not available\n"); return 0; } @@ -1466,34 +1531,17 @@ static int psp_ras_initialize(struct psp_context *psp) } } - psp->ras_context.context.mem_context.shared_mem_size = PSP_RAS_SHARED_MEM_SIZE; - psp->ras_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->ras_context.context.initialized) { ret = psp_ras_init_shared_buf(psp); if (ret) return ret; } - ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; - memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory)); - - if (amdgpu_ras_is_poison_mode_supported(adev)) - ras_cmd->ras_in_message.init_flags.poison_mode_en = 1; - if (!adev->gmc.xgmi.connected_to_cpu) - ras_cmd->ras_in_message.init_flags.dgpu_mode = 1; - ret = psp_ras_load(psp); + if (ret) + return ret; - if (!ret && !ras_cmd->ras_status) - psp->ras_context.context.initialized = true; - else { - if (ras_cmd->ras_status) - dev_warn(psp->adev->dev, "RAS Init Status: 0x%X\n", ras_cmd->ras_status); - amdgpu_ras_fini(psp->adev); - } - - return ret; + return 0; } int psp_ras_trigger_error(struct psp_context *psp, @@ -1520,24 +1568,51 @@ int psp_ras_trigger_error(struct psp_context *psp, if (amdgpu_ras_intr_triggered()) return 0; - if (ras_cmd->ras_status) - return -EINVAL; - - return 0; + return psp_ras_status_to_errno(psp->adev, ras_cmd->ras_status); } // ras end // HDCP start static int psp_hdcp_init_shared_buf(struct psp_context *psp) { - return psp_ta_init_shared_buf(psp, &psp->hdcp_context.context.mem_context); + return psp_ta_init_shared_buf(psp, &psp->hdcp_context.context.mem_context, + PSP_HDCP_SHARED_MEM_SIZE); } static int psp_hdcp_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->hdcp_context.context); -} + int ret; + struct psp_gfx_cmd_resp *cmd; + /* + * TODO: bypass the loading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; + + psp_copy_fw(psp, psp->hdcp.start_addr, + psp->hdcp.size_bytes); + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->hdcp.size_bytes, + psp->hdcp_context.context.mem_context.shared_mc_addr, + PSP_HDCP_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + if (!ret) { + psp->hdcp_context.context.initialized = true; + psp->hdcp_context.context.session_id = cmd->resp.session_id; + mutex_init(&psp->hdcp_context.mutex); + } + + release_psp_cmd_buf(psp); + + return ret; +} static int psp_hdcp_initialize(struct psp_context *psp) { int ret; @@ -1548,15 +1623,12 @@ static int psp_hdcp_initialize(struct psp_context *psp) if (amdgpu_sriov_vf(psp->adev)) return 0; - if (!psp->hdcp_context.context.bin_desc.size_bytes || - !psp->hdcp_context.context.bin_desc.start_addr) { + if (!psp->hdcp.size_bytes || + !psp->hdcp.start_addr) { dev_info(psp->adev->dev, "HDCP: optional hdcp ta ucode is not available\n"); return 0; } - psp->hdcp_context.context.mem_context.shared_mem_size = PSP_HDCP_SHARED_MEM_SIZE; - psp->hdcp_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->hdcp_context.context.initialized) { ret = psp_hdcp_init_shared_buf(psp); if (ret) @@ -1564,17 +1636,32 @@ static int psp_hdcp_initialize(struct psp_context *psp) } ret = psp_hdcp_load(psp); - if (!ret) { - psp->hdcp_context.context.initialized = true; - mutex_init(&psp->hdcp_context.mutex); - } + if (ret) + return ret; - return ret; + return 0; } static int psp_hdcp_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->hdcp_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + + /* + * TODO: bypass the unloading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->hdcp_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id) @@ -1585,7 +1672,7 @@ int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id) if (amdgpu_sriov_vf(psp->adev)) return 0; - return psp_ta_invoke(psp, ta_cmd_id, &psp->hdcp_context.context); + return psp_ta_invoke(psp, ta_cmd_id, psp->hdcp_context.context.session_id); } static int psp_hdcp_terminate(struct psp_context *psp) @@ -1622,12 +1709,42 @@ static int psp_hdcp_terminate(struct psp_context *psp) // DTM start static int psp_dtm_init_shared_buf(struct psp_context *psp) { - return psp_ta_init_shared_buf(psp, &psp->dtm_context.context.mem_context); + return psp_ta_init_shared_buf(psp, &psp->dtm_context.context.mem_context, + PSP_DTM_SHARED_MEM_SIZE); } static int psp_dtm_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->dtm_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + + /* + * TODO: bypass the loading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; + + psp_copy_fw(psp, psp->dtm.start_addr, psp->dtm.size_bytes); + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->dtm.size_bytes, + psp->dtm_context.context.mem_context.shared_mc_addr, + PSP_DTM_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + if (!ret) { + psp->dtm_context.context.initialized = true; + psp->dtm_context.context.session_id = cmd->resp.session_id; + mutex_init(&psp->dtm_context.mutex); + } + + release_psp_cmd_buf(psp); + + return ret; } static int psp_dtm_initialize(struct psp_context *psp) @@ -1640,15 +1757,12 @@ static int psp_dtm_initialize(struct psp_context *psp) if (amdgpu_sriov_vf(psp->adev)) return 0; - if (!psp->dtm_context.context.bin_desc.size_bytes || - !psp->dtm_context.context.bin_desc.start_addr) { + if (!psp->dtm.size_bytes || + !psp->dtm.start_addr) { dev_info(psp->adev->dev, "DTM: optional dtm ta ucode is not available\n"); return 0; } - psp->dtm_context.context.mem_context.shared_mem_size = PSP_DTM_SHARED_MEM_SIZE; - psp->dtm_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->dtm_context.context.initialized) { ret = psp_dtm_init_shared_buf(psp); if (ret) @@ -1656,17 +1770,32 @@ static int psp_dtm_initialize(struct psp_context *psp) } ret = psp_dtm_load(psp); - if (!ret) { - psp->dtm_context.context.initialized = true; - mutex_init(&psp->dtm_context.mutex); - } + if (ret) + return ret; - return ret; + return 0; } static int psp_dtm_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->dtm_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + + /* + * TODO: bypass the unloading in sriov for now + */ + if (amdgpu_sriov_vf(psp->adev)) + return 0; + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->dtm_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id) @@ -1677,7 +1806,7 @@ int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id) if (amdgpu_sriov_vf(psp->adev)) return 0; - return psp_ta_invoke(psp, ta_cmd_id, &psp->dtm_context.context); + return psp_ta_invoke(psp, ta_cmd_id, psp->dtm_context.context.session_id); } static int psp_dtm_terminate(struct psp_context *psp) @@ -1714,17 +1843,50 @@ static int psp_dtm_terminate(struct psp_context *psp) // RAP start static int psp_rap_init_shared_buf(struct psp_context *psp) { - return psp_ta_init_shared_buf(psp, &psp->rap_context.context.mem_context); + return psp_ta_init_shared_buf(psp, &psp->rap_context.context.mem_context, + PSP_RAP_SHARED_MEM_SIZE); } static int psp_rap_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->rap_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd; + + psp_copy_fw(psp, psp->rap.start_addr, psp->rap.size_bytes); + + cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->rap.size_bytes, + psp->rap_context.context.mem_context.shared_mc_addr, + PSP_RAP_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + if (!ret) { + psp->rap_context.context.initialized = true; + psp->rap_context.context.session_id = cmd->resp.session_id; + mutex_init(&psp->rap_context.mutex); + } + + release_psp_cmd_buf(psp); + + return ret; } static int psp_rap_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->rap_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->rap_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } static int psp_rap_initialize(struct psp_context *psp) @@ -1738,15 +1900,12 @@ static int psp_rap_initialize(struct psp_context *psp) if (amdgpu_sriov_vf(psp->adev)) return 0; - if (!psp->rap_context.context.bin_desc.size_bytes || - !psp->rap_context.context.bin_desc.start_addr) { + if (!psp->rap.size_bytes || + !psp->rap.start_addr) { dev_info(psp->adev->dev, "RAP: optional rap ta ucode is not available\n"); return 0; } - psp->rap_context.context.mem_context.shared_mem_size = PSP_RAP_SHARED_MEM_SIZE; - psp->rap_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->rap_context.context.initialized) { ret = psp_rap_init_shared_buf(psp); if (ret) @@ -1754,15 +1913,16 @@ static int psp_rap_initialize(struct psp_context *psp) } ret = psp_rap_load(psp); - if (!ret) { - psp->rap_context.context.initialized = true; - mutex_init(&psp->rap_context.mutex); - } else + if (ret) return ret; ret = psp_rap_invoke(psp, TA_CMD_RAP__INITIALIZE, &status); if (ret || status != TA_RAP_STATUS__SUCCESS) { - psp_rap_terminate(psp); + psp_rap_unload(psp); + + psp_ta_free_shared_buf(&psp->rap_context.context.mem_context); + + psp->rap_context.context.initialized = false; dev_warn(psp->adev->dev, "RAP TA initialize fail (%d) status %d.\n", ret, status); @@ -1811,7 +1971,7 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_stat rap_cmd->cmd_id = ta_cmd_id; rap_cmd->validation_method_id = METHOD_A; - ret = psp_ta_invoke(psp, rap_cmd->cmd_id, &psp->rap_context.context); + ret = psp_ta_invoke(psp, rap_cmd->cmd_id, psp->rap_context.context.session_id); if (ret) goto out_unlock; @@ -1829,17 +1989,49 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_stat static int psp_securedisplay_init_shared_buf(struct psp_context *psp) { return psp_ta_init_shared_buf( - psp, &psp->securedisplay_context.context.mem_context); + psp, &psp->securedisplay_context.context.mem_context, + PSP_SECUREDISPLAY_SHARED_MEM_SIZE); } static int psp_securedisplay_load(struct psp_context *psp) { - return psp_ta_load(psp, &psp->securedisplay_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); + + memset(psp->fw_pri_buf, 0, PSP_1_MEG); + memcpy(psp->fw_pri_buf, psp->securedisplay.start_addr, psp->securedisplay.size_bytes); + + psp_prep_ta_load_cmd_buf(cmd, + psp->fw_pri_mc_addr, + psp->securedisplay.size_bytes, + psp->securedisplay_context.context.mem_context.shared_mc_addr, + PSP_SECUREDISPLAY_SHARED_MEM_SIZE); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + if (!ret) { + psp->securedisplay_context.context.initialized = true; + psp->securedisplay_context.context.session_id = cmd->resp.session_id; + mutex_init(&psp->securedisplay_context.mutex); + } + + release_psp_cmd_buf(psp); + + return ret; } static int psp_securedisplay_unload(struct psp_context *psp) { - return psp_ta_unload(psp, &psp->securedisplay_context.context); + int ret; + struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); + + psp_prep_ta_unload_cmd_buf(cmd, psp->securedisplay_context.context.session_id); + + ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); + + release_psp_cmd_buf(psp); + + return ret; } static int psp_securedisplay_initialize(struct psp_context *psp) @@ -1853,16 +2045,12 @@ static int psp_securedisplay_initialize(struct psp_context *psp) if (amdgpu_sriov_vf(psp->adev)) return 0; - if (!psp->securedisplay_context.context.bin_desc.size_bytes || - !psp->securedisplay_context.context.bin_desc.start_addr) { + if (!psp->securedisplay.size_bytes || + !psp->securedisplay.start_addr) { dev_info(psp->adev->dev, "SECUREDISPLAY: securedisplay ta ucode is not available\n"); return 0; } - psp->securedisplay_context.context.mem_context.shared_mem_size = - PSP_SECUREDISPLAY_SHARED_MEM_SIZE; - psp->securedisplay_context.context.ta_load_type = GFX_CMD_ID_LOAD_TA; - if (!psp->securedisplay_context.context.initialized) { ret = psp_securedisplay_init_shared_buf(psp); if (ret) @@ -1870,10 +2058,7 @@ static int psp_securedisplay_initialize(struct psp_context *psp) } ret = psp_securedisplay_load(psp); - if (!ret) { - psp->securedisplay_context.context.initialized = true; - mutex_init(&psp->securedisplay_context.mutex); - } else + if (ret) return ret; psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, @@ -1881,7 +2066,12 @@ static int psp_securedisplay_initialize(struct psp_context *psp) ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA); if (ret) { - psp_securedisplay_terminate(psp); + psp_securedisplay_unload(psp); + + psp_ta_free_shared_buf(&psp->securedisplay_context.context.mem_context); + + psp->securedisplay_context.context.initialized = false; + dev_err(psp->adev->dev, "SECUREDISPLAY TA initialize fail.\n"); return -EINVAL; } @@ -1933,7 +2123,7 @@ int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id) mutex_lock(&psp->securedisplay_context.mutex); - ret = psp_ta_invoke(psp, ta_cmd_id, &psp->securedisplay_context.context); + ret = psp_ta_invoke(psp, ta_cmd_id, psp->securedisplay_context.context.session_id); mutex_unlock(&psp->securedisplay_context.mutex); @@ -2257,8 +2447,8 @@ static int psp_load_smu_fw(struct psp_context *psp) if ((amdgpu_in_reset(adev) && ras && adev->ras_enabled && - (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 4) || - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 2)))) { + (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_VEGA20))) { ret = amdgpu_dpm_set_mp1_state(adev, PP_MP1_STATE_UNLOAD); if (ret) { DRM_WARN("Failed to set MP1 state prepare for reload\n"); @@ -2355,9 +2545,8 @@ static int psp_load_non_psp_fw(struct psp_context *psp) continue; if (psp->autoload_supported && - (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7) || - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 11) || - adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 12)) && + (adev->asic_type >= CHIP_SIENNA_CICHLID && + adev->asic_type <= CHIP_DIMGREY_CAVEFISH) && (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 || ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3)) @@ -2444,7 +2633,7 @@ static int psp_load_fw(struct amdgpu_device *adev) if (ret) goto failed; - ret = psp_asd_initialize(psp); + ret = psp_asd_load(psp); if (ret) { DRM_ERROR("PSP load asd failed!\n"); return ret; @@ -2456,18 +2645,6 @@ static int psp_load_fw(struct amdgpu_device *adev) return ret; } - if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) { - if (adev->gmc.xgmi.num_physical_nodes > 1) { - ret = psp_xgmi_initialize(psp, false, true); - /* Warning the XGMI seesion initialize failure - * Instead of stop driver initialization - */ - if (ret) - dev_err(psp->adev->dev, - "XGMI: Failed to initialize XGMI session\n"); - } - } - if (psp->ta_fw) { ret = psp_ras_initialize(psp); if (ret) @@ -2548,7 +2725,7 @@ static int psp_hw_fini(void *handle) psp_hdcp_terminate(psp); } - psp_asd_terminate(psp); + psp_asd_unload(psp); psp_tmr_terminate(psp); psp_ring_destroy(psp, PSP_RING_TYPE__KM); @@ -2606,9 +2783,9 @@ static int psp_suspend(void *handle) } } - ret = psp_asd_terminate(psp); + ret = psp_asd_unload(psp); if (ret) { - DRM_ERROR("Failed to terminate asd\n"); + DRM_ERROR("Failed to unload asd\n"); return ret; } @@ -2653,18 +2830,12 @@ static int psp_resume(void *handle) if (ret) goto failed; - ret = psp_asd_initialize(psp); + ret = psp_asd_load(psp); if (ret) { DRM_ERROR("PSP load asd failed!\n"); goto failed; } - ret = psp_rl_load(adev); - if (ret) { - dev_err(adev->dev, "PSP load RL failed!\n"); - goto failed; - } - if (adev->gmc.xgmi.num_physical_nodes > 1) { ret = psp_xgmi_initialize(psp, false, true); /* Warning the XGMI seesion initialize failure @@ -2827,10 +2998,10 @@ int psp_init_asd_microcode(struct psp_context *psp, goto out; asd_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.asd_fw->data; - adev->psp.asd_context.bin_desc.fw_version = le32_to_cpu(asd_hdr->header.ucode_version); - adev->psp.asd_context.bin_desc.feature_version = le32_to_cpu(asd_hdr->sos.fw_version); - adev->psp.asd_context.bin_desc.size_bytes = le32_to_cpu(asd_hdr->header.ucode_size_bytes); - adev->psp.asd_context.bin_desc.start_addr = (uint8_t *)asd_hdr + + adev->psp.asd.fw_version = le32_to_cpu(asd_hdr->header.ucode_version); + adev->psp.asd.feature_version = le32_to_cpu(asd_hdr->sos.fw_version); + adev->psp.asd.size_bytes = le32_to_cpu(asd_hdr->header.ucode_size_bytes); + adev->psp.asd.start_addr = (uint8_t *)asd_hdr + le32_to_cpu(asd_hdr->header.ucode_array_offset_bytes); return 0; out: @@ -2962,8 +3133,7 @@ static int psp_init_sos_base_fw(struct amdgpu_device *adev) ucode_array_start_addr = (uint8_t *)sos_hdr + le32_to_cpu(sos_hdr->header.ucode_array_offset_bytes); - if (adev->gmc.xgmi.connected_to_cpu || - (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2))) { + if (adev->gmc.xgmi.connected_to_cpu || (adev->asic_type != CHIP_ALDEBARAN)) { adev->psp.sos.fw_version = le32_to_cpu(sos_hdr->header.ucode_version); adev->psp.sos.feature_version = le32_to_cpu(sos_hdr->sos.fw_version); @@ -3118,43 +3288,40 @@ static int parse_ta_bin_descriptor(struct psp_context *psp, switch (desc->fw_type) { case TA_FW_TYPE_PSP_ASD: - psp->asd_context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->asd_context.bin_desc.feature_version = le32_to_cpu(desc->fw_version); - psp->asd_context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->asd_context.bin_desc.start_addr = ucode_start_addr; + psp->asd.fw_version = le32_to_cpu(desc->fw_version); + psp->asd.feature_version = le32_to_cpu(desc->fw_version); + psp->asd.size_bytes = le32_to_cpu(desc->size_bytes); + psp->asd.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_XGMI: - psp->xgmi_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->xgmi_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->xgmi_context.context.bin_desc.start_addr = ucode_start_addr; + psp->xgmi.feature_version = le32_to_cpu(desc->fw_version); + psp->xgmi.size_bytes = le32_to_cpu(desc->size_bytes); + psp->xgmi.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_RAS: - psp->ras_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->ras_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->ras_context.context.bin_desc.start_addr = ucode_start_addr; + psp->ras.feature_version = le32_to_cpu(desc->fw_version); + psp->ras.size_bytes = le32_to_cpu(desc->size_bytes); + psp->ras.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_HDCP: - psp->hdcp_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->hdcp_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->hdcp_context.context.bin_desc.start_addr = ucode_start_addr; + psp->hdcp.feature_version = le32_to_cpu(desc->fw_version); + psp->hdcp.size_bytes = le32_to_cpu(desc->size_bytes); + psp->hdcp.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_DTM: - psp->dtm_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->dtm_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->dtm_context.context.bin_desc.start_addr = ucode_start_addr; + psp->dtm.feature_version = le32_to_cpu(desc->fw_version); + psp->dtm.size_bytes = le32_to_cpu(desc->size_bytes); + psp->dtm.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_RAP: - psp->rap_context.context.bin_desc.fw_version = le32_to_cpu(desc->fw_version); - psp->rap_context.context.bin_desc.size_bytes = le32_to_cpu(desc->size_bytes); - psp->rap_context.context.bin_desc.start_addr = ucode_start_addr; + psp->rap.feature_version = le32_to_cpu(desc->fw_version); + psp->rap.size_bytes = le32_to_cpu(desc->size_bytes); + psp->rap.start_addr = ucode_start_addr; break; case TA_FW_TYPE_PSP_SECUREDISPLAY: - psp->securedisplay_context.context.bin_desc.fw_version = - le32_to_cpu(desc->fw_version); - psp->securedisplay_context.context.bin_desc.size_bytes = - le32_to_cpu(desc->size_bytes); - psp->securedisplay_context.context.bin_desc.start_addr = - ucode_start_addr; + psp->securedisplay.feature_version = le32_to_cpu(desc->fw_version); + psp->securedisplay.size_bytes = le32_to_cpu(desc->size_bytes); + psp->securedisplay.start_addr = ucode_start_addr; break; default: dev_warn(psp->adev->dev, "Unsupported TA type: %d\n", desc->fw_type); @@ -3315,7 +3482,7 @@ void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size { int idx; - if (!drm_dev_enter(adev_to_drm(psp->adev), &idx)) + if (!drm_dev_enter(&psp->adev->ddev, &idx)) return; memset(psp->fw_pri_buf, 0, PSP_1_MEG); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index f29afabbff..8ef2d28af9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -34,20 +34,17 @@ #define PSP_FENCE_BUFFER_SIZE 0x1000 #define PSP_CMD_BUFFER_SIZE 0x1000 +#define PSP_XGMI_SHARED_MEM_SIZE 0x4000 +#define PSP_RAS_SHARED_MEM_SIZE 0x4000 #define PSP_1_MEG 0x100000 #define PSP_TMR_SIZE(adev) ((adev)->asic_type == CHIP_ALDEBARAN ? 0x800000 : 0x400000) +#define PSP_HDCP_SHARED_MEM_SIZE 0x4000 +#define PSP_DTM_SHARED_MEM_SIZE 0x4000 +#define PSP_RAP_SHARED_MEM_SIZE 0x4000 +#define PSP_SECUREDISPLAY_SHARED_MEM_SIZE 0x4000 +#define PSP_SHARED_MEM_SIZE 0x4000 #define PSP_FW_NAME_LEN 0x24 -enum psp_shared_mem_size { - PSP_ASD_SHARED_MEM_SIZE = 0x0, - PSP_XGMI_SHARED_MEM_SIZE = 0x4000, - PSP_RAS_SHARED_MEM_SIZE = 0x4000, - PSP_HDCP_SHARED_MEM_SIZE = 0x4000, - PSP_DTM_SHARED_MEM_SIZE = 0x4000, - PSP_RAP_SHARED_MEM_SIZE = 0x4000, - PSP_SECUREDISPLAY_SHARED_MEM_SIZE = 0x4000, -}; - struct psp_context; struct psp_xgmi_node_info; struct psp_xgmi_topology_info; @@ -134,26 +131,21 @@ struct psp_xgmi_topology_info { struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES]; }; -struct psp_bin_desc { - uint32_t fw_version; - uint32_t feature_version; - uint32_t size_bytes; - uint8_t *start_addr; +struct psp_asd_context { + bool asd_initialized; + uint32_t session_id; }; struct ta_mem_context { struct amdgpu_bo *shared_bo; uint64_t shared_mc_addr; void *shared_buf; - enum psp_shared_mem_size shared_mem_size; }; struct ta_context { bool initialized; uint32_t session_id; struct ta_mem_context mem_context; - struct psp_bin_desc bin_desc; - enum psp_gfx_cmd_id ta_load_type; }; struct ta_cp_context { @@ -271,6 +263,13 @@ struct psp_runtime_boot_cfg_entry { uint32_t reserved; }; +struct psp_bin_desc { + uint32_t fw_version; + uint32_t feature_version; + uint32_t size_bytes; + uint8_t *start_addr; +}; + struct psp_context { struct amdgpu_device *adev; @@ -302,6 +301,7 @@ struct psp_context /* asd firmware */ const struct firmware *asd_fw; + struct psp_bin_desc asd; /* toc firmware */ const struct firmware *toc_fw; @@ -326,8 +326,14 @@ struct psp_context /* xgmi ta firmware and buffer */ const struct firmware *ta_fw; uint32_t ta_fw_version; + struct psp_bin_desc xgmi; + struct psp_bin_desc ras; + struct psp_bin_desc hdcp; + struct psp_bin_desc dtm; + struct psp_bin_desc rap; + struct psp_bin_desc securedisplay; - struct ta_context asd_context; + struct psp_asd_context asd_context; struct psp_xgmi_context xgmi_context; struct psp_ras_context ras_context; struct ta_cp_context hdcp_context; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 8f47c14ecb..96a8fd0ca1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -35,11 +35,7 @@ #include "amdgpu_xgmi.h" #include "ivsrcid/nbio/irqsrcs_nbif_7_4.h" #include "atom.h" -#ifdef CONFIG_X86_MCE_AMD -#include -static bool notifier_registered; -#endif static const char *RAS_FS_NAME = "ras"; const char *ras_error_string[] = { @@ -65,30 +61,8 @@ const char *ras_block_string[] = { "mp0", "mp1", "fuse", - "mca", }; -const char *ras_mca_block_string[] = { - "mca_mp0", - "mca_mp1", - "mca_mpio", - "mca_iohc", -}; - -const char *get_ras_block_str(struct ras_common_if *ras_block) -{ - if (!ras_block) - return "NULL"; - - if (ras_block->block >= AMDGPU_RAS_BLOCK_COUNT) - return "OUT OF RANGE"; - - if (ras_block->block == AMDGPU_RAS_BLOCK__MCA) - return ras_mca_block_string[ras_block->sub_block_index]; - - return ras_block_string[ras_block->block]; -} - #define ras_err_str(i) (ras_error_string[ffs(i)]) #define RAS_DEFAULT_FLAGS (AMDGPU_RAS_FLAG_INIT_BY_VBIOS) @@ -111,14 +85,6 @@ static bool amdgpu_ras_check_bad_page_unlock(struct amdgpu_ras *con, uint64_t addr); static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, uint64_t addr); -#ifdef CONFIG_X86_MCE_AMD -static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev); -struct mce_notifier_adev_list { - struct amdgpu_device *devs[MAX_GPU_INSTANCE]; - int num_gpu; -}; -static struct mce_notifier_adev_list mce_adev_list; -#endif void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready) { @@ -221,7 +187,7 @@ static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id) for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) { *block_id = i; - if (strcmp(name, ras_block_string[i]) == 0) + if (strcmp(name, ras_block_str(i)) == 0) return 0; } return -EINVAL; @@ -543,6 +509,7 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev, if (amdgpu_ras_query_error_status(obj->adev, &info)) return -EINVAL; + if (obj->adev->asic_type == CHIP_ALDEBARAN) { if (amdgpu_ras_reset_error_status(obj->adev, info.head.block)) DRM_WARN("Failed to reset error counter and error status"); @@ -562,7 +529,7 @@ static inline void put_obj(struct ras_manager *obj) if (obj && (--obj->use == 0)) list_del(&obj->node); if (obj && (obj->use < 0)) - DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", get_ras_block_str(&obj->head)); + DRM_ERROR("RAS ERROR: Unbalance obj(%s) use\n", ras_block_str(obj->head.block)); } /* make one obj and return it. */ @@ -578,14 +545,7 @@ static struct ras_manager *amdgpu_ras_create_obj(struct amdgpu_device *adev, if (head->block >= AMDGPU_RAS_BLOCK_COUNT) return NULL; - if (head->block == AMDGPU_RAS_BLOCK__MCA) { - if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST) - return NULL; - - obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index]; - } else - obj = &con->objs[head->block]; - + obj = &con->objs[head->block]; /* already exist. return obj? */ if (alive_obj(obj)) return NULL; @@ -613,21 +573,19 @@ struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev, if (head->block >= AMDGPU_RAS_BLOCK_COUNT) return NULL; - if (head->block == AMDGPU_RAS_BLOCK__MCA) { - if (head->sub_block_index >= AMDGPU_RAS_MCA_BLOCK__LAST) - return NULL; + obj = &con->objs[head->block]; - obj = &con->objs[AMDGPU_RAS_BLOCK__LAST + head->sub_block_index]; - } else - obj = &con->objs[head->block]; - - if (alive_obj(obj)) + if (alive_obj(obj)) { + WARN_ON(head->block != obj->head.block); return obj; + } } else { - for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT + AMDGPU_RAS_MCA_BLOCK_COUNT; i++) { + for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT; i++) { obj = &con->objs[i]; - if (alive_obj(obj)) + if (alive_obj(obj)) { + WARN_ON(i != obj->head.block); return obj; + } } } @@ -668,6 +626,8 @@ static int __amdgpu_ras_feature_enable(struct amdgpu_device *adev, */ if (!amdgpu_ras_is_feature_allowed(adev, head)) return 0; + if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head))) + return 0; if (enable) { if (!obj) { @@ -718,14 +678,19 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, /* Do not enable if it is not allowed. */ WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head)); + /* Are we alerady in that state we are going to set? */ + if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head))) { + ret = 0; + goto out; + } if (!amdgpu_ras_intr_triggered()) { ret = psp_ras_enable_features(&adev->psp, info, enable); if (ret) { - dev_err(adev->dev, "ras %s %s failed poison:%d ret:%d\n", + dev_err(adev->dev, "ras %s %s failed %d\n", enable ? "enable":"disable", - get_ras_block_str(head), - amdgpu_ras_is_poison_mode_supported(adev), ret); + ras_block_str(head->block), + ret); goto out; } } @@ -766,7 +731,7 @@ int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev, if (!ret) dev_info(adev->dev, "RAS INFO: %s setup object\n", - get_ras_block_str(head)); + ras_block_str(head->block)); } } else { /* setup the object then issue a ras TA disable cmd.*/ @@ -816,39 +781,17 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev, bool bypass) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + int ras_block_count = AMDGPU_RAS_BLOCK_COUNT; int i; - const enum amdgpu_ras_error_type default_ras_type = AMDGPU_RAS_ERROR__NONE; + const enum amdgpu_ras_error_type default_ras_type = + AMDGPU_RAS_ERROR__NONE; - for (i = 0; i < AMDGPU_RAS_BLOCK_COUNT; i++) { + for (i = 0; i < ras_block_count; i++) { struct ras_common_if head = { .block = i, .type = default_ras_type, .sub_block_index = 0, }; - - if (i == AMDGPU_RAS_BLOCK__MCA) - continue; - - if (bypass) { - /* - * bypass psp. vbios enable ras for us. - * so just create the obj - */ - if (__amdgpu_ras_feature_enable(adev, &head, 1)) - break; - } else { - if (amdgpu_ras_feature_enable(adev, &head, 1)) - break; - } - } - - for (i = 0; i < AMDGPU_RAS_MCA_BLOCK_COUNT; i++) { - struct ras_common_if head = { - .block = AMDGPU_RAS_BLOCK__MCA, - .type = default_ras_type, - .sub_block_index = i, - }; - if (bypass) { /* * bypass psp. vbios enable ras for us. @@ -866,64 +809,6 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev, } /* feature ctl end */ - -static void amdgpu_ras_mca_query_error_status(struct amdgpu_device *adev, - struct ras_common_if *ras_block, - struct ras_err_data *err_data) -{ - switch (ras_block->sub_block_index) { - case AMDGPU_RAS_MCA_BLOCK__MP0: - if (adev->mca.mp0.ras_funcs && - adev->mca.mp0.ras_funcs->query_ras_error_count) - adev->mca.mp0.ras_funcs->query_ras_error_count(adev, &err_data); - break; - case AMDGPU_RAS_MCA_BLOCK__MP1: - if (adev->mca.mp1.ras_funcs && - adev->mca.mp1.ras_funcs->query_ras_error_count) - adev->mca.mp1.ras_funcs->query_ras_error_count(adev, &err_data); - break; - case AMDGPU_RAS_MCA_BLOCK__MPIO: - if (adev->mca.mpio.ras_funcs && - adev->mca.mpio.ras_funcs->query_ras_error_count) - adev->mca.mpio.ras_funcs->query_ras_error_count(adev, &err_data); - break; - default: - break; - } -} - -static void amdgpu_ras_get_ecc_info(struct amdgpu_device *adev, struct ras_err_data *err_data) -{ - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - int ret = 0; - - /* - * choosing right query method according to - * whether smu support query error information - */ - ret = smu_get_ecc_info(&adev->smu, (void *)&(ras->umc_ecc)); - if (ret == -EOPNOTSUPP) { - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->query_ras_error_count) - adev->umc.ras_funcs->query_ras_error_count(adev, err_data); - - /* umc query_ras_error_address is also responsible for clearing - * error status - */ - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->query_ras_error_address) - adev->umc.ras_funcs->query_ras_error_address(adev, err_data); - } else if (!ret) { - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->ecc_info_query_ras_error_count) - adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, err_data); - - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->ecc_info_query_ras_error_address) - adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, err_data); - } -} - /* query/inject/cure begin */ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, struct ras_query_if *info) @@ -937,7 +822,15 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, switch (info->head.block) { case AMDGPU_RAS_BLOCK__UMC: - amdgpu_ras_get_ecc_info(adev, &err_data); + if (adev->umc.ras_funcs && + adev->umc.ras_funcs->query_ras_error_count) + adev->umc.ras_funcs->query_ras_error_count(adev, &err_data); + /* umc query_ras_error_address is also responsible for clearing + * error status + */ + if (adev->umc.ras_funcs && + adev->umc.ras_funcs->query_ras_error_address) + adev->umc.ras_funcs->query_ras_error_address(adev, &err_data); break; case AMDGPU_RAS_BLOCK__SDMA: if (adev->sdma.funcs->query_ras_error_count) { @@ -979,9 +872,6 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, adev->hdp.ras_funcs->query_ras_error_count) adev->hdp.ras_funcs->query_ras_error_count(adev, &err_data); break; - case AMDGPU_RAS_BLOCK__MCA: - amdgpu_ras_mca_query_error_status(adev, &info->head, &err_data); - break; default: break; } @@ -1003,13 +893,13 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, adev->smuio.funcs->get_socket_id(adev), adev->smuio.funcs->get_die_id(adev), obj->err_data.ce_count, - get_ras_block_str(&info->head)); + ras_block_str(info->head.block)); } else { dev_info(adev->dev, "%ld correctable hardware errors " "detected in %s block, no user " "action is needed.\n", obj->err_data.ce_count, - get_ras_block_str(&info->head)); + ras_block_str(info->head.block)); } } if (err_data.ue_count) { @@ -1022,18 +912,15 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, adev->smuio.funcs->get_socket_id(adev), adev->smuio.funcs->get_die_id(adev), obj->err_data.ue_count, - get_ras_block_str(&info->head)); + ras_block_str(info->head.block)); } else { dev_info(adev->dev, "%ld uncorrectable hardware errors " "detected in %s block\n", obj->err_data.ue_count, - get_ras_block_str(&info->head)); + ras_block_str(info->head.block)); } } - if (!amdgpu_persistent_edc_harvesting_supported(adev)) - amdgpu_ras_reset_error_status(adev, info->head.block); - return 0; } @@ -1140,7 +1027,6 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev, case AMDGPU_RAS_BLOCK__SDMA: case AMDGPU_RAS_BLOCK__MMHUB: case AMDGPU_RAS_BLOCK__PCIE_BIF: - case AMDGPU_RAS_BLOCK__MCA: ret = psp_ras_trigger_error(&adev->psp, &block_info); break; case AMDGPU_RAS_BLOCK__XGMI_WAFL: @@ -1148,22 +1034,22 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev, break; default: dev_info(adev->dev, "%s error injection is not supported yet\n", - get_ras_block_str(&info->head)); + ras_block_str(info->head.block)); ret = -EINVAL; } if (ret) dev_err(adev->dev, "ras inject %s failed %d\n", - get_ras_block_str(&info->head), ret); + ras_block_str(info->head.block), ret); return ret; } /** * amdgpu_ras_query_error_count -- Get error counts of all IPs - * @adev: pointer to AMD GPU device - * @ce_count: pointer to an integer to be set to the count of correctible errors. - * @ue_count: pointer to an integer to be set to the count of uncorrectible + * adev: pointer to AMD GPU device + * ce_count: pointer to an integer to be set to the count of correctible errors. + * ue_count: pointer to an integer to be set to the count of uncorrectible * errors. * * If set, @ce_count or @ue_count, count and return the corresponding @@ -1497,7 +1383,7 @@ void amdgpu_ras_debugfs_create_all(struct amdgpu_device *adev) if (amdgpu_ras_is_supported(adev, obj->head.block) && (obj->attr_inuse == 1)) { sprintf(fs_info.debugfs_name, "%s_err_inject", - get_ras_block_str(&obj->head)); + ras_block_str(obj->head.block)); fs_info.head = obj->head; amdgpu_ras_debugfs_create(adev, &fs_info, dir); } @@ -1583,29 +1469,22 @@ static void amdgpu_ras_interrupt_handler(struct ras_manager *obj) data->rptr = (data->aligned_element_size + data->rptr) % data->ring_size; + /* Let IP handle its data, maybe we need get the output + * from the callback to udpate the error type/count, etc + */ if (data->cb) { - if (amdgpu_ras_is_poison_mode_supported(obj->adev) && - obj->head.block == AMDGPU_RAS_BLOCK__UMC) - dev_info(obj->adev->dev, - "Poison is created, no user action is needed.\n"); - else { - /* Let IP handle its data, maybe we need get the output - * from the callback to udpate the error type/count, etc + ret = data->cb(obj->adev, &err_data, &entry); + /* ue will trigger an interrupt, and in that case + * we need do a reset to recovery the whole system. + * But leave IP do that recovery, here we just dispatch + * the error. + */ + if (ret == AMDGPU_RAS_SUCCESS) { + /* these counts could be left as 0 if + * some blocks do not count error number */ - memset(&err_data, 0, sizeof(err_data)); - ret = data->cb(obj->adev, &err_data, &entry); - /* ue will trigger an interrupt, and in that case - * we need do a reset to recovery the whole system. - * But leave IP do that recovery, here we just dispatch - * the error. - */ - if (ret == AMDGPU_RAS_SUCCESS) { - /* these counts could be left as 0 if - * some blocks do not count error number - */ - obj->err_data.ue_count += err_data.ue_count; - obj->err_data.ce_count += err_data.ce_count; - } + obj->err_data.ue_count += err_data.ue_count; + obj->err_data.ce_count += err_data.ce_count; } } } @@ -1748,16 +1627,6 @@ static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev) if (info.head.block == AMDGPU_RAS_BLOCK__PCIE_BIF) continue; - /* - * this is a workaround for aldebaran, skip send msg to - * smu to get ecc_info table due to smu handle get ecc - * info table failed temporarily. - * should be removed until smu fix handle ecc_info table. - */ - if ((info.head.block == AMDGPU_RAS_BLOCK__UMC) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2))) - continue; - amdgpu_ras_query_error_status(adev, &info); } } @@ -1839,7 +1708,8 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev, .size = AMDGPU_GPU_PAGE_SIZE, .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, }; - status = amdgpu_vram_mgr_query_page_status(&adev->mman.vram_mgr, + status = amdgpu_vram_mgr_query_page_status( + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), data->bps[i].retired_page); if (status == -EBUSY) (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; @@ -1940,7 +1810,8 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, goto out; } - amdgpu_vram_mgr_reserve_range(&adev->mman.vram_mgr, + amdgpu_vram_mgr_reserve_range( + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), bps[i].retired_page << AMDGPU_GPU_PAGE_SHIFT, AMDGPU_GPU_PAGE_SIZE); @@ -1968,11 +1839,9 @@ int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev) if (!con || !con->eh_data) return 0; - mutex_lock(&con->recovery_lock); control = &con->eeprom_control; data = con->eh_data; save_count = data->count - control->ras_num_recs; - mutex_unlock(&con->recovery_lock); /* only new entries are saved */ if (save_count > 0) { if (amdgpu_ras_eeprom_append(control, @@ -2145,11 +2014,6 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev) adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs); } -#ifdef CONFIG_X86_MCE_AMD - if ((adev->asic_type == CHIP_ALDEBARAN) && - (adev->gmc.xgmi.connected_to_cpu)) - amdgpu_register_bad_pages_mca_notifier(adev); -#endif return 0; free: @@ -2192,6 +2056,19 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev) } /* recovery end */ +/* return 0 if ras will reset gpu and repost.*/ +int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev, + unsigned int block) +{ + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); + + if (!ras) + return -EINVAL; + + ras->flags |= AMDGPU_RAS_FLAG_INIT_NEED_RESET; + return 0; +} + static bool amdgpu_ras_asic_supported(struct amdgpu_device *adev) { return adev->asic_type == CHIP_VEGA10 || @@ -2299,14 +2176,12 @@ int amdgpu_ras_init(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); int r; - bool df_poison, umc_poison; if (con) return 0; con = kmalloc(sizeof(struct amdgpu_ras) + - sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT + - sizeof(struct ras_manager) * AMDGPU_RAS_MCA_BLOCK_COUNT, + sizeof(struct ras_manager) * AMDGPU_RAS_BLOCK_COUNT, GFP_KERNEL|__GFP_ZERO); if (!con) return -ENOMEM; @@ -2370,27 +2245,6 @@ int amdgpu_ras_init(struct amdgpu_device *adev) goto release_con; } - /* Init poison supported flag, the default value is false */ - if (adev->gmc.xgmi.connected_to_cpu) { - /* enabled by default when GPU is connected to CPU */ - con->poison_supported = true; - } - else if (adev->df.funcs && - adev->df.funcs->query_ras_poison_mode && - adev->umc.ras_funcs && - adev->umc.ras_funcs->query_ras_poison_mode) { - df_poison = - adev->df.funcs->query_ras_poison_mode(adev); - umc_poison = - adev->umc.ras_funcs->query_ras_poison_mode(adev); - /* Only poison is set in both DF and UMC, we can support it */ - if (df_poison && umc_poison) - con->poison_supported = true; - else if (df_poison != umc_poison) - dev_warn(adev->dev, "Poison setting is inconsistent in DF/UMC(%d:%d)!\n", - df_poison, umc_poison); - } - if (amdgpu_ras_fs_init(adev)) { r = -EINVAL; goto release_con; @@ -2434,16 +2288,6 @@ static int amdgpu_persistent_edc_harvesting(struct amdgpu_device *adev, return 0; } -bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev) -{ - struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - - if (!con) - return false; - - return con->poison_supported; -} - /* helper function to handle common stuff in ip late init phase */ int amdgpu_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block, @@ -2462,7 +2306,12 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev, r = amdgpu_ras_feature_enable_on_boot(adev, ras_block, 1); if (r) { - if (adev->in_suspend || amdgpu_in_reset(adev)) { + if (r == -EAGAIN) { + /* request gpu reset. will run again */ + amdgpu_ras_request_reset_on_boot(adev, + ras_block->block); + return 0; + } else if (adev->in_suspend || amdgpu_in_reset(adev)) { /* in resume phase, if fail to enable ras, * clean up all ras fs nodes, and disable ras */ goto cleanup; @@ -2516,6 +2365,7 @@ void amdgpu_ras_late_fini(struct amdgpu_device *adev, amdgpu_ras_sysfs_remove(adev, ras_block); if (ih_info->cb) amdgpu_ras_interrupt_remove_handler(adev, ih_info); + amdgpu_ras_feature_enable(adev, ras_block, 0); } /* do some init work after IP late init as dependence. @@ -2553,6 +2403,19 @@ void amdgpu_ras_resume(struct amdgpu_device *adev) } } } + + if (con->flags & AMDGPU_RAS_FLAG_INIT_NEED_RESET) { + con->flags &= ~AMDGPU_RAS_FLAG_INIT_NEED_RESET; + /* setup ras obj state as disabled. + * for init_by_vbios case. + * if we want to enable ras, just enable it in a normal way. + * If we want do disable it, need setup ras obj as enabled, + * then issue another TA disable cmd. + * See feature_enable_on_boot + */ + amdgpu_ras_disable_all_features(adev, 1); + amdgpu_ras_reset_gpu(adev); + } } void amdgpu_ras_suspend(struct amdgpu_device *adev) @@ -2644,136 +2507,3 @@ void amdgpu_release_ras_context(struct amdgpu_device *adev) kfree(con); } } - -#ifdef CONFIG_X86_MCE_AMD -static struct amdgpu_device *find_adev(uint32_t node_id) -{ - int i; - struct amdgpu_device *adev = NULL; - - for (i = 0; i < mce_adev_list.num_gpu; i++) { - adev = mce_adev_list.devs[i]; - - if (adev && adev->gmc.xgmi.connected_to_cpu && - adev->gmc.xgmi.physical_node_id == node_id) - break; - adev = NULL; - } - - return adev; -} - -#define GET_MCA_IPID_GPUID(m) (((m) >> 44) & 0xF) -#define GET_UMC_INST(m) (((m) >> 21) & 0x7) -#define GET_CHAN_INDEX(m) ((((m) >> 12) & 0x3) | (((m) >> 18) & 0x4)) -#define GPU_ID_OFFSET 8 - -static int amdgpu_bad_page_notifier(struct notifier_block *nb, - unsigned long val, void *data) -{ - struct mce *m = (struct mce *)data; - struct amdgpu_device *adev = NULL; - uint32_t gpu_id = 0; - uint32_t umc_inst = 0; - uint32_t ch_inst, channel_index = 0; - struct ras_err_data err_data = {0, 0, 0, NULL}; - struct eeprom_table_record err_rec; - uint64_t retired_page; - - /* - * If the error was generated in UMC_V2, which belongs to GPU UMCs, - * and error occurred in DramECC (Extended error code = 0) then only - * process the error, else bail out. - */ - if (!m || !((smca_get_bank_type(m->extcpu, m->bank) == SMCA_UMC_V2) && - (XEC(m->status, 0x3f) == 0x0))) - return NOTIFY_DONE; - - /* - * If it is correctable error, return. - */ - if (mce_is_correctable(m)) - return NOTIFY_OK; - - /* - * GPU Id is offset by GPU_ID_OFFSET in MCA_IPID_UMC register. - */ - gpu_id = GET_MCA_IPID_GPUID(m->ipid) - GPU_ID_OFFSET; - - adev = find_adev(gpu_id); - if (!adev) { - DRM_WARN("%s: Unable to find adev for gpu_id: %d\n", __func__, - gpu_id); - return NOTIFY_DONE; - } - - /* - * If it is uncorrectable error, then find out UMC instance and - * channel index. - */ - umc_inst = GET_UMC_INST(m->ipid); - ch_inst = GET_CHAN_INDEX(m->ipid); - - dev_info(adev->dev, "Uncorrectable error detected in UMC inst: %d, chan_idx: %d", - umc_inst, ch_inst); - - memset(&err_rec, 0x0, sizeof(struct eeprom_table_record)); - - /* - * Translate UMC channel address to Physical address - */ - channel_index = - adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num - + ch_inst]; - - retired_page = ADDR_OF_8KB_BLOCK(m->addr) | - ADDR_OF_256B_BLOCK(channel_index) | - OFFSET_IN_256B_BLOCK(m->addr); - - err_rec.address = m->addr; - err_rec.retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT; - err_rec.ts = (uint64_t)ktime_get_real_seconds(); - err_rec.err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE; - err_rec.cu = 0; - err_rec.mem_channel = channel_index; - err_rec.mcumc_id = umc_inst; - - err_data.err_addr = &err_rec; - err_data.err_addr_cnt = 1; - - if (amdgpu_bad_page_threshold != 0) { - amdgpu_ras_add_bad_pages(adev, err_data.err_addr, - err_data.err_addr_cnt); - amdgpu_ras_save_bad_pages(adev); - } - - return NOTIFY_OK; -} - -static struct notifier_block amdgpu_bad_page_nb = { - .notifier_call = amdgpu_bad_page_notifier, - .priority = MCE_PRIO_UC, -}; - -static void amdgpu_register_bad_pages_mca_notifier(struct amdgpu_device *adev) -{ - /* - * Add the adev to the mce_adev_list. - * During mode2 reset, amdgpu device is temporarily - * removed from the mgpu_info list which can cause - * page retirement to fail. - * Use this list instead of mgpu_info to find the amdgpu - * device on which the UMC error was reported. - */ - mce_adev_list.devs[mce_adev_list.num_gpu++] = adev; - - /* - * Register the x86 notifier only once - * with MCE subsystem. - */ - if (notifier_registered == false) { - mce_register_decode_chain(&amdgpu_bad_page_nb); - notifier_registered = true; - } -} -#endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index 1c708122d4..eae604fd90 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -32,6 +32,7 @@ #include "amdgpu_ras_eeprom.h" #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0) +#define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1) enum amdgpu_ras_block { AMDGPU_RAS_BLOCK__UMC = 0, @@ -48,22 +49,15 @@ enum amdgpu_ras_block { AMDGPU_RAS_BLOCK__MP0, AMDGPU_RAS_BLOCK__MP1, AMDGPU_RAS_BLOCK__FUSE, - AMDGPU_RAS_BLOCK__MCA, + AMDGPU_RAS_BLOCK__MPIO, AMDGPU_RAS_BLOCK__LAST }; -enum amdgpu_ras_mca_block { - AMDGPU_RAS_MCA_BLOCK__MP0 = 0, - AMDGPU_RAS_MCA_BLOCK__MP1, - AMDGPU_RAS_MCA_BLOCK__MPIO, - AMDGPU_RAS_MCA_BLOCK__IOHC, - - AMDGPU_RAS_MCA_BLOCK__LAST -}; +extern const char *ras_block_string[]; +#define ras_block_str(i) (ras_block_string[i]) #define AMDGPU_RAS_BLOCK_COUNT AMDGPU_RAS_BLOCK__LAST -#define AMDGPU_RAS_MCA_BLOCK_COUNT AMDGPU_RAS_MCA_BLOCK__LAST #define AMDGPU_RAS_BLOCK_MASK ((1ULL << AMDGPU_RAS_BLOCK_COUNT) - 1) enum amdgpu_ras_gfx_subblock { @@ -319,19 +313,6 @@ struct ras_common_if { char name[32]; }; -#define MAX_UMC_CHANNEL_NUM 32 - -struct ecc_info_per_ch { - uint16_t ce_count_lo_chip; - uint16_t ce_count_hi_chip; - uint64_t mca_umc_status; - uint64_t mca_umc_addr; -}; - -struct umc_ecc_info { - struct ecc_info_per_ch ecc[MAX_UMC_CHANNEL_NUM]; -}; - struct amdgpu_ras { /* ras infrastructure */ /* for ras itself. */ @@ -364,16 +345,10 @@ struct amdgpu_ras { /* disable ras error count harvest in recovery */ bool disable_ras_err_cnt_harvest; - /* is poison mode supported */ - bool poison_supported; - /* RAS count errors delayed work */ struct delayed_work ras_counte_delay_work; atomic_t ras_ue_count; atomic_t ras_ce_count; - - /* record umc error info queried from smu */ - struct umc_ecc_info umc_ecc; }; struct ras_fs_data { @@ -513,6 +488,8 @@ static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev, } int amdgpu_ras_recovery_init(struct amdgpu_device *adev); +int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev, + unsigned int block); void amdgpu_ras_resume(struct amdgpu_device *adev); void amdgpu_ras_suspend(struct amdgpu_device *adev); @@ -567,8 +544,6 @@ amdgpu_ras_block_to_ta(enum amdgpu_ras_block block) { return TA_RAS_BLOCK__MP1; case AMDGPU_RAS_BLOCK__FUSE: return TA_RAS_BLOCK__FUSE; - case AMDGPU_RAS_BLOCK__MCA: - return TA_RAS_BLOCK__MCA; default: WARN_ONCE(1, "RAS ERROR: unexpected block id %d\n", block); return TA_RAS_BLOCK__UMC; @@ -663,8 +638,4 @@ void amdgpu_release_ras_context(struct amdgpu_device *adev); int amdgpu_persistent_edc_harvesting_supported(struct amdgpu_device *adev); -const char *get_ras_block_str(struct ras_common_if *ras_block); - -bool amdgpu_ras_is_poison_mode_supported(struct amdgpu_device *adev); - #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 05117eda10..9873251854 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -1077,13 +1077,6 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control, if (res) DRM_ERROR("RAS table incorrect checksum or error:%d\n", res); - - /* Warn if we are at 90% of the threshold or above - */ - if (10 * control->ras_num_recs >= 9 * ras->bad_page_cnt_threshold) - dev_warn(adev->dev, "RAS records:%u exceeds 90%% of threshold:%d", - control->ras_num_recs, - ras->bad_page_cnt_threshold); } else if (hdr->header == RAS_TABLE_HDR_BAD && amdgpu_bad_page_threshold != 0) { res = __verify_ras_table_checksum(control); @@ -1105,18 +1098,11 @@ int amdgpu_ras_eeprom_init(struct amdgpu_ras_eeprom_control *control, res = amdgpu_ras_eeprom_correct_header_tag(control, RAS_TABLE_HDR_VAL); } else { - dev_err(adev->dev, "RAS records:%d exceed threshold:%d", + *exceed_err_limit = true; + dev_err(adev->dev, + "RAS records:%d exceed threshold:%d, " + "maybe retire this GPU?", control->ras_num_recs, ras->bad_page_cnt_threshold); - if (amdgpu_bad_page_threshold == -2) { - dev_warn(adev->dev, "GPU will be initialized due to bad_page_threshold = -2."); - res = 0; - } else { - *exceed_err_limit = true; - dev_err(adev->dev, - "RAS records:%d exceed threshold:%d, " - "GPU will not be initialized. Replace this GPU or increase the threshold", - control->ras_num_recs, ras->bad_page_cnt_threshold); - } } } else { DRM_INFO("Creating a new EEPROM table"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index ab2351ba95..0554576d36 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -415,20 +415,26 @@ static const struct file_operations amdgpu_debugfs_ring_fops = { #endif -void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, - struct amdgpu_ring *ring) +int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, + struct amdgpu_ring *ring) { #if defined(CONFIG_DEBUG_FS) struct drm_minor *minor = adev_to_drm(adev)->primary; - struct dentry *root = minor->debugfs_root; + struct dentry *ent, *root = minor->debugfs_root; char name[32]; sprintf(name, "amdgpu_ring_%s", ring->name); - debugfs_create_file_size(name, S_IFREG | S_IRUGO, root, ring, - &amdgpu_debugfs_ring_fops, - ring->ring_size + 12); + ent = debugfs_create_file(name, + S_IFREG | S_IRUGO, root, + ring, &amdgpu_debugfs_ring_fops); + if (IS_ERR(ent)) + return PTR_ERR(ent); + + i_size_write(ent->d_inode, ring->ring_size + 12); + ring->ent = ent; #endif + return 0; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index fae7d185ad..e713d31619 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -36,13 +36,8 @@ #define AMDGPU_MAX_VCE_RINGS 3 #define AMDGPU_MAX_UVD_ENC_RINGS 2 -enum amdgpu_ring_priority_level { - AMDGPU_RING_PRIO_0, - AMDGPU_RING_PRIO_1, - AMDGPU_RING_PRIO_DEFAULT = 1, - AMDGPU_RING_PRIO_2, - AMDGPU_RING_PRIO_MAX -}; +#define AMDGPU_RING_PRIO_DEFAULT 1 +#define AMDGPU_RING_PRIO_MAX AMDGPU_GFX_PIPE_PRIO_MAX /* some special values for the owner field */ #define AMDGPU_FENCE_OWNER_UNDEFINED ((void *)0ul) @@ -53,6 +48,9 @@ enum amdgpu_ring_priority_level { #define AMDGPU_FENCE_FLAG_INT (1 << 1) #define AMDGPU_FENCE_FLAG_TC_WB_ONLY (1 << 2) +/* fence flag bit to indicate the face is embedded in job*/ +#define AMDGPU_FENCE_FLAG_EMBED_IN_JOB_BIT (DMA_FENCE_FLAG_USER_BITS + 1) + #define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched) #define AMDGPU_IB_POOL_SIZE (1024 * 1024) @@ -111,7 +109,6 @@ struct amdgpu_fence_driver { struct dma_fence **fences; }; -void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring); void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring); int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, @@ -251,6 +248,10 @@ struct amdgpu_ring { bool has_compute_vm_bug; bool no_scheduler; int hw_prio; + +#if defined(CONFIG_DEBUG_FS) + struct dentry *ent; +#endif }; #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) @@ -350,6 +351,8 @@ static inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, int amdgpu_ring_test_helper(struct amdgpu_ring *ring); -void amdgpu_debugfs_ring_init(struct amdgpu_device *adev, - struct amdgpu_ring *ring); +int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, + struct amdgpu_ring *ring); +void amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring); + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index e9b45089a2..b7d861ed52 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -32,9 +32,37 @@ #include "amdgpu_sched.h" #include "amdgpu_vm.h" +int amdgpu_to_sched_priority(int amdgpu_priority, + enum drm_sched_priority *prio) +{ + switch (amdgpu_priority) { + case AMDGPU_CTX_PRIORITY_VERY_HIGH: + *prio = DRM_SCHED_PRIORITY_HIGH; + break; + case AMDGPU_CTX_PRIORITY_HIGH: + *prio = DRM_SCHED_PRIORITY_HIGH; + break; + case AMDGPU_CTX_PRIORITY_NORMAL: + *prio = DRM_SCHED_PRIORITY_NORMAL; + break; + case AMDGPU_CTX_PRIORITY_LOW: + case AMDGPU_CTX_PRIORITY_VERY_LOW: + *prio = DRM_SCHED_PRIORITY_MIN; + break; + case AMDGPU_CTX_PRIORITY_UNSET: + *prio = DRM_SCHED_PRIORITY_UNSET; + break; + default: + WARN(1, "Invalid context priority %d\n", amdgpu_priority); + return -EINVAL; + } + + return 0; +} + static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, int fd, - int32_t priority) + enum drm_sched_priority priority) { struct fd f = fdget(fd); struct amdgpu_fpriv *fpriv; @@ -61,7 +89,7 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev, static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev, int fd, unsigned ctx_id, - int32_t priority) + enum drm_sched_priority priority) { struct fd f = fdget(fd); struct amdgpu_fpriv *fpriv; @@ -96,6 +124,7 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, { union drm_amdgpu_sched *args = data; struct amdgpu_device *adev = drm_to_adev(dev); + enum drm_sched_priority priority; int r; /* First check the op, then the op's argument. @@ -109,22 +138,21 @@ int amdgpu_sched_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - if (!amdgpu_ctx_priority_is_valid(args->in.priority)) { - WARN(1, "Invalid context priority %d\n", args->in.priority); - return -EINVAL; - } + r = amdgpu_to_sched_priority(args->in.priority, &priority); + if (r) + return r; switch (args->in.op) { case AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE: r = amdgpu_sched_process_priority_override(adev, args->in.fd, - args->in.priority); + priority); break; case AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE: r = amdgpu_sched_context_priority_override(adev, args->in.fd, args->in.ctx_id, - args->in.priority); + priority); break; default: /* Impossible. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index f7d8487799..862eb3c1c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -252,25 +252,41 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync, struct dma_resv *resv, enum amdgpu_sync_mode mode, void *owner) { - struct dma_resv_iter cursor; + struct dma_resv_list *flist; struct dma_fence *f; - int r; + unsigned i; + int r = 0; if (resv == NULL) return -EINVAL; - dma_resv_for_each_fence(&cursor, resv, true, f) { - dma_fence_chain_for_each(f, f) { - struct dma_fence_chain *chain = to_dma_fence_chain(f); + /* always sync to the exclusive fence */ + f = dma_resv_excl_fence(resv); + dma_fence_chain_for_each(f, f) { + struct dma_fence_chain *chain = to_dma_fence_chain(f); - if (amdgpu_sync_test_fence(adev, mode, owner, chain ? - chain->fence : f)) { - r = amdgpu_sync_fence(sync, f); - dma_fence_put(f); - if (r) - return r; - break; - } + if (amdgpu_sync_test_fence(adev, mode, owner, chain ? + chain->fence : f)) { + r = amdgpu_sync_fence(sync, f); + dma_fence_put(f); + if (r) + return r; + break; + } + } + + flist = dma_resv_shared_list(resv); + if (!flist) + return 0; + + for (i = 0; i < flist->shared_count; ++i) { + f = rcu_dereference_protected(flist->shared[i], + dma_resv_held(resv)); + + if (amdgpu_sync_test_fence(adev, mode, owner, f)) { + r = amdgpu_sync_fence(sync, f); + if (r) + return r; } } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 4655702a5e..8132f66177 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -41,9 +41,7 @@ #include #include #include -#include -#include #include #include #include @@ -61,8 +59,6 @@ #include "amdgpu_res_cursor.h" #include "bif/bif_4_1_d.h" -MODULE_IMPORT_NS(DMA_BUF); - #define AMDGPU_TTM_VRAM_MAX_DW_READ (size_t)128 static int amdgpu_ttm_backend_bind(struct ttm_device *bdev, @@ -117,8 +113,17 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, abo = ttm_to_amdgpu_bo(bo); if (abo->flags & AMDGPU_AMDKFD_CREATE_SVM_BO) { + struct dma_fence *fence; + struct dma_resv *resv = &bo->base._resv; + + rcu_read_lock(); + fence = rcu_dereference(resv->fence_excl); + if (fence && !fence->ops->signaled) + dma_fence_enable_sw_signaling(fence); + placement->num_placement = 0; placement->num_busy_placement = 0; + rcu_read_unlock(); return; } @@ -691,9 +696,6 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) true, NULL); out_unlock: mmap_read_unlock(mm); - if (r) - pr_debug("failed %d to get user pages 0x%lx\n", r, start); - mmput(mm); return r; @@ -892,7 +894,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev, DRM_ERROR("failed to pin userptr\n"); return r; } - } else if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) { + } else if (ttm->page_flags & TTM_PAGE_FLAG_SG) { if (!ttm->sg) { struct dma_buf_attachment *attach; struct sg_table *sgt; @@ -914,6 +916,11 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev, ttm->num_pages, bo_mem, ttm); } + if (bo_mem->mem_type == AMDGPU_PL_GDS || + bo_mem->mem_type == AMDGPU_PL_GWS || + bo_mem->mem_type == AMDGPU_PL_OA) + return -EINVAL; + if (bo_mem->mem_type != TTM_PL_TT || !amdgpu_gtt_mgr_has_gart_addr(bo_mem)) { gtt->offset = AMDGPU_BO_INVALID_OFFSET; @@ -1059,6 +1066,8 @@ static void amdgpu_ttm_backend_destroy(struct ttm_device *bdev, { struct amdgpu_ttm_tt *gtt = (void *)ttm; + amdgpu_ttm_backend_unbind(bdev, ttm); + ttm_tt_destroy_common(bdev, ttm); if (gtt->usertask) put_task_struct(gtt->usertask); @@ -1112,8 +1121,6 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, { struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; - pgoff_t i; - int ret; /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ if (gtt->userptr) { @@ -1123,17 +1130,10 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, return 0; } - if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) + if (ttm->page_flags & TTM_PAGE_FLAG_SG) return 0; - ret = ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); - if (ret) - return ret; - - for (i = 0; i < ttm->num_pages; ++i) - ttm->pages[i]->mapping = bdev->dev_mapping; - - return 0; + return ttm_pool_alloc(&adev->mman.bdev.pool, ttm, ctx); } /* @@ -1147,9 +1147,6 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, { struct amdgpu_ttm_tt *gtt = (void *)ttm; struct amdgpu_device *adev; - pgoff_t i; - - amdgpu_ttm_backend_unbind(bdev, ttm); if (gtt->userptr) { amdgpu_ttm_tt_set_user_pages(ttm, NULL); @@ -1158,12 +1155,9 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev, return; } - if (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) + if (ttm->page_flags & TTM_PAGE_FLAG_SG) return; - for (i = 0; i < ttm->num_pages; ++i) - ttm->pages[i]->mapping = NULL; - adev = amdgpu_ttm_adev(bdev); return ttm_pool_free(&adev->mman.bdev.pool, ttm); } @@ -1191,8 +1185,8 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, return -ENOMEM; } - /* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */ - bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL; + /* Set TTM_PAGE_FLAG_SG before populate but after create. */ + bo->ttm->page_flags |= TTM_PAGE_FLAG_SG; gtt = (void *)bo->ttm; gtt->userptr = addr; @@ -1228,7 +1222,7 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) * */ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, - unsigned long end, unsigned long *userptr) + unsigned long end) { struct amdgpu_ttm_tt *gtt = (void *)ttm; unsigned long size; @@ -1243,8 +1237,6 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, if (gtt->userptr > end || gtt->userptr + size <= start) return false; - if (userptr) - *userptr = gtt->userptr; return true; } @@ -1340,9 +1332,10 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, const struct ttm_place *place) { unsigned long num_pages = bo->resource->num_pages; - struct dma_resv_iter resv_cursor; struct amdgpu_res_cursor cursor; + struct dma_resv_list *flist; struct dma_fence *f; + int i; /* Swapout? */ if (bo->resource->mem_type == TTM_PL_SYSTEM) @@ -1356,9 +1349,14 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, * If true, then return false as any KFD process needs all its BOs to * be resident to run successfully */ - dma_resv_for_each_fence(&resv_cursor, bo->base.resv, true, f) { - if (amdkfd_fence_check_mm(f, current->mm)) - return false; + flist = dma_resv_shared_list(bo->base.resv); + if (flist) { + for (i = 0; i < flist->shared_count; ++i) { + f = rcu_dereference_protected(flist->shared[i], + dma_resv_held(bo->base.resv)); + if (amdkfd_fence_check_mm(f, current->mm)) + return false; + } } switch (bo->resource->mem_type) { @@ -1805,7 +1803,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) */ void amdgpu_ttm_fini(struct amdgpu_device *adev) { - int idx; if (!adev->mman.initialized) return; @@ -1820,15 +1817,6 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) NULL, NULL); amdgpu_ttm_fw_reserve_vram_fini(adev); - if (drm_dev_enter(adev_to_drm(adev), &idx)) { - - if (adev->mman.aper_base_kaddr) - iounmap(adev->mman.aper_base_kaddr); - adev->mman.aper_base_kaddr = NULL; - - drm_dev_exit(idx); - } - amdgpu_vram_mgr_fini(adev); amdgpu_gtt_mgr_fini(adev); amdgpu_preempt_mgr_fini(adev); @@ -2048,36 +2036,6 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, return r; } -/** - * amdgpu_ttm_evict_resources - evict memory buffers - * @adev: amdgpu device object - * @mem_type: evicted BO's memory type - * - * Evicts all @mem_type buffers on the lru list of the memory type. - * - * Returns: - * 0 for success or a negative error code on failure. - */ -int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type) -{ - struct ttm_resource_manager *man; - - switch (mem_type) { - case TTM_PL_VRAM: - case TTM_PL_TT: - case AMDGPU_PL_GWS: - case AMDGPU_PL_GDS: - case AMDGPU_PL_OA: - man = ttm_manager_type(&adev->mman.bdev, mem_type); - break; - default: - DRM_ERROR("Trying to evict invalid memory type\n"); - return -EINVAL; - } - - return ttm_resource_manager_evict_all(&adev->mman.bdev, man); -} - #if defined(CONFIG_DEBUG_FS) static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index f8f48be16d..3205fd5200 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -114,8 +114,8 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev); void amdgpu_vram_mgr_fini(struct amdgpu_device *adev); bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem); -uint64_t amdgpu_gtt_mgr_usage(struct amdgpu_gtt_mgr *mgr); -int amdgpu_gtt_mgr_recover(struct amdgpu_gtt_mgr *mgr); +uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man); +int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man); uint64_t amdgpu_preempt_mgr_usage(struct ttm_resource_manager *man); @@ -129,11 +129,11 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, void amdgpu_vram_mgr_free_sgt(struct device *dev, enum dma_data_direction dir, struct sg_table *sgt); -uint64_t amdgpu_vram_mgr_usage(struct amdgpu_vram_mgr *mgr); -uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr); -int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, +uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man); +uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man); +int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man, uint64_t start, uint64_t size); -int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr, +int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man, uint64_t start); int amdgpu_ttm_init(struct amdgpu_device *adev); @@ -182,7 +182,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm); bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, - unsigned long end, unsigned long *userptr); + unsigned long end); bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, int *last_invalidated); bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm); @@ -190,7 +190,6 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem); uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, struct ttm_resource *mem); -int amdgpu_ttm_evict_resources(struct amdgpu_device *adev, int mem_type); void amdgpu_ttm_debugfs_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index ca33505026..abd8469380 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -416,11 +416,10 @@ amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type) else return AMDGPU_FW_LOAD_PSP; default: - if (!load_type) - return AMDGPU_FW_LOAD_DIRECT; - else - return AMDGPU_FW_LOAD_PSP; + DRM_ERROR("Unknown firmware load type\n"); } + + return AMDGPU_FW_LOAD_DIRECT; } const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id) @@ -509,7 +508,7 @@ static ssize_t show_##name(struct device *dev, \ struct drm_device *ddev = dev_get_drvdata(dev); \ struct amdgpu_device *adev = drm_to_adev(ddev); \ \ - return sysfs_emit(buf, "0x%08x\n", adev->field); \ + return snprintf(buf, PAGE_SIZE, "0x%08x\n", adev->field); \ } \ static DEVICE_ATTR(name, mode, show_##name, NULL) @@ -526,9 +525,9 @@ FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version); FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version); FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version); FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version); -FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version); -FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version); -FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi_context.context.bin_desc.fw_version); +FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd.fw_version); +FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras.feature_version); +FW_VERSION_ATTR(ta_xgmi_fw_version, 0444, psp.xgmi.feature_version); FW_VERSION_ATTR(smc_fw_version, 0444, pm.fw_version); FW_VERSION_ATTR(sdma_fw_version, 0444, sdma.instance[0].fw_version); FW_VERSION_ATTR(sdma2_fw_version, 0444, sdma.instance[1].fw_version); @@ -573,7 +572,6 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, const struct dmcu_firmware_header_v1_0 *dmcu_hdr = NULL; const struct dmcub_firmware_header_v1_0 *dmcub_hdr = NULL; const struct mes_firmware_header_v1_0 *mes_hdr = NULL; - u8 *ucode_addr; if (NULL == ucode->fw) return 0; @@ -590,82 +588,93 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, dmcub_hdr = (const struct dmcub_firmware_header_v1_0 *)ucode->fw->data; mes_hdr = (const struct mes_firmware_header_v1_0 *)ucode->fw->data; - if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { - switch (ucode->ucode_id) { - case AMDGPU_UCODE_ID_CP_MEC1: - case AMDGPU_UCODE_ID_CP_MEC2: - ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - - le32_to_cpu(cp_hdr->jt_size) * 4; - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes); - break; - case AMDGPU_UCODE_ID_CP_MEC1_JT: - case AMDGPU_UCODE_ID_CP_MEC2_JT: - ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4; - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes) + - le32_to_cpu(cp_hdr->jt_offset) * 4; - break; - case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL: - ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; - ucode_addr = adev->gfx.rlc.save_restore_list_cntl; - break; - case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM: - ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes; - ucode_addr = adev->gfx.rlc.save_restore_list_gpm; - break; - case AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM: - ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes; - ucode_addr = adev->gfx.rlc.save_restore_list_srm; - break; - case AMDGPU_UCODE_ID_RLC_IRAM: - ucode->ucode_size = adev->gfx.rlc.rlc_iram_ucode_size_bytes; - ucode_addr = adev->gfx.rlc.rlc_iram_ucode; - break; - case AMDGPU_UCODE_ID_RLC_DRAM: - ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes; - ucode_addr = adev->gfx.rlc.rlc_dram_ucode; - break; - case AMDGPU_UCODE_ID_CP_MES: - ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(mes_hdr->mes_ucode_offset_bytes); - break; - case AMDGPU_UCODE_ID_CP_MES_DATA: - ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes); - break; - case AMDGPU_UCODE_ID_DMCU_ERAM: - ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - - le32_to_cpu(dmcu_hdr->intv_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes); - break; - case AMDGPU_UCODE_ID_DMCU_INTV: - ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes) + - le32_to_cpu(dmcu_hdr->intv_offset_bytes); - break; - case AMDGPU_UCODE_ID_DMCUB: - ucode->ucode_size = le32_to_cpu(dmcub_hdr->inst_const_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes); - break; - default: - ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes); - break; - } - } else { + if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP || + (ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1 && + ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2 && + ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC1_JT && + ucode->ucode_id != AMDGPU_UCODE_ID_CP_MEC2_JT && + ucode->ucode_id != AMDGPU_UCODE_ID_CP_MES && + ucode->ucode_id != AMDGPU_UCODE_ID_CP_MES_DATA && + ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL && + ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM && + ucode->ucode_id != AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM && + ucode->ucode_id != AMDGPU_UCODE_ID_RLC_IRAM && + ucode->ucode_id != AMDGPU_UCODE_ID_RLC_DRAM && + ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_ERAM && + ucode->ucode_id != AMDGPU_UCODE_ID_DMCU_INTV && + ucode->ucode_id != AMDGPU_UCODE_ID_DMCUB)) { ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes); - ucode_addr = (u8 *)ucode->fw->data + - le32_to_cpu(header->ucode_array_offset_bytes); - } - memcpy(ucode->kaddr, ucode_addr, ucode->ucode_size); + memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1 || + ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2) { + ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - + le32_to_cpu(cp_hdr->jt_size) * 4; + + memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC1_JT || + ucode->ucode_id == AMDGPU_UCODE_ID_CP_MEC2_JT) { + ucode->ucode_size = le32_to_cpu(cp_hdr->jt_size) * 4; + + memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes) + + le32_to_cpu(cp_hdr->jt_offset) * 4), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_ERAM) { + ucode->ucode_size = le32_to_cpu(header->ucode_size_bytes) - + le32_to_cpu(dmcu_hdr->intv_size_bytes); + + memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCU_INTV) { + ucode->ucode_size = le32_to_cpu(dmcu_hdr->intv_size_bytes); + + memcpy(ucode->kaddr, (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes) + + le32_to_cpu(dmcu_hdr->intv_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_DMCUB) { + ucode->ucode_size = le32_to_cpu(dmcub_hdr->inst_const_bytes); + memcpy(ucode->kaddr, + (void *)((uint8_t *)ucode->fw->data + + le32_to_cpu(header->ucode_array_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL) { + ucode->ucode_size = adev->gfx.rlc.save_restore_list_cntl_size_bytes; + memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_cntl, + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM) { + ucode->ucode_size = adev->gfx.rlc.save_restore_list_gpm_size_bytes; + memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_gpm, + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM) { + ucode->ucode_size = adev->gfx.rlc.save_restore_list_srm_size_bytes; + memcpy(ucode->kaddr, adev->gfx.rlc.save_restore_list_srm, + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_IRAM) { + ucode->ucode_size = adev->gfx.rlc.rlc_iram_ucode_size_bytes; + memcpy(ucode->kaddr, adev->gfx.rlc.rlc_iram_ucode, + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_RLC_DRAM) { + ucode->ucode_size = adev->gfx.rlc.rlc_dram_ucode_size_bytes; + memcpy(ucode->kaddr, adev->gfx.rlc.rlc_dram_ucode, + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MES) { + ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes); + memcpy(ucode->kaddr, (void *)((uint8_t *)adev->mes.fw->data + + le32_to_cpu(mes_hdr->mes_ucode_offset_bytes)), + ucode->ucode_size); + } else if (ucode->ucode_id == AMDGPU_UCODE_ID_CP_MES_DATA) { + ucode->ucode_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes); + memcpy(ucode->kaddr, (void *)((uint8_t *)adev->mes.fw->data + + le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes)), + ucode->ucode_size); + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c index 46264a4002..a90029ee97 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c @@ -23,120 +23,6 @@ #include "amdgpu_ras.h" -static int amdgpu_umc_do_page_retirement(struct amdgpu_device *adev, - void *ras_error_status, - struct amdgpu_iv_entry *entry, - bool reset) -{ - struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; - struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - int ret = 0; - - kgd2kfd_set_sram_ecc_flag(adev->kfd.dev); - ret = smu_get_ecc_info(&adev->smu, (void *)&(con->umc_ecc)); - if (ret == -EOPNOTSUPP) { - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->query_ras_error_count) - adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status); - - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->query_ras_error_address && - adev->umc.max_ras_err_cnt_per_query) { - err_data->err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); - - /* still call query_ras_error_address to clear error status - * even NOMEM error is encountered - */ - if(!err_data->err_addr) - dev_warn(adev->dev, "Failed to alloc memory for " - "umc error address record!\n"); - - /* umc query_ras_error_address is also responsible for clearing - * error status - */ - adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status); - } - } else if (!ret) { - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->ecc_info_query_ras_error_count) - adev->umc.ras_funcs->ecc_info_query_ras_error_count(adev, ras_error_status); - - if (adev->umc.ras_funcs && - adev->umc.ras_funcs->ecc_info_query_ras_error_address && - adev->umc.max_ras_err_cnt_per_query) { - err_data->err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); - - /* still call query_ras_error_address to clear error status - * even NOMEM error is encountered - */ - if(!err_data->err_addr) - dev_warn(adev->dev, "Failed to alloc memory for " - "umc error address record!\n"); - - /* umc query_ras_error_address is also responsible for clearing - * error status - */ - adev->umc.ras_funcs->ecc_info_query_ras_error_address(adev, ras_error_status); - } - } - - /* only uncorrectable error needs gpu reset */ - if (err_data->ue_count) { - dev_info(adev->dev, "%ld uncorrectable hardware errors " - "detected in UMC block\n", - err_data->ue_count); - - if ((amdgpu_bad_page_threshold != 0) && - err_data->err_addr_cnt) { - amdgpu_ras_add_bad_pages(adev, err_data->err_addr, - err_data->err_addr_cnt); - amdgpu_ras_save_bad_pages(adev); - - if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num) - adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs); - } - - if (reset) - amdgpu_ras_reset_gpu(adev); - } - - kfree(err_data->err_addr); - return AMDGPU_RAS_SUCCESS; -} - -int amdgpu_umc_poison_handler(struct amdgpu_device *adev, - void *ras_error_status, - bool reset) -{ - int ret; - struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; - struct ras_common_if head = { - .block = AMDGPU_RAS_BLOCK__UMC, - }; - struct ras_manager *obj = amdgpu_ras_find_obj(adev, &head); - - ret = - amdgpu_umc_do_page_retirement(adev, ras_error_status, NULL, reset); - - if (ret == AMDGPU_RAS_SUCCESS && obj) { - obj->err_data.ue_count += err_data->ue_count; - obj->err_data.ce_count += err_data->ce_count; - } - - return ret; -} - -static int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev, - void *ras_error_status, - struct amdgpu_iv_entry *entry) -{ - return amdgpu_umc_do_page_retirement(adev, ras_error_status, entry, true); -} - int amdgpu_umc_ras_late_init(struct amdgpu_device *adev) { int r; @@ -202,6 +88,61 @@ void amdgpu_umc_ras_fini(struct amdgpu_device *adev) } } +int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev, + void *ras_error_status, + struct amdgpu_iv_entry *entry) +{ + struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + + kgd2kfd_set_sram_ecc_flag(adev->kfd.dev); + if (adev->umc.ras_funcs && + adev->umc.ras_funcs->query_ras_error_count) + adev->umc.ras_funcs->query_ras_error_count(adev, ras_error_status); + + if (adev->umc.ras_funcs && + adev->umc.ras_funcs->query_ras_error_address && + adev->umc.max_ras_err_cnt_per_query) { + err_data->err_addr = + kcalloc(adev->umc.max_ras_err_cnt_per_query, + sizeof(struct eeprom_table_record), GFP_KERNEL); + + /* still call query_ras_error_address to clear error status + * even NOMEM error is encountered + */ + if(!err_data->err_addr) + dev_warn(adev->dev, "Failed to alloc memory for " + "umc error address record!\n"); + + /* umc query_ras_error_address is also responsible for clearing + * error status + */ + adev->umc.ras_funcs->query_ras_error_address(adev, ras_error_status); + } + + /* only uncorrectable error needs gpu reset */ + if (err_data->ue_count) { + dev_info(adev->dev, "%ld uncorrectable hardware errors " + "detected in UMC block\n", + err_data->ue_count); + + if ((amdgpu_bad_page_threshold != 0) && + err_data->err_addr_cnt) { + amdgpu_ras_add_bad_pages(adev, err_data->err_addr, + err_data->err_addr_cnt); + amdgpu_ras_save_bad_pages(adev); + + if (adev->smu.ppt_funcs && adev->smu.ppt_funcs->send_hbm_bad_pages_num) + adev->smu.ppt_funcs->send_hbm_bad_pages_num(&adev->smu, con->eeprom_control.ras_num_recs); + } + + amdgpu_ras_reset_gpu(adev); + } + + kfree(err_data->err_addr); + return AMDGPU_RAS_SUCCESS; +} + int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h index b72194e8bf..e5a75fb788 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h @@ -48,11 +48,6 @@ struct amdgpu_umc_ras_funcs { void *ras_error_status); void (*query_ras_error_address)(struct amdgpu_device *adev, void *ras_error_status); - bool (*query_ras_poison_mode)(struct amdgpu_device *adev); - void (*ecc_info_query_ras_error_count)(struct amdgpu_device *adev, - void *ras_error_status); - void (*ecc_info_query_ras_error_address)(struct amdgpu_device *adev, - void *ras_error_status); }; struct amdgpu_umc_funcs { @@ -78,9 +73,9 @@ struct amdgpu_umc { int amdgpu_umc_ras_late_init(struct amdgpu_device *adev); void amdgpu_umc_ras_fini(struct amdgpu_device *adev); -int amdgpu_umc_poison_handler(struct amdgpu_device *adev, +int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev, void *ras_error_status, - bool reset); + struct amdgpu_iv_entry *entry); int amdgpu_umc_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 6f8de11a17..d451c35960 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -134,51 +134,6 @@ MODULE_FIRMWARE(FIRMWARE_VEGA12); MODULE_FIRMWARE(FIRMWARE_VEGA20); static void amdgpu_uvd_idle_work_handler(struct work_struct *work); -static void amdgpu_uvd_force_into_uvd_segment(struct amdgpu_bo *abo); - -static int amdgpu_uvd_create_msg_bo_helper(struct amdgpu_device *adev, - uint32_t size, - struct amdgpu_bo **bo_ptr) -{ - struct ttm_operation_ctx ctx = { true, false }; - struct amdgpu_bo *bo = NULL; - void *addr; - int r; - - r = amdgpu_bo_create_reserved(adev, size, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_GTT, - &bo, NULL, &addr); - if (r) - return r; - - if (adev->uvd.address_64_bit) - goto succ; - - amdgpu_bo_kunmap(bo); - amdgpu_bo_unpin(bo); - amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM); - amdgpu_uvd_force_into_uvd_segment(bo); - r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); - if (r) - goto err; - r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_VRAM); - if (r) - goto err_pin; - r = amdgpu_bo_kmap(bo, &addr); - if (r) - goto err_kmap; -succ: - amdgpu_bo_unreserve(bo); - *bo_ptr = bo; - return 0; -err_kmap: - amdgpu_bo_unpin(bo); -err_pin: -err: - amdgpu_bo_unreserve(bo); - amdgpu_bo_unref(&bo); - return r; -} int amdgpu_uvd_sw_init(struct amdgpu_device *adev) { @@ -347,10 +302,6 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0)) adev->uvd.address_64_bit = true; - r = amdgpu_uvd_create_msg_bo_helper(adev, 128 << 10, &adev->uvd.ib_bo); - if (r) - return r; - switch (adev->asic_type) { case CHIP_TONGA: adev->uvd.use_ctx_buf = adev->uvd.fw_version >= FW_1_65_10; @@ -373,7 +324,6 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) { - void *addr = amdgpu_bo_kptr(adev->uvd.ib_bo); int i, j; drm_sched_entity_destroy(&adev->uvd.entity); @@ -392,7 +342,6 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) for (i = 0; i < AMDGPU_MAX_UVD_ENC_RINGS; ++i) amdgpu_ring_fini(&adev->uvd.inst[j].ring_enc[i]); } - amdgpu_bo_free_kernel(&adev->uvd.ib_bo, NULL, &addr); release_firmware(adev->uvd.fw); return 0; @@ -454,7 +403,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) if (!adev->uvd.inst[j].saved_bo) return -ENOMEM; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { /* re-write 0 since err_event_athub will corrupt VCPU buffer */ if (in_ras_intr) memset(adev->uvd.inst[j].saved_bo, 0, size); @@ -487,7 +436,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) ptr = adev->uvd.inst[i].cpu_addr; if (adev->uvd.inst[i].saved_bo != NULL) { - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); drm_dev_exit(idx); } @@ -500,7 +449,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) hdr = (const struct common_firmware_header *)adev->uvd.fw->data; if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { offset = le32_to_cpu(hdr->ucode_array_offset_bytes); - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset, le32_to_cpu(hdr->ucode_size_bytes)); drm_dev_exit(idx); @@ -1131,10 +1080,23 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, unsigned offset_idx = 0; unsigned offset[3] = { UVD_BASE_SI, 0, 0 }; + amdgpu_bo_kunmap(bo); + amdgpu_bo_unpin(bo); + + if (!ring->adev->uvd.address_64_bit) { + struct ttm_operation_ctx ctx = { true, false }; + + amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM); + amdgpu_uvd_force_into_uvd_segment(bo); + r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); + if (r) + goto err; + } + r = amdgpu_job_alloc_with_ib(adev, 64, direct ? AMDGPU_IB_POOL_DIRECT : AMDGPU_IB_POOL_DELAYED, &job); if (r) - return r; + goto err; if (adev->asic_type >= CHIP_VEGA10) { offset_idx = 1 + ring->me; @@ -1185,9 +1147,9 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, goto err_free; } - amdgpu_bo_reserve(bo, true); amdgpu_bo_fence(bo, f, false); amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); if (fence) *fence = dma_fence_get(f); @@ -1197,6 +1159,10 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, err_free: amdgpu_job_free(job); + +err: + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } @@ -1207,11 +1173,16 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct dma_fence **fence) { struct amdgpu_device *adev = ring->adev; - struct amdgpu_bo *bo = adev->uvd.ib_bo; + struct amdgpu_bo *bo = NULL; uint32_t *msg; - int i; + int r, i; + + r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_GTT, + &bo, NULL, (void **)&msg); + if (r) + return r; - msg = amdgpu_bo_kptr(bo); /* stitch together an UVD create msg */ msg[0] = cpu_to_le32(0x00000de4); msg[1] = cpu_to_le32(0x00000000); @@ -1228,7 +1199,6 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, msg[i] = cpu_to_le32(0x0); return amdgpu_uvd_send_msg(ring, bo, true, fence); - } int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, @@ -1239,15 +1209,12 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, uint32_t *msg; int r, i; - if (direct) { - bo = adev->uvd.ib_bo; - } else { - r = amdgpu_uvd_create_msg_bo_helper(adev, 4096, &bo); - if (r) - return r; - } + r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_GTT, + &bo, NULL, (void **)&msg); + if (r) + return r; - msg = amdgpu_bo_kptr(bo); /* stitch together an UVD destroy msg */ msg[0] = cpu_to_le32(0x00000de4); msg[1] = cpu_to_le32(0x00000002); @@ -1256,12 +1223,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = 4; i < 1024; ++i) msg[i] = cpu_to_le32(0x0); - r = amdgpu_uvd_send_msg(ring, bo, direct, fence); - - if (!direct) - amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg); - - return r; + return amdgpu_uvd_send_msg(ring, bo, direct, fence); } static void amdgpu_uvd_idle_work_handler(struct work_struct *work) @@ -1336,17 +1298,10 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout) struct dma_fence *fence; long r; - r = amdgpu_uvd_get_create_msg(ring, 1, &fence); + r = amdgpu_uvd_get_create_msg(ring, 1, NULL); if (r) goto error; - r = dma_fence_wait_timeout(fence, false, timeout); - dma_fence_put(fence); - if (r == 0) - r = -ETIMEDOUT; - if (r < 0) - goto error; - r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); if (r) goto error; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 76ac969988..edbb8194ee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h @@ -68,7 +68,6 @@ struct amdgpu_uvd { /* store image width to adjust nb memory state */ unsigned decode_image_width; uint32_t keyselect; - struct amdgpu_bo *ib_bo; }; int amdgpu_uvd_sw_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 344f711ad1..8e8dee9fac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -82,6 +82,7 @@ MODULE_FIRMWARE(FIRMWARE_VEGA20); static void amdgpu_vce_idle_work_handler(struct work_struct *work); static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence); static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, bool direct, struct dma_fence **fence); @@ -313,7 +314,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev) hdr = (const struct common_firmware_header *)adev->vce.fw->data; offset = le32_to_cpu(hdr->ucode_array_offset_bytes); - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_toio(cpu_addr, adev->vce.fw->data + offset, adev->vce.fw->size - offset); drm_dev_exit(idx); @@ -434,17 +435,18 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) * * @ring: ring we should submit the msg to * @handle: VCE session handle to use + * @bo: amdgpu object for which we query the offset * @fence: optional fence to return * * Open up a stream for HW test */ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 1024; struct amdgpu_job *job; struct amdgpu_ib *ib; - struct amdgpu_ib ib_msg; struct dma_fence *f = NULL; uint64_t addr; int i, r; @@ -454,17 +456,9 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, if (r) return r; - memset(&ib_msg, 0, sizeof(ib_msg)); - /* only one gpu page is needed, alloc +1 page to make addr aligned. */ - r = amdgpu_ib_get(ring->adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2, - AMDGPU_IB_POOL_DIRECT, - &ib_msg); - if (r) - goto err; - ib = &job->ibs[0]; - /* let addr point to page boundary */ - addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg.gpu_addr); + + addr = amdgpu_bo_gpu_offset(bo); /* stitch together an VCE create msg */ ib->length_dw = 0; @@ -504,7 +498,6 @@ static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib->ptr[i] = 0x0; r = amdgpu_job_submit_direct(job, ring, &f); - amdgpu_ib_free(ring->adev, &ib_msg, f); if (r) goto err; @@ -1141,13 +1134,20 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; + struct amdgpu_bo *bo = NULL; long r; /* skip vce ring1/2 ib test for now, since it's not reliable */ if (ring != &ring->adev->vce.ring[0]) return 0; - r = amdgpu_vce_get_create_msg(ring, 1, NULL); + r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + + r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL); if (r) goto error; @@ -1163,19 +1163,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_free_kernel(&bo, NULL, NULL); return r; } - -enum amdgpu_ring_priority_level amdgpu_vce_get_ring_prio(int ring) -{ - switch(ring) { - case 0: - return AMDGPU_RING_PRIO_0; - case 1: - return AMDGPU_RING_PRIO_1; - case 2: - return AMDGPU_RING_PRIO_2; - default: - return AMDGPU_RING_PRIO_0; - } -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index be4a6e773c..d6d83a3ec8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h @@ -71,6 +71,5 @@ void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring); void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring); unsigned amdgpu_vce_ring_get_emit_ib_size(struct amdgpu_ring *ring); unsigned amdgpu_vce_ring_get_dma_frame_size(struct amdgpu_ring *ring); -enum amdgpu_ring_priority_level amdgpu_vce_get_ring_prio(int ring); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 9a19a6a57b..008a308a4e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -86,9 +86,8 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) for (i = 0; i < adev->vcn.num_vcn_inst; i++) atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0); - switch (adev->ip_versions[UVD_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): + switch (adev->asic_type) { + case CHIP_RAVEN: if (adev->apu_flags & AMD_APU_IS_RAVEN2) fw_name = FIRMWARE_RAVEN2; else if (adev->apu_flags & AMD_APU_IS_PICASSO) @@ -96,13 +95,13 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) else fw_name = FIRMWARE_RAVEN; break; - case IP_VERSION(2, 5, 0): + case CHIP_ARCTURUS: fw_name = FIRMWARE_ARCTURUS; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(2, 2, 0): + case CHIP_RENOIR: if (adev->apu_flags & AMD_APU_IS_RENOIR) fw_name = FIRMWARE_RENOIR; else @@ -112,54 +111,58 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(2, 6, 0): + case CHIP_ALDEBARAN: fw_name = FIRMWARE_ALDEBARAN; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(2, 0, 0): + case CHIP_NAVI10: fw_name = FIRMWARE_NAVI10; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(2, 0, 2): - if (adev->asic_type == CHIP_NAVI12) - fw_name = FIRMWARE_NAVI12; - else - fw_name = FIRMWARE_NAVI14; + case CHIP_NAVI14: + fw_name = FIRMWARE_NAVI14; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 64): - case IP_VERSION(3, 0, 192): - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) - fw_name = FIRMWARE_SIENNA_CICHLID; - else - fw_name = FIRMWARE_NAVY_FLOUNDER; + case CHIP_NAVI12: + fw_name = FIRMWARE_NAVI12; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(3, 0, 2): + case CHIP_SIENNA_CICHLID: + fw_name = FIRMWARE_SIENNA_CICHLID; + if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) + adev->vcn.indirect_sram = true; + break; + case CHIP_NAVY_FLOUNDER: + fw_name = FIRMWARE_NAVY_FLOUNDER; + if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) + adev->vcn.indirect_sram = true; + break; + case CHIP_VANGOGH: fw_name = FIRMWARE_VANGOGH; break; - case IP_VERSION(3, 0, 16): + case CHIP_DIMGREY_CAVEFISH: fw_name = FIRMWARE_DIMGREY_CAVEFISH; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(3, 0, 33): + case CHIP_BEIGE_GOBY: fw_name = FIRMWARE_BEIGE_GOBY; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) adev->vcn.indirect_sram = true; break; - case IP_VERSION(3, 1, 1): + case CHIP_YELLOW_CARP: fw_name = FIRMWARE_YELLOW_CARP; if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) @@ -286,13 +289,20 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type type, uint32_t vcn_instance) { bool ret = false; - int vcn_config = adev->vcn.vcn_config[vcn_instance]; - if ((type == VCN_ENCODE_RING) && (vcn_config & VCN_BLOCK_ENCODE_DISABLE_MASK)) { + int major; + int minor; + int revision; + + /* if cannot find IP data, then this VCN does not exist */ + if (amdgpu_discovery_get_vcn_version(adev, vcn_instance, &major, &minor, &revision) != 0) + return true; + + if ((type == VCN_ENCODE_RING) && (revision & VCN_BLOCK_ENCODE_DISABLE_MASK)) { ret = true; - } else if ((type == VCN_DECODE_RING) && (vcn_config & VCN_BLOCK_DECODE_DISABLE_MASK)) { + } else if ((type == VCN_DECODE_RING) && (revision & VCN_BLOCK_DECODE_DISABLE_MASK)) { ret = true; - } else if ((type == VCN_UNIFIED_RING) && (vcn_config & VCN_BLOCK_QUEUE_DISABLE_MASK)) { + } else if ((type == VCN_UNIFIED_RING) && (revision & VCN_BLOCK_QUEUE_DISABLE_MASK)) { ret = true; } @@ -320,7 +330,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) if (!adev->vcn.inst[i].saved_bo) return -ENOMEM; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); drm_dev_exit(idx); } @@ -344,7 +354,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) ptr = adev->vcn.inst[i].cpu_addr; if (adev->vcn.inst[i].saved_bo != NULL) { - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); drm_dev_exit(idx); } @@ -357,7 +367,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) hdr = (const struct common_firmware_header *)adev->vcn.fw->data; if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { offset = le32_to_cpu(hdr->ucode_array_offset_bytes); - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, le32_to_cpu(hdr->ucode_size_bytes)); drm_dev_exit(idx); @@ -531,14 +541,15 @@ int amdgpu_vcn_dec_sw_ring_test_ring(struct amdgpu_ring *ring) } static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, - struct amdgpu_ib *ib_msg, + struct amdgpu_bo *bo, struct dma_fence **fence) { struct amdgpu_device *adev = ring->adev; struct dma_fence *f = NULL; struct amdgpu_job *job; struct amdgpu_ib *ib; - uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr); + uint64_t addr; + void *msg = NULL; int i, r; r = amdgpu_job_alloc_with_ib(adev, 64, @@ -547,6 +558,8 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, goto err; ib = &job->ibs[0]; + addr = amdgpu_bo_gpu_offset(bo); + msg = amdgpu_bo_kptr(bo); ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0); ib->ptr[1] = addr; ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0); @@ -563,7 +576,9 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, if (r) goto err_free; - amdgpu_ib_free(adev, ib_msg, f); + amdgpu_bo_fence(bo, f, false); + amdgpu_bo_unreserve(bo); + amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg); if (fence) *fence = dma_fence_get(f); @@ -573,26 +588,27 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, err_free: amdgpu_job_free(job); + err: - amdgpu_ib_free(adev, ib_msg, f); + amdgpu_bo_unreserve(bo); + amdgpu_bo_free_kernel(&bo, NULL, (void **)&msg); return r; } static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, - struct amdgpu_ib *ib) + struct amdgpu_bo **bo) { struct amdgpu_device *adev = ring->adev; uint32_t *msg; int r, i; - memset(ib, 0, sizeof(*ib)); - r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2, - AMDGPU_IB_POOL_DIRECT, - ib); + *bo = NULL; + r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + bo, NULL, (void **)&msg); if (r) return r; - msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr); msg[0] = cpu_to_le32(0x00000028); msg[1] = cpu_to_le32(0x00000038); msg[2] = cpu_to_le32(0x00000001); @@ -614,20 +630,19 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand } static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct amdgpu_ib *ib) + struct amdgpu_bo **bo) { struct amdgpu_device *adev = ring->adev; uint32_t *msg; int r, i; - memset(ib, 0, sizeof(*ib)); - r = amdgpu_ib_get(adev, NULL, AMDGPU_GPU_PAGE_SIZE * 2, - AMDGPU_IB_POOL_DIRECT, - ib); + *bo = NULL; + r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + bo, NULL, (void **)&msg); if (r) return r; - msg = (uint32_t *)AMDGPU_GPU_PAGE_ALIGN((unsigned long)ib->ptr); msg[0] = cpu_to_le32(0x00000028); msg[1] = cpu_to_le32(0x00000018); msg[2] = cpu_to_le32(0x00000000); @@ -643,21 +658,21 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; - struct amdgpu_ib ib; + struct amdgpu_bo *bo; long r; - r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib); + r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo); if (r) goto error; - r = amdgpu_vcn_dec_send_msg(ring, &ib, NULL); + r = amdgpu_vcn_dec_send_msg(ring, bo, NULL); if (r) goto error; - r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib); + r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo); if (r) goto error; - r = amdgpu_vcn_dec_send_msg(ring, &ib, &fence); + r = amdgpu_vcn_dec_send_msg(ring, bo, &fence); if (r) goto error; @@ -673,8 +688,8 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) } static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, - struct amdgpu_ib *ib_msg, - struct dma_fence **fence) + struct amdgpu_bo *bo, + struct dma_fence **fence) { struct amdgpu_vcn_decode_buffer *decode_buffer = NULL; const unsigned int ib_size_dw = 64; @@ -682,7 +697,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, struct dma_fence *f = NULL; struct amdgpu_job *job; struct amdgpu_ib *ib; - uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr); + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(adev, ib_size_dw * 4, @@ -691,6 +706,7 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, goto err; ib = &job->ibs[0]; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = sizeof(struct amdgpu_vcn_decode_buffer) + 8; @@ -710,7 +726,9 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, if (r) goto err_free; - amdgpu_ib_free(adev, ib_msg, f); + amdgpu_bo_fence(bo, f, false); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); if (fence) *fence = dma_fence_get(f); @@ -720,29 +738,31 @@ static int amdgpu_vcn_dec_sw_send_msg(struct amdgpu_ring *ring, err_free: amdgpu_job_free(job); + err: - amdgpu_ib_free(adev, ib_msg, f); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; - struct amdgpu_ib ib; + struct amdgpu_bo *bo; long r; - r = amdgpu_vcn_dec_get_create_msg(ring, 1, &ib); + r = amdgpu_vcn_dec_get_create_msg(ring, 1, &bo); if (r) goto error; - r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, NULL); + r = amdgpu_vcn_dec_sw_send_msg(ring, bo, NULL); if (r) goto error; - r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &ib); + r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &bo); if (r) goto error; - r = amdgpu_vcn_dec_sw_send_msg(ring, &ib, &fence); + r = amdgpu_vcn_dec_sw_send_msg(ring, bo, &fence); if (r) goto error; @@ -789,7 +809,7 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) } static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, - struct amdgpu_ib *ib_msg, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 16; @@ -805,7 +825,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand return r; ib = &job->ibs[0]; - addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr); + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; @@ -843,7 +863,7 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand } static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct amdgpu_ib *ib_msg, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 16; @@ -859,7 +879,7 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han return r; ib = &job->ibs[0]; - addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr); + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; @@ -898,23 +918,21 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { - struct amdgpu_device *adev = ring->adev; struct dma_fence *fence = NULL; - struct amdgpu_ib ib; + struct amdgpu_bo *bo = NULL; long r; - memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(adev, NULL, (128 << 10) + AMDGPU_GPU_PAGE_SIZE, - AMDGPU_IB_POOL_DIRECT, - &ib); + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); if (r) return r; - r = amdgpu_vcn_enc_get_create_msg(ring, 1, &ib, NULL); + r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; - r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &ib, &fence); + r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); if (r) goto error; @@ -925,49 +943,9 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) r = 0; error: - amdgpu_ib_free(adev, &ib, fence); dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_free_kernel(&bo, NULL, NULL); return r; } - -enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring) -{ - switch(ring) { - case 0: - return AMDGPU_RING_PRIO_0; - case 1: - return AMDGPU_RING_PRIO_1; - case 2: - return AMDGPU_RING_PRIO_2; - default: - return AMDGPU_RING_PRIO_0; - } -} - -void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev) -{ - int i; - unsigned int idx; - - if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { - const struct common_firmware_header *hdr; - hdr = (const struct common_firmware_header *)adev->vcn.fw->data; - - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - /* currently only support 2 FW instances */ - if (i >= 2) { - dev_info(adev->dev, "More then 2 VCN FW instances!\n"); - break; - } - idx = AMDGPU_UCODE_ID_VCN + i; - adev->firmware.ucode[idx].ucode_id = idx; - adev->firmware.ucode[idx].fw = adev->vcn.fw; - adev->firmware.fw_size += - ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); - } - dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); - } -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 5d3728b027..d74c62b497 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -235,7 +235,6 @@ struct amdgpu_vcn { uint8_t num_vcn_inst; struct amdgpu_vcn_inst inst[AMDGPU_MAX_VCN_INSTANCES]; - uint8_t vcn_config[AMDGPU_MAX_VCN_INSTANCES]; struct amdgpu_vcn_reg internal; struct mutex vcn_pg_lock; struct mutex vcn1_jpeg1_workaround; @@ -309,8 +308,4 @@ int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout); int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring); int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout); -enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring); - -void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev); - #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 07bc0f5047..ca058fbccc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -283,15 +283,17 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev) *data = kmalloc(sizeof(struct amdgpu_virt_ras_err_handler_data), GFP_KERNEL); if (!*data) - goto data_failure; + return -ENOMEM; bps = kmalloc_array(align_space, sizeof((*data)->bps), GFP_KERNEL); - if (!bps) - goto bps_failure; - bps_bo = kmalloc_array(align_space, sizeof((*data)->bps_bo), GFP_KERNEL); - if (!bps_bo) - goto bps_bo_failure; + + if (!bps || !bps_bo) { + kfree(bps); + kfree(bps_bo); + kfree(*data); + return -ENOMEM; + } (*data)->bps = bps; (*data)->bps_bo = bps_bo; @@ -301,13 +303,6 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev) virt->ras_init_done = true; return 0; - -bps_bo_failure: - kfree(bps); -bps_failure: - kfree(*data); -data_failure: - return -ENOMEM; } static void amdgpu_virt_ras_release_bp(struct amdgpu_device *adev) @@ -537,12 +532,9 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev) POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC, adev->gfx.mec_fw_version); POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2, adev->gfx.mec2_fw_version); POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS, adev->psp.sos.fw_version); - POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD, - adev->psp.asd_context.bin_desc.fw_version); - POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_RAS, - adev->psp.ras_context.context.bin_desc.fw_version); - POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_XGMI, - adev->psp.xgmi_context.context.bin_desc.fw_version); + POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD, adev->psp.asd.fw_version); + POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_RAS, adev->psp.ras.feature_version); + POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_TA_XGMI, adev->psp.xgmi.feature_version); POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SMC, adev->pm.fw_version); POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA, adev->sdma.instance[0].fw_version); POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SDMA2, adev->sdma.instance[1].fw_version); @@ -553,6 +545,7 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev) static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) { struct amd_sriov_msg_vf2pf_info *vf2pf_info; + struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); vf2pf_info = (struct amd_sriov_msg_vf2pf_info *) adev->virt.fw_reserve.p_vf2pf; @@ -575,8 +568,8 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) vf2pf_info->driver_cert = 0; vf2pf_info->os_info.all = 0; - vf2pf_info->fb_usage = amdgpu_vram_mgr_usage(&adev->mman.vram_mgr) >> 20; - vf2pf_info->fb_vis_usage = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr) >> 20; + vf2pf_info->fb_usage = amdgpu_vram_mgr_usage(vram_man) >> 20; + vf2pf_info->fb_vis_usage = amdgpu_vram_mgr_vis_usage(vram_man) >> 20; vf2pf_info->fb_size = adev->gmc.real_vram_size >> 20; vf2pf_info->fb_vis_size = adev->gmc.visible_vram_size >> 20; @@ -588,7 +581,6 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) vf2pf_info->encode_usage = 0; vf2pf_info->decode_usage = 0; - vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr; vf2pf_info->checksum = amd_sriov_msg_checksum( vf2pf_info, vf2pf_info->header.size, 0, 0); @@ -621,34 +613,16 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev) void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) { + uint64_t bp_block_offset = 0; + uint32_t bp_block_size = 0; + struct amd_sriov_msg_pf2vf_info *pf2vf_v2 = NULL; + adev->virt.fw_reserve.p_pf2vf = NULL; adev->virt.fw_reserve.p_vf2pf = NULL; adev->virt.vf2pf_update_interval_ms = 0; if (adev->mman.fw_vram_usage_va != NULL) { - /* go through this logic in ip_init and reset to init workqueue*/ - amdgpu_virt_exchange_data(adev); - - INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); - schedule_delayed_work(&(adev->virt.vf2pf_work), msecs_to_jiffies(adev->virt.vf2pf_update_interval_ms)); - } else if (adev->bios != NULL) { - /* got through this logic in early init stage to get necessary flags, e.g. rlcg_acc related*/ - adev->virt.fw_reserve.p_pf2vf = - (struct amd_sriov_msg_pf2vf_info_header *) - (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); - - amdgpu_virt_read_pf2vf_data(adev); - } -} - - -void amdgpu_virt_exchange_data(struct amdgpu_device *adev) -{ - uint64_t bp_block_offset = 0; - uint32_t bp_block_size = 0; - struct amd_sriov_msg_pf2vf_info *pf2vf_v2 = NULL; - - if (adev->mman.fw_vram_usage_va != NULL) { + adev->virt.vf2pf_update_interval_ms = 2000; adev->virt.fw_reserve.p_pf2vf = (struct amd_sriov_msg_pf2vf_info_header *) @@ -674,10 +648,22 @@ void amdgpu_virt_exchange_data(struct amdgpu_device *adev) if (adev->virt.ras_init_done) amdgpu_virt_add_bad_page(adev, bp_block_offset, bp_block_size); } + } else if (adev->bios != NULL) { + adev->virt.fw_reserve.p_pf2vf = + (struct amd_sriov_msg_pf2vf_info_header *) + (adev->bios + (AMD_SRIOV_MSG_PF2VF_OFFSET_KB << 10)); + + amdgpu_virt_read_pf2vf_data(adev); + + return; + } + + if (adev->virt.vf2pf_update_interval_ms != 0) { + INIT_DELAYED_WORK(&adev->virt.vf2pf_work, amdgpu_virt_update_vf2pf_work_item); + schedule_delayed_work(&(adev->virt.vf2pf_work), adev->virt.vf2pf_update_interval_ms); } } - void amdgpu_detect_virtualization(struct amdgpu_device *adev) { uint32_t reg; @@ -720,10 +706,6 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev) vi_set_virt_ops(adev); break; case CHIP_VEGA10: - soc15_set_virt_ops(adev); - /* send a dummy GPU_INIT_DATA request to host on vega10 */ - amdgpu_virt_request_init_data(adev); - break; case CHIP_VEGA20: case CHIP_ARCTURUS: case CHIP_ALDEBARAN: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 9adfb8d632..8d4c20bb71 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -308,7 +308,6 @@ int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); void amdgpu_virt_release_ras_err_handler_data(struct amdgpu_device *adev); void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); -void amdgpu_virt_exchange_data(struct amdgpu_device *adev); void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev); void amdgpu_detect_virtualization(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index 5224d9a397..7d58bf410b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -16,8 +16,6 @@ #include "ivsrcid/ivsrcid_vislands30.h" #include "amdgpu_vkms.h" #include "amdgpu_display.h" -#include "atom.h" -#include "amdgpu_irq.h" /** * DOC: amdgpu_vkms @@ -43,16 +41,16 @@ static const u32 amdgpu_vkms_formats[] = { static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer) { - struct amdgpu_crtc *amdgpu_crtc = container_of(timer, struct amdgpu_crtc, vblank_timer); - struct drm_crtc *crtc = &amdgpu_crtc->base; - struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc); + struct amdgpu_vkms_output *output = container_of(timer, + struct amdgpu_vkms_output, + vblank_hrtimer); + struct drm_crtc *crtc = &output->crtc; u64 ret_overrun; bool ret; - ret_overrun = hrtimer_forward_now(&amdgpu_crtc->vblank_timer, + ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, output->period_ns); - if (ret_overrun != 1) - DRM_WARN("%s: vblank timer overrun\n", __func__); + WARN_ON(ret_overrun != 1); ret = drm_crtc_handle_vblank(crtc); if (!ret) @@ -67,21 +65,22 @@ static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc) unsigned int pipe = drm_crtc_index(crtc); struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc); - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); drm_calc_timestamping_constants(crtc, &crtc->mode); + hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate; out->period_ns = ktime_set(0, vblank->framedur_ns); - hrtimer_start(&amdgpu_crtc->vblank_timer, out->period_ns, HRTIMER_MODE_REL); + hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL); return 0; } static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc) { - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); + struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc); - hrtimer_cancel(&amdgpu_crtc->vblank_timer); + hrtimer_cancel(&out->vblank_hrtimer); } static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc, @@ -93,14 +92,13 @@ static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc, unsigned int pipe = crtc->index; struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc); struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); if (!READ_ONCE(vblank->enabled)) { *vblank_time = ktime_get(); return true; } - *vblank_time = READ_ONCE(amdgpu_crtc->vblank_timer.node.expires); + *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires); if (WARN_ON(*vblank_time == vblank->time)) return true; @@ -168,8 +166,6 @@ static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = { static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, struct drm_plane *primary, struct drm_plane *cursor) { - struct amdgpu_device *adev = drm_to_adev(dev); - struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); int ret; ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor, @@ -181,17 +177,6 @@ static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs); - amdgpu_crtc->crtc_id = drm_crtc_index(crtc); - adev->mode_info.crtcs[drm_crtc_index(crtc)] = amdgpu_crtc; - - amdgpu_crtc->pll_id = ATOM_PPLL_INVALID; - amdgpu_crtc->encoder = NULL; - amdgpu_crtc->connector = NULL; - amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE; - - hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - amdgpu_crtc->vblank_timer.function = &amdgpu_vkms_vblank_simulate; - return ret; } @@ -412,12 +397,12 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, return plane; } -static int amdgpu_vkms_output_init(struct drm_device *dev, struct - amdgpu_vkms_output *output, int index) +int amdgpu_vkms_output_init(struct drm_device *dev, + struct amdgpu_vkms_output *output, int index) { struct drm_connector *connector = &output->connector; struct drm_encoder *encoder = &output->encoder; - struct drm_crtc *crtc = &output->crtc.base; + struct drm_crtc *crtc = &output->crtc; struct drm_plane *primary, *cursor = NULL; int ret; @@ -481,11 +466,6 @@ static int amdgpu_vkms_sw_init(void *handle) int r, i; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, - sizeof(struct amdgpu_vkms_output), GFP_KERNEL); - if (!adev->amdgpu_vkms_output) - return -ENOMEM; - adev_to_drm(adev)->max_vblank_count = 0; adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs; @@ -502,6 +482,10 @@ static int amdgpu_vkms_sw_init(void *handle) if (r) return r; + adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, sizeof(struct amdgpu_vkms_output), GFP_KERNEL); + if (!adev->amdgpu_vkms_output) + return -ENOMEM; + /* allocate crtcs, encoders, connectors */ for (i = 0; i < adev->mode_info.num_crtc; i++) { r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i); @@ -521,16 +505,15 @@ static int amdgpu_vkms_sw_fini(void *handle) int i = 0; for (i = 0; i < adev->mode_info.num_crtc; i++) - if (adev->mode_info.crtcs[i]) - hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer); - - drm_kms_helper_poll_fini(adev_to_drm(adev)); - drm_mode_config_cleanup(adev_to_drm(adev)); - - adev->mode_info.mode_config_initialized = false; + if (adev->amdgpu_vkms_output[i].vblank_hrtimer.function) + hrtimer_cancel(&adev->amdgpu_vkms_output[i].vblank_hrtimer); kfree(adev->mode_info.bios_hardcoded_edid); kfree(adev->amdgpu_vkms_output); + + drm_kms_helper_poll_fini(adev_to_drm(adev)); + + adev->mode_info.mode_config_initialized = false; return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h index 4f8722ff37..97f1b79c07 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h @@ -10,14 +10,15 @@ #define YRES_MAX 16384 #define drm_crtc_to_amdgpu_vkms_output(target) \ - container_of(target, struct amdgpu_vkms_output, crtc.base) + container_of(target, struct amdgpu_vkms_output, crtc) extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block; struct amdgpu_vkms_output { - struct amdgpu_crtc crtc; + struct drm_crtc crtc; struct drm_encoder encoder; struct drm_connector connector; + struct hrtimer vblank_hrtimer; ktime_t period_ns; struct drm_pending_vblank_event *event; }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index d62190b3dd..fd37bb3977 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -53,7 +53,7 @@ * can be mapped as snooped (cached system pages) or unsnooped * (uncached system pages). * Each VM has an ID associated with it and there is a page table - * associated with each VMID. When executing a command buffer, + * associated with each VMID. When execting a command buffer, * the kernel tells the the ring what VMID to use for that command * buffer. VMIDs are allocated dynamically as commands are submitted. * The userspace drivers maintain their own address space and the kernel @@ -777,7 +777,8 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm) amdgpu_vm_eviction_lock(vm); ret = !vm->evicting; amdgpu_vm_eviction_unlock(vm); - return ret; + + return ret && list_empty(&vm->evicted); } /** @@ -805,7 +806,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, struct amdgpu_bo *bo = &vmbo->bo; unsigned entries, ats_entries; uint64_t addr; - int r, idx; + int r; /* Figure out our place in the hierarchy */ if (ancestor->parent) { @@ -850,12 +851,9 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, return r; } - if (!drm_dev_enter(adev_to_drm(adev), &idx)) - return -ENODEV; - r = vm->update_funcs->map_table(vmbo); if (r) - goto exit; + return r; memset(¶ms, 0, sizeof(params)); params.adev = adev; @@ -864,7 +862,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT); if (r) - goto exit; + return r; addr = 0; if (ats_entries) { @@ -880,7 +878,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, r = vm->update_funcs->update(¶ms, vmbo, addr, 0, ats_entries, value, flags); if (r) - goto exit; + return r; addr += ats_entries * 8; } @@ -903,13 +901,10 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, r = vm->update_funcs->update(¶ms, vmbo, addr, 0, entries, value, flags); if (r) - goto exit; + return r; } - r = vm->update_funcs->commit(¶ms, NULL); -exit: - drm_dev_exit(idx); - return r; + return vm->update_funcs->commit(¶ms, NULL); } /** @@ -1395,14 +1390,11 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, struct amdgpu_vm *vm, bool immediate) { struct amdgpu_vm_update_params params; - int r, idx; + int r; if (list_empty(&vm->relocated)) return 0; - if (!drm_dev_enter(adev_to_drm(adev), &idx)) - return -ENODEV; - memset(¶ms, 0, sizeof(params)); params.adev = adev; params.vm = vm; @@ -1410,7 +1402,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, r = vm->update_funcs->prepare(¶ms, NULL, AMDGPU_SYNC_EXPLICIT); if (r) - goto exit; + return r; while (!list_empty(&vm->relocated)) { struct amdgpu_vm_bo_base *entry; @@ -1428,13 +1420,10 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, r = vm->update_funcs->commit(¶ms, &vm->last_update); if (r) goto error; - drm_dev_exit(idx); return 0; error: amdgpu_vm_invalidate_pds(adev, vm); -exit: - drm_dev_exit(idx); return r; } @@ -1723,7 +1712,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, enum amdgpu_sync_mode sync_mode; int r, idx; - if (!drm_dev_enter(adev_to_drm(adev), &idx)) + if (!drm_dev_enter(&adev->ddev, &idx)) return -ENODEV; memset(¶ms, 0, sizeof(params)); @@ -2107,14 +2096,30 @@ static void amdgpu_vm_free_mapping(struct amdgpu_device *adev, static void amdgpu_vm_prt_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) { struct dma_resv *resv = vm->root.bo->tbo.base.resv; - struct dma_resv_iter cursor; - struct dma_fence *fence; + struct dma_fence *excl, **shared; + unsigned i, shared_count; + int r; - dma_resv_for_each_fence(&cursor, resv, true, fence) { - /* Add a callback for each fence in the reservation object */ - amdgpu_vm_prt_get(adev); - amdgpu_vm_add_prt_cb(adev, fence); + r = dma_resv_get_fences(resv, &excl, &shared_count, &shared); + if (r) { + /* Not enough memory to grab the fence list, as last resort + * block for all the fences to complete. + */ + dma_resv_wait_timeout(resv, true, false, + MAX_SCHEDULE_TIMEOUT); + return; } + + /* Add a callback for each fence in the reservation object */ + amdgpu_vm_prt_get(adev); + amdgpu_vm_add_prt_cb(adev, excl); + + for (i = 0; i < shared_count; ++i) { + amdgpu_vm_prt_get(adev); + amdgpu_vm_add_prt_cb(adev, shared[i]); + } + + kfree(shared); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 7a2b487db5..7b2b0980ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -96,9 +96,10 @@ static ssize_t amdgpu_mem_info_vram_used_show(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); + struct ttm_resource_manager *man; - return sysfs_emit(buf, "%llu\n", - amdgpu_vram_mgr_usage(&adev->mman.vram_mgr)); + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + return sysfs_emit(buf, "%llu\n", amdgpu_vram_mgr_usage(man)); } /** @@ -115,9 +116,10 @@ static ssize_t amdgpu_mem_info_vis_vram_used_show(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); + struct ttm_resource_manager *man; - return sysfs_emit(buf, "%llu\n", - amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr)); + man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + return sysfs_emit(buf, "%llu\n", amdgpu_vram_mgr_vis_usage(man)); } /** @@ -261,15 +263,16 @@ static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man) /** * amdgpu_vram_mgr_reserve_range - Reserve a range from VRAM * - * @mgr: amdgpu_vram_mgr pointer + * @man: TTM memory type manager * @start: start address of the range in VRAM * @size: size of the range * - * Reserve memory from start address with the specified size in VRAM + * Reserve memory from start addess with the specified size in VRAM */ -int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, +int amdgpu_vram_mgr_reserve_range(struct ttm_resource_manager *man, uint64_t start, uint64_t size) { + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); struct amdgpu_vram_reservation *rsv; rsv = kzalloc(sizeof(*rsv), GFP_KERNEL); @@ -282,7 +285,7 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, spin_lock(&mgr->lock); list_add_tail(&mgr->reservations_pending, &rsv->node); - amdgpu_vram_mgr_do_reserve(&mgr->manager); + amdgpu_vram_mgr_do_reserve(man); spin_unlock(&mgr->lock); return 0; @@ -291,7 +294,7 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, /** * amdgpu_vram_mgr_query_page_status - query the reservation status * - * @mgr: amdgpu_vram_mgr pointer + * @man: TTM memory type manager * @start: start address of a page in VRAM * * Returns: @@ -299,9 +302,10 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, * 0: the page has been reserved * -ENOENT: the input page is not a reservation */ -int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr, +int amdgpu_vram_mgr_query_page_status(struct ttm_resource_manager *man, uint64_t start) { + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); struct amdgpu_vram_reservation *rsv; int ret; @@ -628,24 +632,28 @@ void amdgpu_vram_mgr_free_sgt(struct device *dev, /** * amdgpu_vram_mgr_usage - how many bytes are used in this domain * - * @mgr: amdgpu_vram_mgr pointer + * @man: TTM memory type manager * * Returns how many bytes are used in this domain. */ -uint64_t amdgpu_vram_mgr_usage(struct amdgpu_vram_mgr *mgr) +uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man) { + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); + return atomic64_read(&mgr->usage); } /** * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part * - * @mgr: amdgpu_vram_mgr pointer + * @man: TTM memory type manager * * Returns how many bytes are used in the visible part of VRAM */ -uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr) +uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man) { + struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); + return atomic64_read(&mgr->vis_usage); } @@ -667,8 +675,8 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man, spin_unlock(&mgr->lock); drm_printf(printer, "man size:%llu pages, ram usage:%lluMB, vis usage:%lluMB\n", - man->size, amdgpu_vram_mgr_usage(mgr) >> 20, - amdgpu_vram_mgr_vis_usage(mgr) >> 20); + man->size, amdgpu_vram_mgr_usage(man) >> 20, + amdgpu_vram_mgr_vis_usage(man) >> 20); } static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index e8b8f28c2f..a799e0b1ff 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -208,7 +208,6 @@ static struct attribute *amdgpu_xgmi_hive_attrs[] = { &amdgpu_xgmi_hive_id, NULL }; -ATTRIBUTE_GROUPS(amdgpu_xgmi_hive); static ssize_t amdgpu_xgmi_show_attrs(struct kobject *kobj, struct attribute *attr, char *buf) @@ -238,7 +237,7 @@ static const struct sysfs_ops amdgpu_xgmi_hive_ops = { struct kobj_type amdgpu_xgmi_hive_type = { .release = amdgpu_xgmi_hive_release, .sysfs_ops = &amdgpu_xgmi_hive_ops, - .default_groups = amdgpu_xgmi_hive_groups, + .default_attrs = amdgpu_xgmi_hive_attrs, }; static ssize_t amdgpu_xgmi_show_device_id(struct device *dev, @@ -266,11 +265,6 @@ static ssize_t amdgpu_xgmi_show_error(struct device *dev, ficaa_pie_ctl_in = AMDGPU_XGMI_SET_FICAA(0x200); ficaa_pie_status_in = AMDGPU_XGMI_SET_FICAA(0x208); - if ((!adev->df.funcs) || - (!adev->df.funcs->get_fica) || - (!adev->df.funcs->set_fica)) - return -EINVAL; - fica_out = adev->df.funcs->get_fica(adev, ficaa_pie_ctl_in); if (fica_out != 0x1f) pr_err("xGMI error counters not enabled!\n"); @@ -813,9 +807,9 @@ static void amdgpu_xgmi_reset_ras_error_count(struct amdgpu_device *adev) for (i = 0; i < ARRAY_SIZE(xgmi23_pcs_err_status_reg_aldebaran); i++) pcs_clear_status(adev, xgmi23_pcs_err_status_reg_aldebaran[i]); - for (i = 0; i < ARRAY_SIZE(xgmi3x16_pcs_err_status_reg_aldebaran); i++) + for (i = 0; i < ARRAY_SIZE(xgmi23_pcs_err_status_reg_aldebaran); i++) pcs_clear_status(adev, - xgmi3x16_pcs_err_status_reg_aldebaran[i]); + xgmi23_pcs_err_status_reg_aldebaran[i]); for (i = 0; i < ARRAY_SIZE(walf_pcs_err_status_reg_aldebaran); i++) pcs_clear_status(adev, walf_pcs_err_status_reg_aldebaran[i]); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h index 7326b6c1b7..a434c71fde 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h @@ -204,10 +204,8 @@ struct amd_sriov_msg_pf2vf_info { } mm_bw_management[AMD_SRIOV_MSG_RESERVE_VCN_INST]; /* UUID info */ struct amd_sriov_msg_uuid_info uuid_info; - /* pcie atomic Ops info */ - uint32_t pcie_atomic_ops_enabled_flags; /* reserved */ - uint32_t reserved[256 - 48]; + uint32_t reserved[256 - 47]; }; struct amd_sriov_msg_vf2pf_info_header { @@ -261,10 +259,9 @@ struct amd_sriov_msg_vf2pf_info { uint8_t id; uint32_t version; } ucode_info[AMD_SRIOV_MSG_RESERVE_UCODE]; - uint64_t dummy_page_addr; /* reserved */ - uint32_t reserved[256-70]; + uint32_t reserved[256-68]; }; /* mailbox message send from guest to host */ diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c index ab6a07e5e8..3ac505d954 100644 --- a/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/athub_v2_0.c @@ -77,9 +77,10 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[ATHUB_HWIP][0]) { - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 2): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: athub_v2_0_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); athub_v2_0_update_medium_grain_light_sleep(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c b/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c index 2edefd10e5..c12c290073 100644 --- a/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c +++ b/drivers/gpu/drm/amd/amdgpu/athub_v2_1.c @@ -70,10 +70,11 @@ int athub_v2_1_set_clockgating(struct amdgpu_device *adev, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[ATHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: athub_v2_1_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); athub_v2_1_update_medium_grain_light_sleep(adev, state == AMD_CG_STATE_GATE); break; diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index a92d86e127..6134ed9640 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -469,7 +469,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder) if (amdgpu_connector->use_digital && (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE)) return ATOM_ENCODER_MODE_HDMI; - else if (connector->display_info.is_hdmi && + else if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) && (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else if (amdgpu_connector->use_digital) @@ -488,7 +488,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder) if (amdgpu_audio != 0) { if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE) return ATOM_ENCODER_MODE_HDMI; - else if (connector->display_info.is_hdmi && + else if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) && (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else @@ -506,7 +506,7 @@ int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder) } else if (amdgpu_audio != 0) { if (amdgpu_connector->audio == AMDGPU_AUDIO_ENABLE) return ATOM_ENCODER_MODE_HDMI; - else if (connector->display_info.is_hdmi && + else if (drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) && (amdgpu_connector->audio == AMDGPU_AUDIO_AUTO)) return ATOM_ENCODER_MODE_HDMI; else diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 8318ee8339..b200b9e722 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -2092,18 +2092,22 @@ static int dce_v8_0_pick_dig_encoder(struct drm_encoder *encoder) return 1; else return 0; + break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: if (dig->linkb) return 3; else return 2; + break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: if (dig->linkb) return 5; else return 4; + break; case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: return 6; + break; default: DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c index 43c5e3ec9a..14514a145c 100644 --- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c @@ -637,36 +637,6 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, } } -static bool df_v3_6_query_ras_poison_mode(struct amdgpu_device *adev) -{ - uint32_t hw_assert_msklo, hw_assert_mskhi; - uint32_t v0, v1, v28, v31; - - hw_assert_msklo = RREG32_SOC15(DF, 0, - mmDF_CS_UMC_AON0_HardwareAssertMaskLow); - hw_assert_mskhi = RREG32_SOC15(DF, 0, - mmDF_NCS_PG0_HardwareAssertMaskHigh); - - v0 = REG_GET_FIELD(hw_assert_msklo, - DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk0); - v1 = REG_GET_FIELD(hw_assert_msklo, - DF_CS_UMC_AON0_HardwareAssertMaskLow, HWAssertMsk1); - v28 = REG_GET_FIELD(hw_assert_mskhi, - DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk28); - v31 = REG_GET_FIELD(hw_assert_mskhi, - DF_NCS_PG0_HardwareAssertMaskHigh, HWAssertMsk31); - - if (v0 && v1 && v28 && v31) - return true; - else if (!v0 && !v1 && !v28 && !v31) - return false; - else { - dev_warn(adev->dev, "DF poison setting is inconsistent(%d:%d:%d:%d)!\n", - v0, v1, v28, v31); - return false; - } -} - const struct amdgpu_df_funcs df_v3_6_funcs = { .sw_init = df_v3_6_sw_init, .sw_fini = df_v3_6_sw_fini, @@ -681,5 +651,4 @@ const struct amdgpu_df_funcs df_v3_6_funcs = { .pmc_get_count = df_v3_6_pmc_get_count, .get_fica = df_v3_6_get_fica, .set_fica = df_v3_6_set_fica, - .query_ras_poison_mode = df_v3_6_query_ras_poison_mode, }; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index dbe7442fb2..970d59a210 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -270,6 +270,25 @@ MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec.bin"); MODULE_FIRMWARE("amdgpu/cyan_skillfish2_mec2.bin"); MODULE_FIRMWARE("amdgpu/cyan_skillfish2_rlc.bin"); +static const struct soc15_reg_golden golden_settings_gc_10_0[] = +{ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_INDEX, 0xffffffff, 0x00000000), + /* TA_GRAD_ADJ_UCONFIG -> TA_GRAD_ADJ */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2544c382), + /* VGT_TF_RING_SIZE_UMD -> VGT_TF_RING_SIZE */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2262c24e), + /* VGT_HS_OFFCHIP_PARAM_UMD -> VGT_HS_OFFCHIP_PARAM */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x226cc24f), + /* VGT_TF_MEMORY_BASE_UMD -> VGT_TF_MEMORY_BASE */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x226ec250), + /* VGT_TF_MEMORY_BASE_HI_UMD -> VGT_TF_MEMORY_BASE_HI */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2278c261), + /* VGT_ESGS_RING_SIZE_UMD -> VGT_ESGS_RING_SIZE */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2232c240), + /* VGT_GSVS_RING_SIZE_UMD -> VGT_GSVS_RING_SIZE */ + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGRBM_CAM_DATA, 0xffffffff, 0x2233c241), +}; + static const struct soc15_reg_golden golden_settings_gc_10_1[] = { SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014), @@ -1518,7 +1537,7 @@ static u32 gfx_v10_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32 scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3) * 4; - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) { + if (adev->asic_type >= CHIP_SIENNA_CICHLID) { spare_int = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_0_Sienna_Cichlid_BASE_IDX] + mmRLC_SPARE_INT_0_Sienna_Cichlid) * 4; @@ -3708,18 +3727,18 @@ static void gfx_v10_0_set_kiq_pm4_funcs(struct amdgpu_device *adev) static void gfx_v10_0_init_spm_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): + switch (adev->asic_type) { + case CHIP_NAVI10: soc15_program_register_sequence(adev, golden_settings_gc_rlc_spm_10_0_nv10, (const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_0_nv10)); break; - case IP_VERSION(10, 1, 1): + case CHIP_NAVI14: soc15_program_register_sequence(adev, golden_settings_gc_rlc_spm_10_1_nv14, (const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_1_nv14)); break; - case IP_VERSION(10, 1, 2): + case CHIP_NAVI12: soc15_program_register_sequence(adev, golden_settings_gc_rlc_spm_10_1_2_nv12, (const u32)ARRAY_SIZE(golden_settings_gc_rlc_spm_10_1_2_nv12)); @@ -3731,8 +3750,8 @@ static void gfx_v10_0_init_spm_golden_registers(struct amdgpu_device *adev) static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): + switch (adev->asic_type) { + case CHIP_NAVI10: soc15_program_register_sequence(adev, golden_settings_gc_10_1, (const u32)ARRAY_SIZE(golden_settings_gc_10_1)); @@ -3740,7 +3759,7 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_10_0_nv10, (const u32)ARRAY_SIZE(golden_settings_gc_10_0_nv10)); break; - case IP_VERSION(10, 1, 1): + case CHIP_NAVI14: soc15_program_register_sequence(adev, golden_settings_gc_10_1_1, (const u32)ARRAY_SIZE(golden_settings_gc_10_1_1)); @@ -3748,7 +3767,7 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_10_1_nv14, (const u32)ARRAY_SIZE(golden_settings_gc_10_1_nv14)); break; - case IP_VERSION(10, 1, 2): + case CHIP_NAVI12: soc15_program_register_sequence(adev, golden_settings_gc_10_1_2, (const u32)ARRAY_SIZE(golden_settings_gc_10_1_2)); @@ -3756,7 +3775,7 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_10_1_2_nv12, (const u32)ARRAY_SIZE(golden_settings_gc_10_1_2_nv12)); break; - case IP_VERSION(10, 3, 0): + case CHIP_SIENNA_CICHLID: soc15_program_register_sequence(adev, golden_settings_gc_10_3, (const u32)ARRAY_SIZE(golden_settings_gc_10_3)); @@ -3764,32 +3783,35 @@ static void gfx_v10_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_10_3_sienna_cichlid, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_sienna_cichlid)); break; - case IP_VERSION(10, 3, 2): + case CHIP_NAVY_FLOUNDER: soc15_program_register_sequence(adev, golden_settings_gc_10_3_2, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_2)); break; - case IP_VERSION(10, 3, 1): + case CHIP_VANGOGH: soc15_program_register_sequence(adev, golden_settings_gc_10_3_vangogh, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_vangogh)); break; - case IP_VERSION(10, 3, 3): + case CHIP_YELLOW_CARP: soc15_program_register_sequence(adev, golden_settings_gc_10_3_3, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_3)); break; - case IP_VERSION(10, 3, 4): + case CHIP_DIMGREY_CAVEFISH: soc15_program_register_sequence(adev, golden_settings_gc_10_3_4, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_4)); break; - case IP_VERSION(10, 3, 5): + case CHIP_BEIGE_GOBY: soc15_program_register_sequence(adev, golden_settings_gc_10_3_5, (const u32)ARRAY_SIZE(golden_settings_gc_10_3_5)); break; - case IP_VERSION(10, 1, 3): + case CHIP_CYAN_SKILLFISH: + soc15_program_register_sequence(adev, + golden_settings_gc_10_0, + (const u32)ARRAY_SIZE(golden_settings_gc_10_0)); soc15_program_register_sequence(adev, golden_settings_gc_10_0_cyan_skillfish, (const u32)ARRAY_SIZE(golden_settings_gc_10_0_cyan_skillfish)); @@ -3963,11 +3985,11 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev) { adev->gfx.cp_fw_write_wait = false; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: + case CHIP_CYAN_SKILLFISH: if ((adev->gfx.me_fw_version >= 0x00000046) && (adev->gfx.me_feature_version >= 27) && (adev->gfx.pfp_fw_version >= 0x00000068) && @@ -3976,12 +3998,12 @@ static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev) (adev->gfx.mec_feature_version >= 27)) adev->gfx.cp_fw_write_wait = true; break; - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: adev->gfx.cp_fw_write_wait = true; break; default: @@ -4044,8 +4066,8 @@ static bool gfx_v10_0_navi10_gfxoff_should_enable(struct amdgpu_device *adev) static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): + switch (adev->asic_type) { + case CHIP_NAVI10: if (!gfx_v10_0_navi10_gfxoff_should_enable(adev)) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; break; @@ -4071,38 +4093,38 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): + switch (adev->asic_type) { + case CHIP_NAVI10: chip_name = "navi10"; break; - case IP_VERSION(10, 1, 1): + case CHIP_NAVI14: chip_name = "navi14"; if (!(adev->pdev->device == 0x7340 && adev->pdev->revision != 0x00)) wks = "_wks"; break; - case IP_VERSION(10, 1, 2): + case CHIP_NAVI12: chip_name = "navi12"; break; - case IP_VERSION(10, 3, 0): + case CHIP_SIENNA_CICHLID: chip_name = "sienna_cichlid"; break; - case IP_VERSION(10, 3, 2): + case CHIP_NAVY_FLOUNDER: chip_name = "navy_flounder"; break; - case IP_VERSION(10, 3, 1): + case CHIP_VANGOGH: chip_name = "vangogh"; break; - case IP_VERSION(10, 3, 4): + case CHIP_DIMGREY_CAVEFISH: chip_name = "dimgrey_cavefish"; break; - case IP_VERSION(10, 3, 5): + case CHIP_BEIGE_GOBY: chip_name = "beige_goby"; break; - case IP_VERSION(10, 3, 3): + case CHIP_YELLOW_CARP: chip_name = "yellow_carp"; break; - case IP_VERSION(10, 1, 3): + case CHIP_CYAN_SKILLFISH: if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) chip_name = "cyan_skillfish2"; else @@ -4662,10 +4684,10 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.funcs = &gfx_v10_0_gfx_funcs; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -4673,12 +4695,12 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0; gb_addr_config = RREG32_SOC15(GC, 0, mmGB_ADDR_CONFIG); break; - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -4688,7 +4710,7 @@ static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.config.gb_addr_config_fields.num_pkrs = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PKRS); break; - case IP_VERSION(10, 1, 3): + case CHIP_CYAN_SKILLFISH: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -4796,11 +4818,11 @@ static int gfx_v10_0_sw_init(void *handle) struct amdgpu_kiq *kiq; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_CYAN_SKILLFISH: adev->gfx.me.num_me = 1; adev->gfx.me.num_pipe_per_me = 1; adev->gfx.me.num_queue_per_pipe = 1; @@ -4808,12 +4830,12 @@ static int gfx_v10_0_sw_init(void *handle) adev->gfx.mec.num_pipe_per_mec = 4; adev->gfx.mec.num_queue_per_pipe = 8; break; - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: adev->gfx.me.num_me = 1; adev->gfx.me.num_pipe_per_me = 1; adev->gfx.me.num_queue_per_pipe = 1; @@ -5046,8 +5068,8 @@ static void gfx_v10_0_setup_rb(struct amdgpu_device *adev) for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { bitmap = i * adev->gfx.config.max_sh_per_se + j; - if (((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) || - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3))) && + if (((adev->asic_type == CHIP_SIENNA_CICHLID) || + (adev->asic_type == CHIP_YELLOW_CARP)) && ((gfx_v10_3_get_disabled_sa(adev) >> bitmap) & 1)) continue; gfx_v10_0_select_se_sh(adev, i, j, 0xffffffff); @@ -5074,7 +5096,7 @@ static u32 gfx_v10_0_init_pa_sc_tile_steering_override(struct amdgpu_device *ade /* for ASICs that integrates GFX v10.3 * pa_sc_tile_steering_override should be set to 0 */ - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) + if (adev->asic_type >= CHIP_SIENNA_CICHLID) return 0; /* init num_sc */ @@ -5227,7 +5249,7 @@ static void gfx_v10_0_get_tcc_info(struct amdgpu_device *adev) /* TCCs are global (not instanced). */ uint32_t tcc_disable; - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) { + if (adev->asic_type >= CHIP_SIENNA_CICHLID) { tcc_disable = RREG32_SOC15(GC, 0, mmCGTS_TCC_DISABLE_gc_10_3) | RREG32_SOC15(GC, 0, mmCGTS_USER_TCC_DISABLE_gc_10_3); } else { @@ -5304,7 +5326,7 @@ static int gfx_v10_0_init_csb(struct amdgpu_device *adev) adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr); /* csib */ - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2)) { + if (adev->asic_type == CHIP_NAVI12) { WREG32_SOC15_RLC(GC, 0, mmRLC_CSIB_ADDR_HI, adev->gfx.rlc.clear_state_gpu_addr >> 32); WREG32_SOC15_RLC(GC, 0, mmRLC_CSIB_ADDR_LO, @@ -5926,7 +5948,7 @@ static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, enable ? 0 : 1); tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, enable ? 0 : 1); - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2)) { + if (adev->asic_type == CHIP_NAVI12) { WREG32_SOC15_RLC(GC, 0, mmCP_ME_CNTL, tmp); } else { WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); @@ -6315,13 +6337,13 @@ static void gfx_v10_0_cp_gfx_set_doorbell(struct amdgpu_device *adev, } WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_CONTROL, tmp); } - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER, DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index); WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp); @@ -6452,13 +6474,13 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev) static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) { if (enable) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0); break; default: @@ -6466,13 +6488,13 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) break; } } else { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, (CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); @@ -6564,13 +6586,13 @@ static void gfx_v10_0_kiq_setting(struct amdgpu_ring *ring) struct amdgpu_device *adev = ring->adev; /* tell RLC which is KIQ queue */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid); tmp &= 0xffffff00; tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue); @@ -7281,11 +7303,11 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev) /* check if mmVGT_ESGS_RING_SIZE_UMD * has been remapped to mmVGT_ESGS_RING_SIZE */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid); WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid, 0); WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_UMD, pattern); @@ -7298,8 +7320,8 @@ static bool gfx_v10_0_check_grbm_cam_remapping(struct amdgpu_device *adev) return false; } break; - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 3): + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: return true; default: data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE); @@ -7328,13 +7350,13 @@ static void gfx_v10_0_setup_grbm_cam_remapping(struct amdgpu_device *adev) * index will auto-inc after each data writting */ WREG32_SOC15(GC, 0, mmGRBM_CAM_INDEX, 0); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: /* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */ data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) << GRBM_CAM_DATA__CAM_ADDR__SHIFT) | @@ -7498,19 +7520,19 @@ static int gfx_v10_0_hw_init(void *handle) * init golden registers and rlc resume may override some registers, * reconfig them here */ - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 10) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 1) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2)) + if (adev->asic_type == CHIP_NAVI10 || + adev->asic_type == CHIP_NAVI14 || + adev->asic_type == CHIP_NAVI12) gfx_v10_0_tcp_harvest(adev); r = gfx_v10_0_cp_resume(adev); if (r) return r; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) + if (adev->asic_type == CHIP_SIENNA_CICHLID) gfx_v10_3_program_pbb_mode(adev); - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) + if (adev->asic_type >= CHIP_SIENNA_CICHLID) gfx_v10_3_set_power_brake_sequence(adev); return r; @@ -7562,7 +7584,7 @@ static int gfx_v10_0_hw_fini(void *handle) if (amdgpu_sriov_vf(adev)) { gfx_v10_0_cp_gfx_enable(adev, false); /* Program KIQ position of RLC_CP_SCHEDULERS during destroy */ - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) { + if (adev->asic_type >= CHIP_SIENNA_CICHLID) { tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid); tmp &= 0xffffff00; WREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid, tmp); @@ -7648,13 +7670,13 @@ static int gfx_v10_0_soft_reset(void *handle) /* GRBM_STATUS2 */ tmp = RREG32_SOC15(GC, 0, mmGRBM_STATUS2); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid)) grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, @@ -7704,9 +7726,9 @@ static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev) { uint64_t clock, clock_lo, clock_hi, hi_check; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: preempt_disable(); clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Vangogh); clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Vangogh); @@ -7773,19 +7795,19 @@ static int gfx_v10_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_CYAN_SKILLFISH: adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_NV1X; break; - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid; break; default: @@ -7837,13 +7859,13 @@ static void gfx_v10_0_set_safe_mode(struct amdgpu_device *adev) data = RLC_SAFE_MODE__CMD_MASK; data |= (1 << RLC_SAFE_MODE__MESSAGE__SHIFT); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); /* wait for RLC_SAFE_MODE */ @@ -7873,13 +7895,13 @@ static void gfx_v10_0_unset_safe_mode(struct amdgpu_device *adev) uint32_t data; data = RLC_SAFE_MODE__CMD_MASK; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); break; default: @@ -8182,7 +8204,7 @@ static void gfx_v10_0_apply_medium_grain_clock_gating_workaround(struct amdgpu_d mmCGTS_SA1_QUAD1_SM_CTRL_REG }; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2)) { + if (adev->asic_type == CHIP_NAVI12) { for (i = 0; i < ARRAY_SIZE(tcp_ctrl_regs_nv12); i++) { reg_idx = adev->reg_offset[GC_HWIP][0][mmCGTS_SA0_WGP00_CU0_TCP_CTRL_REG_BASE_IDX] + tcp_ctrl_regs_nv12[i]; @@ -8227,9 +8249,8 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, /* === CGCG + CGLS === */ gfx_v10_0_update_coarse_grain_clock_gating(adev, enable); - if ((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 10)) || - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 1)) || - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 2))) + if ((adev->asic_type >= CHIP_NAVI10) && + (adev->asic_type <= CHIP_NAVI12)) gfx_v10_0_apply_medium_grain_clock_gating_workaround(adev); } else { /* CGCG/CGLS should be disabled before MGCG/MGLS @@ -8260,9 +8281,6 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) { u32 reg, data; - - amdgpu_gfx_off_ctrl(adev, false); - /* not for *_SOC15 */ reg = SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_MC_CNTL); if (amdgpu_sriov_is_pp_one_vf(adev)) @@ -8277,8 +8295,6 @@ static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) WREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL, data); else WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data); - - amdgpu_gfx_off_ctrl(adev, true); } static bool gfx_v10_0_check_rlcg_range(struct amdgpu_device *adev, @@ -8330,12 +8346,15 @@ static void gfx_v10_cntl_power_gating(struct amdgpu_device *adev, bool enable) * Power/performance team will optimize it and might give a new value later. */ if (enable && (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_VANGOGH: data = 0x4E20 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh; WREG32_SOC15(GC, 0, mmRLC_PG_DELAY_3, data); break; + case CHIP_YELLOW_CARP: + data = 0x1388 & RLC_PG_DELAY_3__CGCG_ACTIVE_BEFORE_CGPG_MASK_Vangogh; + WREG32_SOC15(GC, 0, mmRLC_PG_DELAY_3, data); + break; default: break; } @@ -8391,18 +8410,18 @@ static int gfx_v10_0_set_powergating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: amdgpu_gfx_off_ctrl(adev, enable); break; - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 3): + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: gfx_v10_cntl_pg(adev, enable); amdgpu_gfx_off_ctrl(adev, enable); break; @@ -8420,16 +8439,16 @@ static int gfx_v10_0_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: gfx_v10_0_update_gfx_clock_gating(adev, state == AMD_CG_STATE_GATE); break; @@ -9533,19 +9552,19 @@ static void gfx_v10_0_set_irq_funcs(struct amdgpu_device *adev) static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs; break; - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 3, 0): + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs_sriov; break; default: @@ -9633,8 +9652,8 @@ static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev, for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { bitmap = i * adev->gfx.config.max_sh_per_se + j; - if (((adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) || - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 3))) && + if (((adev->asic_type == CHIP_SIENNA_CICHLID) || + (adev->asic_type == CHIP_YELLOW_CARP)) && ((gfx_v10_3_get_disabled_sa(adev) >> bitmap) & 1)) continue; mask = 1; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index d17a6f3993..37b4a3db63 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -3575,16 +3575,12 @@ static void gfx_v7_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) { u32 data; - amdgpu_gfx_off_ctrl(adev, false); - data = RREG32(mmRLC_SPM_VMID); data &= ~RLC_SPM_VMID__RLC_SPM_VMID_MASK; data |= (vmid & RLC_SPM_VMID__RLC_SPM_VMID_MASK) << RLC_SPM_VMID__RLC_SPM_VMID__SHIFT; WREG32(mmRLC_SPM_VMID, data); - - amdgpu_gfx_off_ctrl(adev, true); } static void gfx_v7_0_enable_cgcg(struct amdgpu_device *adev, bool enable) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 5f112efda6..e0302c23e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -5624,8 +5624,6 @@ static void gfx_v8_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) { u32 data; - amdgpu_gfx_off_ctrl(adev, false); - if (amdgpu_sriov_is_pp_one_vf(adev)) data = RREG32_NO_KIQ(mmRLC_SPM_VMID); else @@ -5638,8 +5636,6 @@ static void gfx_v8_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) WREG32_NO_KIQ(mmRLC_SPM_VMID, data); else WREG32(mmRLC_SPM_VMID, data); - - amdgpu_gfx_off_ctrl(adev, true); } static const struct amdgpu_rlc_funcs iceland_rlc_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 9189fb85a4..c39e53a41f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -63,13 +63,6 @@ #define mmGCEA_PROBE_MAP 0x070c #define mmGCEA_PROBE_MAP_BASE_IDX 0 -#define GFX9_RLCG_GC_WRITE_OLD (0x8 << 28) -#define GFX9_RLCG_GC_WRITE (0x0 << 28) -#define GFX9_RLCG_GC_READ (0x1 << 28) -#define GFX9_RLCG_VFGATE_DISABLED 0x4000000 -#define GFX9_RLCG_WRONG_OPERATION_TYPE 0x2000000 -#define GFX9_RLCG_NOT_IN_RANGE 0x1000000 - MODULE_FIRMWARE("amdgpu/vega10_ce.bin"); MODULE_FIRMWARE("amdgpu/vega10_pfp.bin"); MODULE_FIRMWARE("amdgpu/vega10_me.bin"); @@ -746,7 +739,7 @@ static const u32 GFX_RLC_SRM_INDEX_CNTL_DATA_OFFSETS[] = mmRLC_SRM_INDEX_CNTL_DATA_7 - mmRLC_SRM_INDEX_CNTL_DATA_0, }; -static u32 gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint32_t flag) +static void gfx_v9_0_rlcg_w(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag) { static void *scratch_reg0; static void *scratch_reg1; @@ -755,20 +748,21 @@ static u32 gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint3 static void *spare_int; static uint32_t grbm_cntl; static uint32_t grbm_idx; - uint32_t i = 0; - uint32_t retries = 50000; - u32 ret = 0; - u32 tmp; scratch_reg0 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG0_BASE_IDX] + mmSCRATCH_REG0)*4; scratch_reg1 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG1)*4; - scratch_reg2 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG2_BASE_IDX] + mmSCRATCH_REG2)*4; - scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG3_BASE_IDX] + mmSCRATCH_REG3)*4; + scratch_reg2 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG2)*4; + scratch_reg3 = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmSCRATCH_REG1_BASE_IDX] + mmSCRATCH_REG3)*4; spare_int = adev->rmmio + (adev->reg_offset[GC_HWIP][0][mmRLC_SPARE_INT_BASE_IDX] + mmRLC_SPARE_INT)*4; grbm_cntl = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_CNTL_BASE_IDX] + mmGRBM_GFX_CNTL; grbm_idx = adev->reg_offset[GC_HWIP][0][mmGRBM_GFX_INDEX_BASE_IDX] + mmGRBM_GFX_INDEX; + if (amdgpu_sriov_runtime(adev)) { + pr_err("shouldn't call rlcg write register during runtime\n"); + return; + } + if (offset == grbm_cntl || offset == grbm_idx) { if (offset == grbm_cntl) writel(v, scratch_reg2); @@ -777,95 +771,41 @@ static u32 gfx_v9_0_rlcg_rw(struct amdgpu_device *adev, u32 offset, u32 v, uint3 writel(v, ((void __iomem *)adev->rmmio) + (offset * 4)); } else { - /* - * SCRATCH_REG0 = read/write value - * SCRATCH_REG1[30:28] = command - * SCRATCH_REG1[19:0] = address in dword - * SCRATCH_REG1[26:24] = Error reporting - */ - writel(v, scratch_reg0); - writel(offset | flag, scratch_reg1); - writel(1, spare_int); + uint32_t i = 0; + uint32_t retries = 50000; + writel(v, scratch_reg0); + writel(offset | 0x80000000, scratch_reg1); + writel(1, spare_int); for (i = 0; i < retries; i++) { + u32 tmp; + tmp = readl(scratch_reg1); - if (!(tmp & flag)) + if (!(tmp & 0x80000000)) break; udelay(10); } - - if (i >= retries) { - if (amdgpu_sriov_reg_indirect_gc(adev)) { - if (tmp & GFX9_RLCG_VFGATE_DISABLED) - pr_err("The vfgate is disabled, program reg:0x%05x failed!\n", offset); - else if (tmp & GFX9_RLCG_WRONG_OPERATION_TYPE) - pr_err("Wrong operation type, program reg:0x%05x failed!\n", offset); - else if (tmp & GFX9_RLCG_NOT_IN_RANGE) - pr_err("The register is not in range, program reg:0x%05x failed!\n", offset); - else - pr_err("Unknown error type, program reg:0x%05x failed!\n", offset); - } else - pr_err("timeout: rlcg program reg:0x%05x failed!\n", offset); - } + if (i >= retries) + pr_err("timeout: rlcg program reg:0x%05x failed !\n", offset); } - ret = readl(scratch_reg0); - - return ret; -} - -static bool gfx_v9_0_get_rlcg_flag(struct amdgpu_device *adev, u32 acc_flags, u32 hwip, - int write, u32 *rlcg_flag) -{ - - switch (hwip) { - case GC_HWIP: - if (amdgpu_sriov_reg_indirect_gc(adev)) { - *rlcg_flag = write ? GFX9_RLCG_GC_WRITE : GFX9_RLCG_GC_READ; - - return true; - /* only in new version, AMDGPU_REGS_NO_KIQ and AMDGPU_REGS_RLC enabled simultaneously */ - } else if ((acc_flags & AMDGPU_REGS_RLC) && !(acc_flags & AMDGPU_REGS_NO_KIQ) && write) { - *rlcg_flag = GFX9_RLCG_GC_WRITE_OLD; - return true; - } - - break; - default: - return false; - } - - return false; -} - -static u32 gfx_v9_0_sriov_rreg(struct amdgpu_device *adev, u32 offset, u32 acc_flags, u32 hwip) -{ - u32 rlcg_flag; - - if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 0, &rlcg_flag)) - return gfx_v9_0_rlcg_rw(adev, offset, 0, rlcg_flag); - - if (acc_flags & AMDGPU_REGS_NO_KIQ) - return RREG32_NO_KIQ(offset); - else - return RREG32(offset); } static void gfx_v9_0_sriov_wreg(struct amdgpu_device *adev, u32 offset, - u32 value, u32 acc_flags, u32 hwip) + u32 v, u32 acc_flags, u32 hwip) { - u32 rlcg_flag; + if ((acc_flags & AMDGPU_REGS_RLC) && + amdgpu_sriov_fullaccess(adev)) { + gfx_v9_0_rlcg_w(adev, offset, v, acc_flags); - if (!amdgpu_sriov_runtime(adev) && gfx_v9_0_get_rlcg_flag(adev, acc_flags, hwip, 1, &rlcg_flag)) { - gfx_v9_0_rlcg_rw(adev, offset, value, rlcg_flag); return; } if (acc_flags & AMDGPU_REGS_NO_KIQ) - WREG32_NO_KIQ(offset, value); + WREG32_NO_KIQ(offset, v); else - WREG32(offset, value); + WREG32(offset, v); } #define VEGA10_GB_ADDR_CONFIG_GOLDEN 0x2a114042 @@ -1018,8 +958,8 @@ static void gfx_v9_0_set_kiq_pm4_funcs(struct amdgpu_device *adev) static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): + switch (adev->asic_type) { + case CHIP_VEGA10: soc15_program_register_sequence(adev, golden_settings_gc_9_0, ARRAY_SIZE(golden_settings_gc_9_0)); @@ -1027,7 +967,7 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_9_0_vg10, ARRAY_SIZE(golden_settings_gc_9_0_vg10)); break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: soc15_program_register_sequence(adev, golden_settings_gc_9_2_1, ARRAY_SIZE(golden_settings_gc_9_2_1)); @@ -1035,7 +975,7 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_9_2_1_vg12, ARRAY_SIZE(golden_settings_gc_9_2_1_vg12)); break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: soc15_program_register_sequence(adev, golden_settings_gc_9_0, ARRAY_SIZE(golden_settings_gc_9_0)); @@ -1043,13 +983,12 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_9_0_vg20, ARRAY_SIZE(golden_settings_gc_9_0_vg20)); break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: soc15_program_register_sequence(adev, golden_settings_gc_9_4_1_arct, ARRAY_SIZE(golden_settings_gc_9_4_1_arct)); break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + case CHIP_RAVEN: soc15_program_register_sequence(adev, golden_settings_gc_9_1, ARRAY_SIZE(golden_settings_gc_9_1)); if (adev->apu_flags & AMD_APU_IS_RAVEN2) @@ -1061,12 +1000,12 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_gc_9_1_rv1, ARRAY_SIZE(golden_settings_gc_9_1_rv1)); break; - case IP_VERSION(9, 3, 0): + case CHIP_RENOIR: soc15_program_register_sequence(adev, golden_settings_gc_9_1_rn, ARRAY_SIZE(golden_settings_gc_9_1_rn)); return; /* for renoir, don't need common goldensetting */ - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: gfx_v9_4_2_init_golden_registers(adev, adev->smuio.funcs->get_die_id(adev)); break; @@ -1074,8 +1013,8 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev) break; } - if ((adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 1)) && - (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 2))) + if ((adev->asic_type != CHIP_ARCTURUS) && + (adev->asic_type != CHIP_ALDEBARAN)) soc15_program_register_sequence(adev, golden_settings_gc_9_x_common, (const u32)ARRAY_SIZE(golden_settings_gc_9_x_common)); } @@ -1259,15 +1198,15 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev) adev->gfx.me_fw_write_wait = false; adev->gfx.mec_fw_write_wait = false; - if ((adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 1)) && + if ((adev->asic_type != CHIP_ARCTURUS) && ((adev->gfx.mec_fw_version < 0x000001a5) || (adev->gfx.mec_feature_version < 46) || (adev->gfx.pfp_fw_version < 0x000000b7) || (adev->gfx.pfp_feature_version < 46))) DRM_WARN_ONCE("CP firmware version too old, please update!"); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): + switch (adev->asic_type) { + case CHIP_VEGA10: if ((adev->gfx.me_fw_version >= 0x0000009c) && (adev->gfx.me_feature_version >= 42) && (adev->gfx.pfp_fw_version >= 0x000000b1) && @@ -1278,7 +1217,7 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev) (adev->gfx.mec_feature_version >= 42)) adev->gfx.mec_fw_write_wait = true; break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: if ((adev->gfx.me_fw_version >= 0x0000009c) && (adev->gfx.me_feature_version >= 44) && (adev->gfx.pfp_fw_version >= 0x000000b2) && @@ -1289,7 +1228,7 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev) (adev->gfx.mec_feature_version >= 44)) adev->gfx.mec_fw_write_wait = true; break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: if ((adev->gfx.me_fw_version >= 0x0000009c) && (adev->gfx.me_feature_version >= 44) && (adev->gfx.pfp_fw_version >= 0x000000b2) && @@ -1300,8 +1239,7 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev) (adev->gfx.mec_feature_version >= 44)) adev->gfx.mec_fw_write_wait = true; break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): + case CHIP_RAVEN: if ((adev->gfx.me_fw_version >= 0x0000009c) && (adev->gfx.me_feature_version >= 42) && (adev->gfx.pfp_fw_version >= 0x000000b1) && @@ -1364,7 +1302,7 @@ static bool is_raven_kicker(struct amdgpu_device *adev) static bool check_if_enlarge_doorbell_range(struct amdgpu_device *adev) { - if ((adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 3, 0)) && + if ((adev->asic_type == CHIP_RENOIR) && (adev->gfx.me_fw_version >= 0x000000a5) && (adev->gfx.me_feature_version >= 52)) return true; @@ -1377,13 +1315,12 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) if (gfx_v9_0_should_disable_gfxoff(adev->pdev)) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + case CHIP_RAVEN: if (!((adev->apu_flags & AMD_APU_IS_RAVEN2) || (adev->apu_flags & AMD_APU_IS_PICASSO)) && ((!is_raven_kicker(adev) && @@ -1397,7 +1334,7 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) AMD_PG_SUPPORT_CP | AMD_PG_SUPPORT_RLC_SMU_HS; break; - case IP_VERSION(9, 3, 0): + case CHIP_RENOIR: if (adev->pm.pp_feature & PP_GFXOFF_MASK) adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | AMD_PG_SUPPORT_CP | @@ -1621,9 +1558,9 @@ static int gfx_v9_0_init_rlc_microcode(struct amdgpu_device *adev, static bool gfx_v9_0_load_mec2_fw_bin_support(struct amdgpu_device *adev) { - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 3, 0)) + if (adev->asic_type == CHIP_ALDEBARAN || + adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_RENOIR) return false; return true; @@ -1731,18 +1668,17 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): + switch (adev->asic_type) { + case CHIP_VEGA10: chip_name = "vega10"; break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: chip_name = "vega12"; break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: chip_name = "vega20"; break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + case CHIP_RAVEN: if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; else if (adev->apu_flags & AMD_APU_IS_PICASSO) @@ -1750,16 +1686,16 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) else chip_name = "raven"; break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: chip_name = "arcturus"; break; - case IP_VERSION(9, 3, 0): + case CHIP_RENOIR: if (adev->apu_flags & AMD_APU_IS_RENOIR) chip_name = "renoir"; else chip_name = "green_sardine"; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: chip_name = "aldebaran"; break; default: @@ -1863,7 +1799,7 @@ static void gfx_v9_0_init_always_on_cu_mask(struct amdgpu_device *adev) if (adev->flags & AMD_IS_APU) always_on_cu_num = 4; - else if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 2, 1)) + else if (adev->asic_type == CHIP_VEGA12) always_on_cu_num = 8; else always_on_cu_num = 12; @@ -2032,12 +1968,11 @@ static int gfx_v9_0_rlc_init(struct amdgpu_device *adev) return r; } - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + switch (adev->asic_type) { + case CHIP_RAVEN: gfx_v9_0_init_lbpw(adev); break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: gfx_v9_4_init_lbpw(adev); break; default: @@ -2212,8 +2147,8 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.funcs = &gfx_v9_0_gfx_funcs; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): + switch (adev->asic_type) { + case CHIP_VEGA10: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -2221,7 +2156,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0; gb_addr_config = VEGA10_GB_ADDR_CONFIG_GOLDEN; break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -2230,7 +2165,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) gb_addr_config = VEGA12_GB_ADDR_CONFIG_GOLDEN; DRM_INFO("fix gfx.config for vega12\n"); break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: adev->gfx.ras_funcs = &gfx_v9_0_ras_funcs; adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; @@ -2245,8 +2180,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) if (err) return err; break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + case CHIP_RAVEN: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -2257,7 +2191,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) else gb_addr_config = RAVEN_GB_ADDR_CONFIG_GOLDEN; break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: adev->gfx.ras_funcs = &gfx_v9_4_ras_funcs; adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; @@ -2268,7 +2202,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) gb_addr_config &= ~0xf3e777ff; gb_addr_config |= 0x22014042; break; - case IP_VERSION(9, 3, 0): + case CHIP_RENOIR: adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; adev->gfx.config.sc_prim_fifo_size_backend = 0x100; @@ -2278,7 +2212,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev) gb_addr_config &= ~0xf3e777ff; gb_addr_config |= 0x22010042; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: adev->gfx.ras_funcs = &gfx_v9_4_2_ras_funcs; adev->gfx.config.max_hw_contexts = 8; adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; @@ -2376,15 +2310,14 @@ static int gfx_v9_0_sw_init(void *handle) struct amdgpu_kiq *kiq; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 2): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_ARCTURUS: + case CHIP_RENOIR: + case CHIP_ALDEBARAN: adev->gfx.mec.num_mec = 2; break; default: @@ -2527,9 +2460,7 @@ static int gfx_v9_0_sw_fini(void *handle) amdgpu_gfx_kiq_fini(adev); gfx_v9_0_mec_fini(adev); - amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj, - &adev->gfx.rlc.clear_state_gpu_addr, - (void **)&adev->gfx.rlc.cs_ptr); + amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj); if (adev->flags & AMD_IS_APU) { amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj, &adev->gfx.rlc.cp_table_gpu_addr, @@ -2670,8 +2601,8 @@ static void gfx_v9_0_init_sq_config(struct amdgpu_device *adev) { uint32_t tmp; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 4, 1): + switch (adev->asic_type) { + case CHIP_ARCTURUS: tmp = RREG32_SOC15(GC, 0, mmSQ_CONFIG); tmp = REG_SET_FIELD(tmp, SQ_CONFIG, DISABLE_BARRIER_WAITCNT, 1); @@ -3006,7 +2937,7 @@ static void gfx_v9_0_init_gfx_power_gating(struct amdgpu_device *adev) /* program GRBM_REG_SAVE_GFX_IDLE_THRESHOLD to 0x55f0 */ data |= (0x55f0 << RLC_AUTO_PG_CTRL__GRBM_REG_SAVE_GFX_IDLE_THRESHOLD__SHIFT); WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_AUTO_PG_CTRL), data); - if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 3, 0)) + if (adev->asic_type != CHIP_RENOIR) pwr_10_0_gfxip_control_over_cgpg(adev, true); } } @@ -3118,7 +3049,7 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) * And it's needed by gfxoff feature. */ if (adev->gfx.rlc.is_rlc_v2_1) { - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 2, 1) || + if (adev->asic_type == CHIP_VEGA12 || (adev->apu_flags & AMD_APU_IS_RAVEN2)) gfx_v9_1_init_rlc_save_restore_list(adev); gfx_v9_0_enable_save_restore_machine(adev); @@ -3231,15 +3162,14 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) return r; } - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + switch (adev->asic_type) { + case CHIP_RAVEN: if (amdgpu_lbpw == 0) gfx_v9_0_enable_lbpw(adev, false); else gfx_v9_0_enable_lbpw(adev, true); break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: if (amdgpu_lbpw > 0) gfx_v9_0_enable_lbpw(adev, true); else @@ -4034,8 +3964,8 @@ static void gfx_v9_0_init_tcp_config(struct amdgpu_device *adev) { u32 tmp; - if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 1) && - adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 2)) + if (adev->asic_type != CHIP_ARCTURUS && + adev->asic_type != CHIP_ALDEBARAN) return; tmp = RREG32_SOC15(GC, 0, mmTCP_ADDR_CONFIG); @@ -4075,7 +4005,7 @@ static int gfx_v9_0_hw_init(void *handle) if (r) return r; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) + if (adev->asic_type == CHIP_ALDEBARAN) gfx_v9_4_2_set_power_brake_sequence(adev); return r; @@ -4120,10 +4050,9 @@ static int gfx_v9_0_hw_fini(void *handle) gfx_v9_0_cp_enable(adev, false); - /* Skip stopping RLC with A+A reset or when RLC controls GFX clock */ - if ((adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) || - (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2))) { - dev_dbg(adev->dev, "Skipping RLC halt\n"); + /* Skip suspend with A+A reset */ + if (adev->gmc.xgmi.connected_to_cpu && amdgpu_in_reset(adev)) { + dev_dbg(adev->dev, "Device in reset. Skipping RLC halt\n"); return 0; } @@ -4306,8 +4235,8 @@ static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev) { uint64_t clock, clock_lo, clock_hi, hi_check; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 3, 0): + switch (adev->asic_type) { + case CHIP_RENOIR: preempt_disable(); clock_hi = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_UPPER_Renoir); clock_lo = RREG32_SOC15_NO_KIQ(SMUIO, 0, mmGOLDEN_TSC_COUNT_LOWER_Renoir); @@ -4325,7 +4254,7 @@ static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev) default: amdgpu_gfx_off_ctrl(adev, false); mutex_lock(&adev->gfx.gpu_clock_mutex); - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 0, 1) && amdgpu_sriov_runtime(adev)) { + if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) { clock = gfx_v9_0_kiq_read_clock(adev); } else { WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); @@ -4677,7 +4606,7 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) if (!ring->sched.ready) return 0; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1)) { + if (adev->asic_type == CHIP_ARCTURUS) { vgpr_init_shader_ptr = vgpr_init_compute_shader_arcturus; vgpr_init_shader_size = sizeof(vgpr_init_compute_shader_arcturus); vgpr_init_regs_ptr = vgpr_init_regs_arcturus; @@ -4827,8 +4756,8 @@ static int gfx_v9_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) + if (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) adev->gfx.num_gfx_rings = 0; else adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS; @@ -4862,7 +4791,7 @@ static int gfx_v9_0_ecc_late_init(void *handle) } /* requires IBs so do in late init after IB pool is initialized */ - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) + if (adev->asic_type == CHIP_ALDEBARAN) r = gfx_v9_4_2_do_edc_gpr_workarounds(adev); else r = gfx_v9_0_do_edc_gpr_workarounds(adev); @@ -4990,7 +4919,7 @@ static void gfx_v9_0_update_medium_grain_clock_gating(struct amdgpu_device *adev /* 1 - RLC_CGTT_MGCG_OVERRIDE */ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); - if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 2, 1)) + if (adev->asic_type != CHIP_VEGA12) data &= ~RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK; data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | @@ -5024,7 +4953,7 @@ static void gfx_v9_0_update_medium_grain_clock_gating(struct amdgpu_device *adev /* 1 - MGCG_OVERRIDE */ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); - if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 2, 1)) + if (adev->asic_type != CHIP_VEGA12) data |= RLC_CGTT_MGCG_OVERRIDE__CPF_CGTT_SCLK_OVERRIDE_MASK; data |= (RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK | @@ -5130,7 +5059,7 @@ static void gfx_v9_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev /* enable cgcg FSM(0x0000363F) */ def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL); - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1)) + if (adev->asic_type == CHIP_ARCTURUS) data = (0x2000 << RLC_CGCG_CGLS_CTRL__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK; else @@ -5189,13 +5118,11 @@ static void gfx_v9_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) { u32 reg, data; - amdgpu_gfx_off_ctrl(adev, false); - reg = SOC15_REG_OFFSET(GC, 0, mmRLC_SPM_MC_CNTL); if (amdgpu_sriov_is_pp_one_vf(adev)) data = RREG32_NO_KIQ(reg); else - data = RREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL); + data = RREG32(reg); data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK; data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT; @@ -5204,8 +5131,6 @@ static void gfx_v9_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid) WREG32_SOC15_NO_KIQ(GC, 0, mmRLC_SPM_MC_CNTL, data); else WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data); - - amdgpu_gfx_off_ctrl(adev, true); } static bool gfx_v9_0_check_rlcg_range(struct amdgpu_device *adev, @@ -5251,7 +5176,6 @@ static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = { .start = gfx_v9_0_rlc_start, .update_spm_vmid = gfx_v9_0_update_spm_vmid, .sriov_wreg = gfx_v9_0_sriov_wreg, - .sriov_rreg = gfx_v9_0_sriov_rreg, .is_rlcg_access_range = gfx_v9_0_is_rlcg_access_range, }; @@ -5261,10 +5185,9 @@ static int gfx_v9_0_set_powergating_state(void *handle, struct amdgpu_device *adev = (struct amdgpu_device *)handle; bool enable = (state == AMD_PG_STATE_GATE); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 3, 0): + switch (adev->asic_type) { + case CHIP_RAVEN: + case CHIP_RENOIR: if (!enable) amdgpu_gfx_off_ctrl(adev, false); @@ -5290,7 +5213,7 @@ static int gfx_v9_0_set_powergating_state(void *handle, if (enable) amdgpu_gfx_off_ctrl(adev, true); break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: amdgpu_gfx_off_ctrl(adev, enable); break; default: @@ -5308,15 +5231,14 @@ static int gfx_v9_0_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 2): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_ARCTURUS: + case CHIP_RENOIR: + case CHIP_ALDEBARAN: gfx_v9_0_update_gfx_clock_gating(adev, state == AMD_CG_STATE_GATE); break; @@ -5358,7 +5280,7 @@ static void gfx_v9_0_get_clockgating_state(void *handle, u32 *flags) if (data & CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK) *flags |= AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_MGLS; - if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 1)) { + if (adev->asic_type != CHIP_ARCTURUS) { /* AMD_CG_SUPPORT_GFX_3D_CGCG */ data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D)); if (data & RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK) @@ -5857,16 +5779,16 @@ static void gfx_v9_0_set_compute_eop_interrupt_state(struct amdgpu_device *adev, switch (state) { case AMDGPU_IRQ_STATE_DISABLE: - mec_int_cntl = RREG32_SOC15_IP(GC,mec_int_cntl_reg); + mec_int_cntl = RREG32(mec_int_cntl_reg); mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL, TIME_STAMP_INT_ENABLE, 0); - WREG32_SOC15_IP(GC, mec_int_cntl_reg, mec_int_cntl); + WREG32(mec_int_cntl_reg, mec_int_cntl); break; case AMDGPU_IRQ_STATE_ENABLE: - mec_int_cntl = RREG32_SOC15_IP(GC, mec_int_cntl_reg); + mec_int_cntl = RREG32(mec_int_cntl_reg); mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL, TIME_STAMP_INT_ENABLE, 1); - WREG32_SOC15_IP(GC, mec_int_cntl_reg, mec_int_cntl); + WREG32(mec_int_cntl_reg, mec_int_cntl); break; default: break; @@ -7129,15 +7051,14 @@ static void gfx_v9_0_set_irq_funcs(struct amdgpu_device *adev) static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 2): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_ARCTURUS: + case CHIP_RENOIR: + case CHIP_ALDEBARAN: adev->gfx.rlc.funcs = &gfx_v9_0_rlc_funcs; break; default: @@ -7148,18 +7069,17 @@ static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev) static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev) { /* init asci gds info */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: adev->gds.gds_size = 0x10000; break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 4, 1): + case CHIP_RAVEN: + case CHIP_ARCTURUS: adev->gds.gds_size = 0x1000; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: /* aldebaran removed all the GDS internal memory, * only support GWS opcode in kernel, like barrier * semaphore.etc */ @@ -7170,25 +7090,24 @@ static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev) break; } - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 4, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA20: adev->gds.gds_compute_max_wave_id = 0x7ff; break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: adev->gds.gds_compute_max_wave_id = 0x27f; break; - case IP_VERSION(9, 2, 2): - case IP_VERSION(9, 1, 0): + case CHIP_RAVEN: if (adev->apu_flags & AMD_APU_IS_RAVEN2) adev->gds.gds_compute_max_wave_id = 0x77; /* raven2 */ else adev->gds.gds_compute_max_wave_id = 0x15f; /* raven1 */ break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: adev->gds.gds_compute_max_wave_id = 0xfff; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: /* deprecated for Aldebaran, no usage at all */ adev->gds.gds_compute_max_wave_id = 0; break; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c index c4f37a1618..00a2b36a24 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c @@ -706,11 +706,6 @@ int gfx_v9_4_2_do_edc_gpr_workarounds(struct amdgpu_device *adev) if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) return 0; - /* Workaround for ALDEBARAN, skip GPRs init in GPU reset. - Will remove it once GPRs init algorithm works for all CU settings. */ - if (amdgpu_in_reset(adev)) - return 0; - gfx_v9_4_2_do_sgprs_init(adev); gfx_v9_4_2_do_vgprs_init(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c index ec4d5e15b7..f51fd0688e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -347,10 +347,6 @@ static void gfxhub_v1_0_gart_disable(struct amdgpu_device *adev) WREG32_SOC15_OFFSET(GC, 0, mmVM_CONTEXT0_CNTL, i * hub->ctx_distance, 0); - if (amdgpu_sriov_vf(adev)) - /* Avoid write to GMC registers */ - return; - /* Setup TLB control */ tmp = RREG32_SOC15(GC, 0, mmMC_VM_MX_L1_TLB_CNTL); tmp = REG_SET_FIELD(tmp, MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c index 90f0aefbdb..497b86c376 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.c @@ -54,17 +54,15 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev) seg_size = REG_GET_FIELD( RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE_ALDE), MC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24; - max_region = - REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL_ALDE, PF_MAX_REGION); } else { xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL); seg_size = REG_GET_FIELD( RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_SIZE), MC_VM_XGMI_LFB_SIZE, PF_LFB_SIZE) << 24; - max_region = - REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION); } + max_region = + REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION); switch (adev->asic_type) { @@ -91,15 +89,9 @@ int gfxhub_v1_1_get_xgmi_info(struct amdgpu_device *adev) if (adev->gmc.xgmi.num_physical_nodes > max_num_physical_nodes) return -EINVAL; - if (adev->asic_type == CHIP_ALDEBARAN) { - adev->gmc.xgmi.physical_node_id = - REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL_ALDE, - PF_LFB_REGION); - } else { - adev->gmc.xgmi.physical_node_id = - REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, - PF_LFB_REGION); - } + adev->gmc.xgmi.physical_node_id = + REG_GET_FIELD(xgmi_lfb_cntl, MC_VM_XGMI_LFB_CNTL, + PF_LFB_REGION); if (adev->gmc.xgmi.physical_node_id > max_physical_node_id) return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c index ff738e9725..9328991e88 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_1.c @@ -505,8 +505,8 @@ static int gfxhub_v2_1_get_xgmi_info(struct amdgpu_device *adev) u32 max_num_physical_nodes = 0; u32 max_physical_node_id = 0; - switch (adev->ip_versions[XGMI_HWIP][0]) { - case IP_VERSION(4, 8, 0): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: max_num_physical_nodes = 4; max_physical_node_id = 3; break; @@ -543,9 +543,7 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev) adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines); - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 3): + if (adev->asic_type == CHIP_YELLOW_CARP) { /* Get SA disabled bitmap from eFuse setting */ efuse_setting = RREG32_SOC15(GC, 0, mmCC_GC_SA_UNIT_DISABLE); efuse_setting &= CC_GC_SA_UNIT_DISABLE__SA_DISABLE_MASK; @@ -568,9 +566,6 @@ static void gfxhub_v2_1_utcl2_harvest(struct amdgpu_device *adev) disabled_sa = tmp; WREG32_SOC15(GC, 0, mmGCUTCL2_HARVEST_BYPASS_GROUPS_YELLOW_CARP, disabled_sa); - break; - default: - break; } } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index a2f8ed0e6a..3c01be6610 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -107,7 +107,7 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev, /* Process it onyl if it's the first fault for this address */ if (entry->ih != &adev->irq.ih_soft && - amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid, + amdgpu_gmc_filter_faults(adev, addr, entry->pasid, entry->timestamp)) return 1; @@ -133,7 +133,7 @@ static int gmc_v10_0_process_interrupt(struct amdgpu_device *adev, * the new fast GRBM interface. */ if ((entry->vmid_src == AMDGPU_GFXHUB_0) && - (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 3, 0))) + (adev->asic_type < CHIP_SIENNA_CICHLID)) RREG32(hub->vm_l2_pro_fault_status); status = RREG32(hub->vm_l2_pro_fault_status); @@ -268,7 +268,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, * to avoid a false ACK due to the new fast GRBM interface. */ if ((vmhub == AMDGPU_GFXHUB_0) && - (adev->ip_versions[GC_HWIP][0] < IP_VERSION(10, 3, 0))) + (adev->asic_type < CHIP_SIENNA_CICHLID)) RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, hub_ip); @@ -657,8 +657,8 @@ static void gmc_v10_0_set_gmc_funcs(struct amdgpu_device *adev) static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[UMC_HWIP][0]) { - case IP_VERSION(8, 7, 0): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: adev->umc.max_ras_err_cnt_per_query = UMC_V8_7_TOTAL_CHANNEL_NUM; adev->umc.channel_inst_num = UMC_V8_7_CHANNEL_INSTANCE_NUM; adev->umc.umc_inst_num = UMC_V8_7_UMC_INSTANCE_NUM; @@ -674,9 +674,9 @@ static void gmc_v10_0_set_umc_funcs(struct amdgpu_device *adev) static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 3, 0): - case IP_VERSION(2, 4, 0): + switch (adev->asic_type) { + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: adev->mmhub.funcs = &mmhub_v2_3_funcs; break; default: @@ -687,13 +687,13 @@ static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev) static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: adev->gfxhub.funcs = &gfxhub_v2_1_funcs; break; default: @@ -800,9 +800,23 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev) adev->gmc.visible_vram_size = adev->gmc.real_vram_size; /* set the gart size */ - if (amdgpu_gart_size == -1) - adev->gmc.gart_size = 512ULL << 20; - else + if (amdgpu_gart_size == -1) { + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + default: + adev->gmc.gart_size = 512ULL << 20; + break; + } + } else adev->gmc.gart_size = (u64)amdgpu_gart_size << 20; gmc_v10_0_vram_gtt_location(adev, &adev->gmc); @@ -857,17 +871,17 @@ static int gmc_v10_0_sw_init(void *handle) adev->gmc.vram_vendor = vram_vendor; } - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 1): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - case IP_VERSION(10, 3, 0): - case IP_VERSION(10, 3, 2): - case IP_VERSION(10, 3, 1): - case IP_VERSION(10, 3, 4): - case IP_VERSION(10, 3, 5): - case IP_VERSION(10, 3, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: adev->num_vmhubs = 2; /* * To fulfill 4-level page support, @@ -914,6 +928,12 @@ static int gmc_v10_0_sw_init(void *handle) return r; } + if (adev->gmc.xgmi.supported) { + r = adev->gfxhub.funcs->get_xgmi_info(adev); + if (r) + return r; + } + r = gmc_v10_0_mc_init(adev); if (r) return r; @@ -969,6 +989,21 @@ static int gmc_v10_0_sw_fini(void *handle) static void gmc_v10_0_init_golden_registers(struct amdgpu_device *adev) { + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + break; + default: + break; + } } /** @@ -989,7 +1024,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) goto skip_pin_bo; - r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); + r = amdgpu_gart_table_vram_pin(adev); if (r) return r; @@ -1060,6 +1095,7 @@ static void gmc_v10_0_gart_disable(struct amdgpu_device *adev) { adev->gfxhub.funcs->gart_disable(adev); adev->mmhub.funcs->gart_disable(adev); + amdgpu_gart_table_vram_unpin(adev); } static int gmc_v10_0_hw_fini(void *handle) @@ -1130,7 +1166,8 @@ static int gmc_v10_0_set_clockgating_state(void *handle, if (r) return r; - if (adev->ip_versions[ATHUB_HWIP][0] >= IP_VERSION(2, 1, 0)) + if (adev->asic_type >= CHIP_SIENNA_CICHLID && + adev->asic_type <= CHIP_YELLOW_CARP) return athub_v2_1_set_clockgating(adev, state); else return athub_v2_0_set_clockgating(adev, state); @@ -1140,12 +1177,10 @@ static void gmc_v10_0_get_clockgating_state(void *handle, u32 *flags) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 1, 3)) - return; - adev->mmhub.funcs->get_clockgating(adev, flags); - if (adev->ip_versions[ATHUB_HWIP][0] >= IP_VERSION(2, 1, 0)) + if (adev->asic_type >= CHIP_SIENNA_CICHLID && + adev->asic_type <= CHIP_YELLOW_CARP) athub_v2_1_get_clockgating(adev, flags); else athub_v2_0_get_clockgating(adev, flags); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index cd6c38e083..0fe714f54c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -476,7 +476,7 @@ static int gmc_v6_0_gart_enable(struct amdgpu_device *adev) dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); return -EINVAL; } - r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); + r = amdgpu_gart_table_vram_pin(adev); if (r) return r; @@ -608,6 +608,7 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev) WREG32(mmVM_L2_CNTL3, VM_L2_CNTL3__L2_CACHE_BIGK_ASSOCIATIVITY_MASK | (0UL << VM_L2_CNTL3__L2_CACHE_BIGK_FRAGMENT_SIZE__SHIFT)); + amdgpu_gart_table_vram_unpin(adev); } static void gmc_v6_0_vm_decode_fault(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index ab8adbff9e..0a50fdaced 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -620,7 +620,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); return -EINVAL; } - r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); + r = amdgpu_gart_table_vram_pin(adev); if (r) return r; @@ -758,6 +758,7 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev) tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); WREG32(mmVM_L2_CNTL, tmp); WREG32(mmVM_L2_CNTL2, 0); + amdgpu_gart_table_vram_unpin(adev); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 0547338382..63b890f1e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -844,7 +844,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) dev_err(adev->dev, "No VRAM object for PCIE GART.\n"); return -EINVAL; } - r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); + r = amdgpu_gart_table_vram_pin(adev); if (r) return r; @@ -999,6 +999,7 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev) tmp = REG_SET_FIELD(tmp, VM_L2_CNTL, ENABLE_L2_CACHE, 0); WREG32(mmVM_L2_CNTL, tmp); WREG32(mmVM_L2_CNTL2, 0); + amdgpu_gart_table_vram_unpin(adev); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 88c1eb9ad0..c67e212443 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -481,18 +481,9 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, hub = &adev->vmhub[j]; for (i = 0; i < 16; i++) { reg = hub->vm_context0_cntl + i; - - if (j == AMDGPU_GFXHUB_0) - tmp = RREG32_SOC15_IP(GC, reg); - else - tmp = RREG32_SOC15_IP(MMHUB, reg); - + tmp = RREG32(reg); tmp &= ~bits; - - if (j == AMDGPU_GFXHUB_0) - WREG32_SOC15_IP(GC, reg, tmp); - else - WREG32_SOC15_IP(MMHUB, reg, tmp); + WREG32(reg, tmp); } } break; @@ -501,18 +492,9 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, hub = &adev->vmhub[j]; for (i = 0; i < 16; i++) { reg = hub->vm_context0_cntl + i; - - if (j == AMDGPU_GFXHUB_0) - tmp = RREG32_SOC15_IP(GC, reg); - else - tmp = RREG32_SOC15_IP(MMHUB, reg); - + tmp = RREG32(reg); tmp |= bits; - - if (j == AMDGPU_GFXHUB_0) - WREG32_SOC15_IP(GC, reg, tmp); - else - WREG32_SOC15_IP(MMHUB, reg, tmp); + WREG32(reg, tmp); } } break; @@ -544,7 +526,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, /* Process it onyl if it's the first fault for this address */ if (entry->ih != &adev->irq.ih_soft && - amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid, + amdgpu_gmc_filter_faults(adev, addr, entry->pasid, entry->timestamp)) return 1; @@ -600,7 +582,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, * the new fast GRBM interface. */ if ((entry->vmid_src == AMDGPU_GFXHUB_0) && - (adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 4, 2))) + (adev->asic_type < CHIP_ALDEBARAN)) RREG32(hub->vm_l2_pro_fault_status); status = RREG32(hub->vm_l2_pro_fault_status); @@ -618,28 +600,26 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, gfxhub_client_ids[cid], cid); } else { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(9, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: mmhub_cid = mmhub_client_ids_vega10[cid][rw]; break; - case IP_VERSION(9, 3, 0): + case CHIP_VEGA12: mmhub_cid = mmhub_client_ids_vega12[cid][rw]; break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: mmhub_cid = mmhub_client_ids_vega20[cid][rw]; break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: mmhub_cid = mmhub_client_ids_arcturus[cid][rw]; break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 0): + case CHIP_RAVEN: mmhub_cid = mmhub_client_ids_raven[cid][rw]; break; - case IP_VERSION(1, 5, 0): - case IP_VERSION(2, 4, 0): + case CHIP_RENOIR: mmhub_cid = mmhub_client_ids_renoir[cid][rw]; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: mmhub_cid = mmhub_client_ids_aldebaran[cid][rw]; break; default: @@ -717,7 +697,7 @@ static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid, static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev, uint32_t vmhub) { - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) + if (adev->asic_type == CHIP_ALDEBARAN) return false; return ((vmhub == AMDGPU_MMHUB_0 || @@ -768,7 +748,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, hub = &adev->vmhub[vmhub]; if (adev->gmc.xgmi.num_physical_nodes && - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)) { + adev->asic_type == CHIP_VEGA20) { /* Vega20+XGMI caches PTEs in TC and TLB. Add a * heavy-weight TLB flush (type 2), which flushes * both. Due to a race condition with concurrent @@ -809,12 +789,9 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ if (use_semaphore) { for (j = 0; j < adev->usec_timeout; j++) { - /* a read return value of 1 means semaphore acquire */ - if (vmhub == AMDGPU_GFXHUB_0) - tmp = RREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_sem + hub->eng_distance * eng); - else - tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_sem + hub->eng_distance * eng); - + /* a read return value of 1 means semaphore acuqire */ + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + + hub->eng_distance * eng); if (tmp & 0x1) break; udelay(1); @@ -825,10 +802,8 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, } do { - if (vmhub == AMDGPU_GFXHUB_0) - WREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req); - else - WREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req); + WREG32_NO_KIQ(hub->vm_inv_eng0_req + + hub->eng_distance * eng, inv_req); /* * Issue a dummy read to wait for the ACK register to @@ -836,16 +811,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, * GRBM interface. */ if ((vmhub == AMDGPU_GFXHUB_0) && - (adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 4, 2))) + (adev->asic_type < CHIP_ALDEBARAN)) RREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng); for (j = 0; j < adev->usec_timeout; j++) { - if (vmhub == AMDGPU_GFXHUB_0) - tmp = RREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_ack + hub->eng_distance * eng); - else - tmp = RREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_ack + hub->eng_distance * eng); - + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack + + hub->eng_distance * eng); if (tmp & (1 << vmid)) break; udelay(1); @@ -856,16 +828,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, } while (inv_req); /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ - if (use_semaphore) { + if (use_semaphore) /* * add semaphore release after invalidation, * write with 0 means semaphore release */ - if (vmhub == AMDGPU_GFXHUB_0) - WREG32_SOC15_IP_NO_KIQ(GC, hub->vm_inv_eng0_sem + hub->eng_distance * eng, 0); - else - WREG32_SOC15_IP_NO_KIQ(MMHUB, hub->vm_inv_eng0_sem + hub->eng_distance * eng, 0); - } + WREG32_NO_KIQ(hub->vm_inv_eng0_sem + + hub->eng_distance * eng, 0); spin_unlock(&adev->gmc.invalidate_lock); @@ -908,7 +877,7 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev, * still need a second TLB flush after this. */ bool vega20_xgmi_wa = (adev->gmc.xgmi.num_physical_nodes && - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0)); + adev->asic_type == CHIP_VEGA20); /* 2 dwords flush + 8 dwords fence */ unsigned int ndw = kiq->pmf->invalidate_tlbs_size + 8; @@ -1122,13 +1091,13 @@ static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev, *flags &= ~AMDGPU_PTE_VALID; } - if ((adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) && + if ((adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) && !(*flags & AMDGPU_PTE_SYSTEM) && mapping->bo_va->is_xgmi) *flags |= AMDGPU_PTE_SNOOPED; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) + if (adev->asic_type == CHIP_ALDEBARAN) *flags |= mapping->flags & AMDGPU_PTE_SNOOPED; } @@ -1144,9 +1113,8 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) } else { u32 viewport; - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): + switch (adev->asic_type) { + case CHIP_RAVEN: viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION); size = (REG_GET_FIELD(viewport, HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) * @@ -1154,7 +1122,7 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) * 4); break; - case IP_VERSION(2, 1, 0): + case CHIP_RENOIR: viewport = RREG32_SOC15(DCE, 0, mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_DCN2); size = (REG_GET_FIELD(viewport, HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) * @@ -1162,6 +1130,9 @@ static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev) HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) * 4); break; + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: default: viewport = RREG32_SOC15(DCE, 0, mmSCL0_VIEWPORT_SIZE); size = (REG_GET_FIELD(viewport, SCL0_VIEWPORT_SIZE, VIEWPORT_HEIGHT) * @@ -1192,11 +1163,11 @@ static void gmc_v9_0_set_gmc_funcs(struct amdgpu_device *adev) static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[UMC_HWIP][0]) { - case IP_VERSION(6, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: adev->umc.funcs = &umc_v6_0_funcs; break; - case IP_VERSION(6, 1, 1): + case CHIP_VEGA20: adev->umc.max_ras_err_cnt_per_query = UMC_V6_1_TOTAL_CHANNEL_NUM; adev->umc.channel_inst_num = UMC_V6_1_CHANNEL_INSTANCE_NUM; adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM; @@ -1204,7 +1175,7 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev) adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0]; adev->umc.ras_funcs = &umc_v6_1_ras_funcs; break; - case IP_VERSION(6, 1, 2): + case CHIP_ARCTURUS: adev->umc.max_ras_err_cnt_per_query = UMC_V6_1_TOTAL_CHANNEL_NUM; adev->umc.channel_inst_num = UMC_V6_1_CHANNEL_INSTANCE_NUM; adev->umc.umc_inst_num = UMC_V6_1_UMC_INSTANCE_NUM; @@ -1212,7 +1183,7 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev) adev->umc.channel_idx_tbl = &umc_v6_1_channel_idx_tbl[0][0]; adev->umc.ras_funcs = &umc_v6_1_ras_funcs; break; - case IP_VERSION(6, 7, 0): + case CHIP_ALDEBARAN: adev->umc.max_ras_err_cnt_per_query = UMC_V6_7_TOTAL_CHANNEL_NUM; adev->umc.channel_inst_num = UMC_V6_7_CHANNEL_INSTANCE_NUM; adev->umc.umc_inst_num = UMC_V6_7_UMC_INSTANCE_NUM; @@ -1231,11 +1202,11 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev) static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(9, 4, 1): + switch (adev->asic_type) { + case CHIP_ARCTURUS: adev->mmhub.funcs = &mmhub_v9_4_funcs; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: adev->mmhub.funcs = &mmhub_v1_7_funcs; break; default: @@ -1246,14 +1217,14 @@ static void gmc_v9_0_set_mmhub_funcs(struct amdgpu_device *adev) static void gmc_v9_0_set_mmhub_ras_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(9, 4, 0): + switch (adev->asic_type) { + case CHIP_VEGA20: adev->mmhub.ras_funcs = &mmhub_v1_0_ras_funcs; break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: adev->mmhub.ras_funcs = &mmhub_v9_4_ras_funcs; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: adev->mmhub.ras_funcs = &mmhub_v1_7_ras_funcs; break; default: @@ -1274,9 +1245,8 @@ static void gmc_v9_0_set_hdp_ras_funcs(struct amdgpu_device *adev) static void gmc_v9_0_set_mca_funcs(struct amdgpu_device *adev) { - /* is UMC the right IP to check for MCA? Maybe DF? */ - switch (adev->ip_versions[UMC_HWIP][0]) { - case IP_VERSION(6, 7, 0): + switch (adev->asic_type) { + case CHIP_ALDEBARAN: if (!adev->gmc.xgmi.connected_to_cpu) adev->mca.funcs = &mca_v3_0_funcs; break; @@ -1289,12 +1259,11 @@ static int gmc_v9_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - /* ARCT and VEGA20 don't have XGMI defined in their IP discovery tables */ if (adev->asic_type == CHIP_VEGA20 || adev->asic_type == CHIP_ARCTURUS) adev->gmc.xgmi.supported = true; - if (adev->ip_versions[XGMI_HWIP][0] == IP_VERSION(6, 1, 0)) { + if (adev->asic_type == CHIP_ALDEBARAN) { adev->gmc.xgmi.supported = true; adev->gmc.xgmi.connected_to_cpu = adev->smuio.funcs->is_host_gpu_xgmi_supported(adev); @@ -1332,11 +1301,9 @@ static int gmc_v9_0_late_init(void *handle) * Workaround performance drop issue with VBIOS enables partial * writes, while disables HBM ECC for vega10. */ - if (!amdgpu_sriov_vf(adev) && - (adev->ip_versions[UMC_HWIP][0] == IP_VERSION(6, 0, 0))) { + if (!amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_VEGA10)) { if (!(adev->ras_enabled & (1 << AMDGPU_RAS_BLOCK__UMC))) { - if (adev->df.funcs && - adev->df.funcs->enable_ecc_force_par_wr_rmw) + if (adev->df.funcs->enable_ecc_force_par_wr_rmw) adev->df.funcs->enable_ecc_force_par_wr_rmw(adev, false); } } @@ -1438,18 +1405,17 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev) /* set the gart size */ if (amdgpu_gart_size == -1) { - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): /* all engines support GPUVM */ - case IP_VERSION(9, 2, 1): /* all engines support GPUVM */ - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - case IP_VERSION(9, 4, 2): + switch (adev->asic_type) { + case CHIP_VEGA10: /* all engines support GPUVM */ + case CHIP_VEGA12: /* all engines support GPUVM */ + case CHIP_VEGA20: + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: default: adev->gmc.gart_size = 512ULL << 20; break; - case IP_VERSION(9, 1, 0): /* DCE SG support */ - case IP_VERSION(9, 2, 2): /* DCE SG support */ - case IP_VERSION(9, 3, 0): + case CHIP_RAVEN: /* DCE SG support */ + case CHIP_RENOIR: adev->gmc.gart_size = 1024ULL << 20; break; } @@ -1510,8 +1476,7 @@ static int gmc_v9_0_gart_init(struct amdgpu_device *adev) */ static void gmc_v9_0_save_registers(struct amdgpu_device *adev) { - if ((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) || - (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) + if (adev->asic_type == CHIP_RAVEN) adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); } @@ -1547,18 +1512,15 @@ static int gmc_v9_0_sw_init(void *handle) chansize = 64; else chansize = 128; - if (adev->df.funcs && - adev->df.funcs->get_hbm_channel_number) { - numchan = adev->df.funcs->get_hbm_channel_number(adev); - adev->gmc.vram_width = numchan * chansize; - } + + numchan = adev->df.funcs->get_hbm_channel_number(adev); + adev->gmc.vram_width = numchan * chansize; } adev->gmc.vram_type = vram_type; adev->gmc.vram_vendor = vram_vendor; - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): + switch (adev->asic_type) { + case CHIP_RAVEN: adev->num_vmhubs = 2; if (adev->rev_id == 0x0 || adev->rev_id == 0x1) { @@ -1570,11 +1532,11 @@ static int gmc_v9_0_sw_init(void *handle) adev->vm_manager.num_level > 1; } break; - case IP_VERSION(9, 0, 1): - case IP_VERSION(9, 2, 1): - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 3, 0): - case IP_VERSION(9, 4, 2): + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RENOIR: + case CHIP_ALDEBARAN: adev->num_vmhubs = 2; @@ -1589,7 +1551,7 @@ static int gmc_v9_0_sw_init(void *handle) else amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48); break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: adev->num_vmhubs = 3; /* Keep the vm size same with Vega20 */ @@ -1605,7 +1567,7 @@ static int gmc_v9_0_sw_init(void *handle) if (r) return r; - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1)) { + if (adev->asic_type == CHIP_ARCTURUS) { r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC1, VMC_1_0__SRCID__VM_FAULT, &adev->gmc.vm_fault); if (r) @@ -1640,6 +1602,12 @@ static int gmc_v9_0_sw_init(void *handle) } adev->need_swiotlb = drm_need_swiotlb(44); + if (adev->gmc.xgmi.supported) { + r = adev->gfxhub.funcs->get_xgmi_info(adev); + if (r) + return r; + } + r = gmc_v9_0_mc_init(adev); if (r) return r; @@ -1666,8 +1634,8 @@ static int gmc_v9_0_sw_init(void *handle) * for video processing. */ adev->vm_manager.first_kfd_vmid = - (adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 1) || - adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 2)) ? 3 : 8; + (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) ? 3 : 8; amdgpu_vm_manager_init(adev); @@ -1693,12 +1661,12 @@ static int gmc_v9_0_sw_fini(void *handle) static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(9, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: if (amdgpu_sriov_vf(adev)) break; fallthrough; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: soc15_program_register_sequence(adev, golden_settings_mmhub_1_0_0, ARRAY_SIZE(golden_settings_mmhub_1_0_0)); @@ -1706,8 +1674,9 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_athub_1_0_0, ARRAY_SIZE(golden_settings_athub_1_0_0)); break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 0): + case CHIP_VEGA12: + break; + case CHIP_RAVEN: /* TODO for renoir */ soc15_program_register_sequence(adev, golden_settings_athub_1_0_0, @@ -1727,8 +1696,7 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) */ void gmc_v9_0_restore_registers(struct amdgpu_device *adev) { - if ((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) || - (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) { + if (adev->asic_type == CHIP_RAVEN) { WREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); WARN_ON(adev->gmc.sdpif_register != RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0)); @@ -1755,7 +1723,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) goto skip_pin_bo; - r = amdgpu_gtt_mgr_recover(&adev->mman.gtt_mgr); + r = amdgpu_gart_table_vram_pin(adev); if (r) return r; @@ -1784,7 +1752,7 @@ static int gmc_v9_0_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; bool value; - int i; + int r, i; /* The sequence of these two function calls matters.*/ gmc_v9_0_init_golden_registers(adev); @@ -1819,7 +1787,9 @@ static int gmc_v9_0_hw_init(void *handle) if (adev->umc.funcs && adev->umc.funcs->init_registers) adev->umc.funcs->init_registers(adev); - return gmc_v9_0_gart_enable(adev); + r = gmc_v9_0_gart_enable(adev); + + return r; } /** @@ -1833,6 +1803,7 @@ static void gmc_v9_0_gart_disable(struct amdgpu_device *adev) { adev->gfxhub.funcs->gart_disable(adev); adev->mmhub.funcs->gart_disable(adev); + amdgpu_gart_table_vram_unpin(adev); } static int gmc_v9_0_hw_fini(void *handle) @@ -1847,14 +1818,6 @@ static int gmc_v9_0_hw_fini(void *handle) return 0; } - /* - * Pair the operations did in gmc_v9_0_hw_init and thus maintain - * a correct cached state for GMC. Otherwise, the "gate" again - * operation on S3 resuming will fail due to wrong cached state. - */ - if (adev->mmhub.funcs->update_power_gating) - adev->mmhub.funcs->update_power_gating(adev, false); - amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c index eecfb1545c..74b90cc2bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c @@ -49,7 +49,7 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev, static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring) { - if (adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 4, 0)) + if (adev->asic_type == CHIP_ALDEBARAN) return; if (!ring || !ring->funcs->emit_wreg) @@ -79,7 +79,7 @@ static void hdp_v4_0_reset_ras_error_count(struct amdgpu_device *adev) if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__HDP)) return; - if (adev->ip_versions[HDP_HWIP][0] >= IP_VERSION(4, 4, 0)) + if (adev->asic_type >= CHIP_ALDEBARAN) WREG32_SOC15(HDP, 0, mmHDP_EDC_CNT, 0); else /*read back hdp ras counter to reset it to 0 */ @@ -91,10 +91,9 @@ static void hdp_v4_0_update_clock_gating(struct amdgpu_device *adev, { uint32_t def, data; - if (adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 0, 0) || - adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 0, 1) || - adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 1, 1) || - adev->ip_versions[HDP_HWIP][0] == IP_VERSION(4, 1, 0)) { + if (adev->asic_type == CHIP_VEGA10 || + adev->asic_type == CHIP_VEGA12 || + adev->asic_type == CHIP_RAVEN) { def = data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS)) @@ -136,8 +135,8 @@ static void hdp_v4_0_get_clockgating_state(struct amdgpu_device *adev, static void hdp_v4_0_init_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[HDP_HWIP][0]) { - case IP_VERSION(4, 2, 1): + switch (adev->asic_type) { + case CHIP_ARCTURUS: WREG32_FIELD15(HDP, 0, HDP_MMHUB_CNTL, HDP_MMHUB_GCC, 1); break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c index 299de1d131..85967a5570 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c @@ -32,6 +32,26 @@ #include "vcn/vcn_2_0_0_sh_mask.h" #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" +#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff +#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 +#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a +#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b +#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea +#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb +#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf +#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 +#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 +#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 +#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 +#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec +#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed +#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 +#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 +#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 +#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f + +#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000 + static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev); static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev); static int jpeg_v2_0_set_powergating_state(void *handle, diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h index 1a03baa597..15a344ed34 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h @@ -24,26 +24,6 @@ #ifndef __JPEG_V2_0_H__ #define __JPEG_V2_0_H__ -#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET 0x1bfff -#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 -#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a -#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b -#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea -#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40eb -#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf -#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 -#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40e8 -#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 -#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 -#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec -#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40ed -#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 -#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 -#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 -#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f - -#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000 - void jpeg_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring); void jpeg_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring); void jpeg_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c index a29c86617f..46096ad7f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c @@ -423,42 +423,6 @@ static void jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring) } } -/** - * jpeg_v2_6_dec_ring_insert_start - insert a start command - * - * @ring: amdgpu_ring pointer - * - * Write a start command to the ring. - */ -static void jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring *ring) -{ - amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, - 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */ - - amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, - 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x80000000 | (1 << (ring->me * 2 + 14))); -} - -/** - * jpeg_v2_6_dec_ring_insert_end - insert a end command - * - * @ring: amdgpu_ring pointer - * - * Write a end command to the ring. - */ -static void jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring *ring) -{ - amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET, - 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */ - - amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, - 0, 0, PACKETJ_TYPE0)); - amdgpu_ring_write(ring, (1 << (ring->me * 2 + 14))); -} - static bool jpeg_v2_5_is_idle(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -669,8 +633,8 @@ static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = { .test_ring = amdgpu_jpeg_dec_ring_test_ring, .test_ib = amdgpu_jpeg_dec_ring_test_ib, .insert_nop = jpeg_v2_0_dec_ring_nop, - .insert_start = jpeg_v2_6_dec_ring_insert_start, - .insert_end = jpeg_v2_6_dec_ring_insert_end, + .insert_start = jpeg_v2_0_dec_ring_insert_start, + .insert_end = jpeg_v2_0_dec_ring_insert_end, .pad_ib = amdgpu_ring_generic_pad_ib, .begin_use = amdgpu_jpeg_ring_begin_use, .end_use = amdgpu_jpeg_ring_end_use, diff --git a/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c index 8f7107d392..058b65730a 100644 --- a/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mca_v3_0.c @@ -52,8 +52,7 @@ const struct amdgpu_mca_ras_funcs mca_v3_0_mp0_ras_funcs = { .ras_fini = mca_v3_0_mp0_ras_fini, .query_ras_error_count = mca_v3_0_mp0_query_ras_error_count, .query_ras_error_address = NULL, - .ras_block = AMDGPU_RAS_BLOCK__MCA, - .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP0, + .ras_block = AMDGPU_RAS_BLOCK__MP0, .sysfs_name = "mp0_err_count", }; @@ -80,8 +79,7 @@ const struct amdgpu_mca_ras_funcs mca_v3_0_mp1_ras_funcs = { .ras_fini = mca_v3_0_mp1_ras_fini, .query_ras_error_count = mca_v3_0_mp1_query_ras_error_count, .query_ras_error_address = NULL, - .ras_block = AMDGPU_RAS_BLOCK__MCA, - .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MP1, + .ras_block = AMDGPU_RAS_BLOCK__MP1, .sysfs_name = "mp1_err_count", }; @@ -108,8 +106,7 @@ const struct amdgpu_mca_ras_funcs mca_v3_0_mpio_ras_funcs = { .ras_fini = mca_v3_0_mpio_ras_fini, .query_ras_error_count = mca_v3_0_mpio_query_ras_error_count, .query_ras_error_address = NULL, - .ras_block = AMDGPU_RAS_BLOCK__MCA, - .ras_sub_block = AMDGPU_RAS_MCA_BLOCK__MPIO, + .ras_block = AMDGPU_RAS_BLOCK__MPIO, .sysfs_name = "mpio_err_count", }; diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index 1da2ec6920..b3bede1dc4 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -301,10 +301,10 @@ static void mmhub_v1_0_update_power_gating(struct amdgpu_device *adev, if (amdgpu_sriov_vf(adev)) return; - if (adev->pg_flags & AMD_PG_SUPPORT_MMHUB) - amdgpu_dpm_set_powergating_by_smu(adev, - AMD_IP_BLOCK_TYPE_GMC, - enable); + if (enable && adev->pg_flags & AMD_PG_SUPPORT_MMHUB) { + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GMC, true); + + } } static int mmhub_v1_0_gart_enable(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c index 3718ff610a..2e58ed2caa 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c @@ -153,16 +153,18 @@ mmhub_v2_0_print_l2_protection_fault_status(struct amdgpu_device *adev, dev_err(adev->dev, "MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", status); - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 2): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: mmhub_cid = mmhub_client_ids_navi1x[cid][rw]; break; - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: mmhub_cid = mmhub_client_ids_sienna_cichlid[cid][rw]; break; - case IP_VERSION(2, 1, 2): + case CHIP_BEIGE_GOBY: mmhub_cid = mmhub_client_ids_beige_goby[cid][rw]; break; default: @@ -568,10 +570,11 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad if (!(adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) return; - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); break; @@ -602,10 +605,11 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); } - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: if (def != data) WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); if (def1 != data1) @@ -628,10 +632,11 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade if (!(adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) return; - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); break; default: @@ -645,10 +650,11 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK; if (def != data) { - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); break; default: @@ -664,12 +670,14 @@ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: mmhub_v2_0_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); mmhub_v2_0_update_medium_grain_light_sleep(adev, @@ -689,10 +697,11 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u32 *flags) if (amdgpu_sriov_vf(adev)) *flags = 0; - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 1, 0): - case IP_VERSION(2, 1, 1): - case IP_VERSION(2, 1, 2): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); break; diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c index 9e16da2850..c63b6b9349 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c @@ -90,9 +90,9 @@ mmhub_v2_3_print_l2_protection_fault_status(struct amdgpu_device *adev, dev_err(adev->dev, "MMVM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", status); - switch (adev->ip_versions[MMHUB_HWIP][0]) { - case IP_VERSION(2, 3, 0): - case IP_VERSION(2, 4, 0): + switch (adev->asic_type) { + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: mmhub_cid = mmhub_client_ids_vangogh[cid][rw]; break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 56da5ab829..23b066bcff 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c @@ -180,11 +180,6 @@ static int xgpu_ai_send_access_requests(struct amdgpu_device *adev, RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW2)); } - } else if (req == IDH_REQ_GPU_INIT_DATA){ - /* Dummy REQ_GPU_INIT_DATA handling */ - r = xgpu_ai_poll_msg(adev, IDH_REQ_GPU_INIT_DATA_READY); - /* version set to 0 since dummy */ - adev->virt.req_init_data_ver = 0; } return 0; @@ -257,12 +252,11 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work) * otherwise the mailbox msg will be ruined/reseted by * the VF FLR. */ - if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0) + if (!down_write_trylock(&adev->reset_sem)) return; - down_write(&adev->reset_sem); - amdgpu_virt_fini_data_exchange(adev); + atomic_set(&adev->in_gpu_reset, 1); xgpu_ai_mailbox_trans_msg(adev, IDH_READY_TO_RESET, 0, 0, 0); @@ -386,16 +380,10 @@ void xgpu_ai_mailbox_put_irq(struct amdgpu_device *adev) amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0); } -static int xgpu_ai_request_init_data(struct amdgpu_device *adev) -{ - return xgpu_ai_send_access_requests(adev, IDH_REQ_GPU_INIT_DATA); -} - const struct amdgpu_virt_ops xgpu_ai_virt_ops = { .req_full_gpu = xgpu_ai_request_full_gpu_access, .rel_full_gpu = xgpu_ai_release_full_gpu_access, .reset_gpu = xgpu_ai_request_reset, .wait_reset = NULL, .trans_msg = xgpu_ai_mailbox_trans_msg, - .req_init_data = xgpu_ai_request_init_data, }; diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h index fa7e13e045..bd3b231715 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h @@ -26,7 +26,7 @@ #define AI_MAILBOX_POLL_ACK_TIMEDOUT 500 #define AI_MAILBOX_POLL_MSG_TIMEDOUT 6000 -#define AI_MAILBOX_POLL_FLR_TIMEDOUT 10000 +#define AI_MAILBOX_POLL_FLR_TIMEDOUT 5000 #define AI_MAILBOX_POLL_MSG_REP_MAX 11 enum idh_request { @@ -35,7 +35,6 @@ enum idh_request { IDH_REQ_GPU_FINI_ACCESS, IDH_REL_GPU_FINI_ACCESS, IDH_REQ_GPU_RESET_ACCESS, - IDH_REQ_GPU_INIT_DATA, IDH_LOG_VF_ERROR = 200, IDH_READY_TO_RESET = 201, @@ -49,7 +48,6 @@ enum idh_event { IDH_SUCCESS, IDH_FAIL, IDH_QUERY_ALIVE, - IDH_REQ_GPU_INIT_DATA_READY, IDH_TEXT_MESSAGE = 255, }; diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c index 477d0dde19..a35e6d87e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c @@ -281,12 +281,11 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work) * otherwise the mailbox msg will be ruined/reseted by * the VF FLR. */ - if (atomic_cmpxchg(&adev->in_gpu_reset, 0, 1) != 0) + if (!down_write_trylock(&adev->reset_sem)) return; - down_write(&adev->reset_sem); - amdgpu_virt_fini_data_exchange(adev); + atomic_set(&adev->in_gpu_reset, 1); xgpu_nv_mailbox_trans_msg(adev, IDH_READY_TO_RESET, 0, 0, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c index 8ce5b8ca1f..5300116228 100644 --- a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c @@ -107,7 +107,7 @@ force_update_wptr_for_self_int(struct amdgpu_device *adev, { u32 ih_cntl, ih_rb_cntl; - if (adev->ip_versions[OSSSYS_HWIP][0] < IP_VERSION(5, 0, 3)) + if (adev->asic_type < CHIP_SIENNA_CICHLID) return; ih_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_CNTL2); @@ -160,7 +160,6 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev, tmp = RREG32(ih_regs->ih_rb_cntl); tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0)); - tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1); /* enable_intr field is only valid in ring0 */ if (ih == &adev->irq.ih) tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0)); @@ -276,8 +275,10 @@ static int navi10_ih_enable_ring(struct amdgpu_device *adev, tmp = navi10_ih_rb_cntl(ih, tmp); if (ih == &adev->irq.ih) tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled); - if (ih == &adev->irq.ih1) + if (ih == &adev->irq.ih1) { + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 0); tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1); + } if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) { @@ -318,6 +319,7 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) { struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2}; u32 ih_chicken; + u32 tmp; int ret; int i; @@ -330,10 +332,13 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) if (unlikely(adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT)) { if (ih[0]->use_bus_addr) { - switch (adev->ip_versions[OSSSYS_HWIP][0]) { - case IP_VERSION(5, 0, 3): - case IP_VERSION(5, 2, 0): - case IP_VERSION(5, 2, 1): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid); ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1); @@ -361,6 +366,15 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev) adev->nbio.funcs->ih_doorbell_range(adev, ih[0]->use_doorbell, ih[0]->doorbell_index); + tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL); + tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL, + CLIENT18_IS_STORM_CLIENT, 1); + WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp); + + tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL); + tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1); + WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp); + pci_set_master(adev->pdev); /* enable interrupts */ @@ -409,19 +423,12 @@ static u32 navi10_ih_get_wptr(struct amdgpu_device *adev, u32 wptr, tmp; struct amdgpu_ih_regs *ih_regs; - if (ih == &adev->irq.ih) { - /* Only ring0 supports writeback. On other rings fall back - * to register-based code with overflow checking below. - */ - wptr = le32_to_cpu(*ih->wptr_cpu); - - if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) - goto out; - } - + wptr = le32_to_cpu(*ih->wptr_cpu); ih_regs = &ih->ih_regs; - /* Double check that the overflow wasn't already cleared. */ + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr); if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) goto out; @@ -509,11 +516,15 @@ static int navi10_ih_self_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { + uint32_t wptr = cpu_to_le32(entry->src_data[0]); + switch (entry->ring_id) { case 1: + *adev->irq.ih1.wptr_cpu = wptr; schedule_work(&adev->irq.ih1_work); break; case 2: + *adev->irq.ih2.wptr_cpu = wptr; schedule_work(&adev->irq.ih2_work); break; default: break; @@ -716,7 +727,6 @@ static const struct amd_ip_funcs navi10_ih_ip_funcs = { static const struct amdgpu_ih_funcs navi10_ih_funcs = { .get_wptr = navi10_ih_get_wptr, .decode_iv = amdgpu_ih_decode_iv_helper, - .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper, .set_rptr = navi10_ih_set_rptr }; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c index ee7cab37df..b184b656b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c @@ -53,16 +53,6 @@ #define smnPCIE_LC_LINK_WIDTH_CNTL 0x11140288 -#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L /* Don't use. Firmware uses this bit internally */ -#define GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK 0x00002000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK 0x00004000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK 0x00008000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK 0x00010000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK 0x00020000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK 0x00040000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK 0x00080000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK 0x00100000L - static void nbio_v2_3_remap_hdp_registers(struct amdgpu_device *adev) { WREG32_SOC15(NBIO, 0, mmREMAP_HDP_MEM_FLUSH_CNTL, @@ -328,27 +318,6 @@ const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg = { .ref_and_mask_sdma1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__SDMA1_MASK, }; -const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc = { - .ref_and_mask_cp0 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP0_MASK, - .ref_and_mask_cp1 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP1_MASK, - .ref_and_mask_cp2 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP2_MASK, - .ref_and_mask_cp3 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP3_MASK, - .ref_and_mask_cp4 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP4_MASK, - .ref_and_mask_cp5 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP5_MASK, - .ref_and_mask_cp6 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP6_MASK, - .ref_and_mask_cp7 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP7_MASK, - .ref_and_mask_cp8 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP8_MASK, - .ref_and_mask_cp9 = BIF_BX_PF_GPU_HDP_FLUSH_DONE__CP9_MASK, - .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK, - .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK, - .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK, - .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK, - .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK, - .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK, - .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK, - .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK, -}; - static void nbio_v2_3_init_registers(struct amdgpu_device *adev) { uint32_t def, data; @@ -359,10 +328,6 @@ static void nbio_v2_3_init_registers(struct amdgpu_device *adev) if (def != data) WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); - - if (amdgpu_sriov_vf(adev)) - adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, - mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; } #define NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT 0x00000000 // off by default, no gains over L1 diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h index 6074dd3a1e..a43b60acf7 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.h @@ -27,7 +27,6 @@ #include "soc15_common.h" extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg; -extern const struct nbio_hdp_flush_reg nbio_v2_3_hdp_flush_reg_sc; extern const struct amdgpu_nbio_funcs nbio_v2_3_funcs; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c index 4bbacf1be2..0d2d629e2d 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c @@ -276,10 +276,6 @@ static void nbio_v6_1_init_registers(struct amdgpu_device *adev) if (def != data) WREG32_PCIE(smnPCIE_CI_CNTL, data); - - if (amdgpu_sriov_vf(adev)) - adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, - mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; } static void nbio_v6_1_program_ltr(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c index 37a4039fdf..3c00666a13 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c @@ -273,9 +273,7 @@ const struct nbio_hdp_flush_reg nbio_v7_0_hdp_flush_reg = { static void nbio_v7_0_init_registers(struct amdgpu_device *adev) { - if (amdgpu_sriov_vf(adev)) - adev->rmmio_remap.reg_offset = - SOC15_REG_OFFSET(NBIO, 0, mmHDP_MEM_COHERENCY_FLUSH_CNTL) << 2; + } const struct amdgpu_nbio_funcs nbio_v7_0_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c index 3444332ea1..8f2a315e7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c @@ -371,10 +371,6 @@ static void nbio_v7_2_init_registers(struct amdgpu_device *adev) if (def != data) WREG32_PCIE_PORT(SOC15_REG_OFFSET(NBIO, 0, regPCIE_CONFIG_CNTL), data); } - - if (amdgpu_sriov_vf(adev)) - adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, - regBIF_BX_PF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; } const struct amdgpu_nbio_funcs nbio_v7_2_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c index dc5e93756f..f50045cebd 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c @@ -56,15 +56,12 @@ * These are nbio v7_4_1 registers mask. Temporarily define these here since * nbio v7_4_1 header is incomplete. */ -#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L /* Don't use. Firmware uses this bit internally */ +#define GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK 0x00001000L #define GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK 0x00002000L #define GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK 0x00004000L #define GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK 0x00008000L #define GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK 0x00010000L #define GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK 0x00020000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK 0x00040000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK 0x00080000L -#define GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK 0x00100000L #define mmBIF_MMSCH1_DOORBELL_RANGE 0x01dc #define mmBIF_MMSCH1_DOORBELL_RANGE_BASE_IDX 2 @@ -337,34 +334,17 @@ const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg = { .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK, .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__SDMA0_MASK, .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__SDMA1_MASK, -}; - -const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald = { - .ref_and_mask_cp0 = GPU_HDP_FLUSH_DONE__CP0_MASK, - .ref_and_mask_cp1 = GPU_HDP_FLUSH_DONE__CP1_MASK, - .ref_and_mask_cp2 = GPU_HDP_FLUSH_DONE__CP2_MASK, - .ref_and_mask_cp3 = GPU_HDP_FLUSH_DONE__CP3_MASK, - .ref_and_mask_cp4 = GPU_HDP_FLUSH_DONE__CP4_MASK, - .ref_and_mask_cp5 = GPU_HDP_FLUSH_DONE__CP5_MASK, - .ref_and_mask_cp6 = GPU_HDP_FLUSH_DONE__CP6_MASK, - .ref_and_mask_cp7 = GPU_HDP_FLUSH_DONE__CP7_MASK, - .ref_and_mask_cp8 = GPU_HDP_FLUSH_DONE__CP8_MASK, - .ref_and_mask_cp9 = GPU_HDP_FLUSH_DONE__CP9_MASK, - .ref_and_mask_sdma0 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK, - .ref_and_mask_sdma1 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK, - .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK, - .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK, - .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK, - .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG6_MASK, - .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG7_MASK, - .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG8_MASK, + .ref_and_mask_sdma2 = GPU_HDP_FLUSH_DONE__RSVD_ENG0_MASK, + .ref_and_mask_sdma3 = GPU_HDP_FLUSH_DONE__RSVD_ENG1_MASK, + .ref_and_mask_sdma4 = GPU_HDP_FLUSH_DONE__RSVD_ENG2_MASK, + .ref_and_mask_sdma5 = GPU_HDP_FLUSH_DONE__RSVD_ENG3_MASK, + .ref_and_mask_sdma6 = GPU_HDP_FLUSH_DONE__RSVD_ENG4_MASK, + .ref_and_mask_sdma7 = GPU_HDP_FLUSH_DONE__RSVD_ENG5_MASK, }; static void nbio_v7_4_init_registers(struct amdgpu_device *adev) { - if (amdgpu_sriov_vf(adev)) - adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, - mmBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; + } static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device *adev) @@ -407,13 +387,13 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device "errors detected in %s block, " "no user action is needed.\n", obj->err_data.ce_count, - get_ras_block_str(adev->nbio.ras_if)); + ras_block_str(adev->nbio.ras_if->block)); if (err_data.ue_count) dev_info(adev->dev, "%ld uncorrectable hardware " "errors detected in %s block\n", obj->err_data.ue_count, - get_ras_block_str(adev->nbio.ras_if)); + ras_block_str(adev->nbio.ras_if->block)); } dev_info(adev->dev, "RAS controller interrupt triggered " @@ -586,9 +566,7 @@ static int nbio_v7_4_init_ras_err_event_athub_interrupt (struct amdgpu_device *a return r; } -#define smnPARITY_ERROR_STATUS_UNCORR_GRP2 0x13a20030 -#define smnPARITY_ERROR_STATUS_UNCORR_GRP2_ALDE 0x13b20030 -#define smnRAS_GLOBAL_STATUS_LO_ALDE 0x13b20020 +#define smnPARITY_ERROR_STATUS_UNCORR_GRP2 0x13a20030 static void nbio_v7_4_query_ras_error_count(struct amdgpu_device *adev, void *ras_error_status) @@ -597,20 +575,12 @@ static void nbio_v7_4_query_ras_error_count(struct amdgpu_device *adev, uint32_t corr, fatal, non_fatal; struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; - if (adev->asic_type == CHIP_ALDEBARAN) - global_sts = RREG32_PCIE(smnRAS_GLOBAL_STATUS_LO_ALDE); - else - global_sts = RREG32_PCIE(smnRAS_GLOBAL_STATUS_LO); - + global_sts = RREG32_PCIE(smnRAS_GLOBAL_STATUS_LO); corr = REG_GET_FIELD(global_sts, RAS_GLOBAL_STATUS_LO, ParityErrCorr); fatal = REG_GET_FIELD(global_sts, RAS_GLOBAL_STATUS_LO, ParityErrFatal); non_fatal = REG_GET_FIELD(global_sts, RAS_GLOBAL_STATUS_LO, ParityErrNonFatal); - - if (adev->asic_type == CHIP_ALDEBARAN) - parity_sts = RREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2_ALDE); - else - parity_sts = RREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2); + parity_sts = RREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2); if (corr) err_data->ce_count++; @@ -619,21 +589,13 @@ static void nbio_v7_4_query_ras_error_count(struct amdgpu_device *adev, if (corr || fatal || non_fatal) { central_sts = RREG32_PCIE(smnBIFL_RAS_CENTRAL_STATUS); - /* clear error status register */ - if (adev->asic_type == CHIP_ALDEBARAN) - WREG32_PCIE(smnRAS_GLOBAL_STATUS_LO_ALDE, global_sts); - else - WREG32_PCIE(smnRAS_GLOBAL_STATUS_LO, global_sts); + WREG32_PCIE(smnRAS_GLOBAL_STATUS_LO, global_sts); if (fatal) - { /* clear parity fatal error indication field */ - if (adev->asic_type == CHIP_ALDEBARAN) - WREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2_ALDE, parity_sts); - else - WREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2, parity_sts); - } + WREG32_PCIE(smnPARITY_ERROR_STATUS_UNCORR_GRP2, + parity_sts); if (REG_GET_FIELD(central_sts, BIFL_RAS_CENTRAL_STATUS, BIFL_RasContller_Intr_Recv)) { @@ -694,9 +656,6 @@ static void nbio_v7_4_program_aspm(struct amdgpu_device *adev) { uint32_t def, data; - if (adev->ip_versions[NBIO_HWIP][0] == IP_VERSION(7, 4, 4)) - return; - def = data = RREG32_PCIE(smnPCIE_LC_CNTL); data &= ~PCIE_LC_CNTL__LC_L1_INACTIVITY_MASK; data &= ~PCIE_LC_CNTL__LC_L0S_INACTIVITY_MASK; diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h index cc5692db6f..b8216581ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.h @@ -27,7 +27,6 @@ #include "soc15_common.h" extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg; -extern const struct nbio_hdp_flush_reg nbio_v7_4_hdp_flush_reg_ald; extern const struct amdgpu_nbio_funcs nbio_v7_4_funcs; extern const struct amdgpu_nbio_ras_funcs nbio_v7_4_ras_funcs; diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index 2ec1ffb36b..01efda4398 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -180,10 +180,8 @@ static const struct amdgpu_video_codecs yc_video_codecs_decode = { static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, const struct amdgpu_video_codecs **codecs) { - switch (adev->ip_versions[UVD_HWIP][0]) { - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 64): - case IP_VERSION(3, 0, 192): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: if (amdgpu_sriov_vf(adev)) { if (encode) *codecs = &sriov_sc_video_codecs_encode; @@ -196,27 +194,29 @@ static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode, *codecs = &sc_video_codecs_decode; } return 0; - case IP_VERSION(3, 0, 16): - case IP_VERSION(3, 0, 2): + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_VANGOGH: if (encode) *codecs = &nv_video_codecs_encode; else *codecs = &sc_video_codecs_decode; return 0; - case IP_VERSION(3, 1, 1): + case CHIP_YELLOW_CARP: if (encode) *codecs = &nv_video_codecs_encode; else *codecs = &yc_video_codecs_decode; return 0; - case IP_VERSION(3, 0, 33): + case CHIP_BEIGE_GOBY: if (encode) *codecs = &bg_video_codecs_encode; else *codecs = &bg_video_codecs_decode; return 0; - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 0, 2): + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: if (encode) *codecs = &nv_video_codecs_encode; else @@ -511,15 +511,14 @@ nv_asic_reset_method(struct amdgpu_device *adev) dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", amdgpu_reset_method); - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 5, 0): - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + switch (adev->asic_type) { + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: return AMD_RESET_METHOD_MODE2; - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: return AMD_RESET_METHOD_MODE1; default: if (amdgpu_dpm_is_baco_supported(adev)) @@ -600,7 +599,7 @@ static void nv_enable_doorbell_aperture(struct amdgpu_device *adev, adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); } -const struct amdgpu_ip_block_version nv_common_ip_block = +static const struct amdgpu_ip_block_version nv_common_ip_block = { .type = AMD_IP_BLOCK_TYPE_COMMON, .major = 1, @@ -609,11 +608,314 @@ const struct amdgpu_ip_block_version nv_common_ip_block = .funcs = &nv_common_ip_funcs, }; +static bool nv_is_headless_sku(struct pci_dev *pdev) +{ + if ((pdev->device == 0x731E && + (pdev->revision == 0xC6 || pdev->revision == 0xC7)) || + (pdev->device == 0x7340 && pdev->revision == 0xC9) || + (pdev->device == 0x7360 && pdev->revision == 0xC7)) + return true; + return false; +} + +static int nv_reg_base_init(struct amdgpu_device *adev) +{ + int r; + + if (amdgpu_discovery) { + r = amdgpu_discovery_reg_base_init(adev); + if (r) { + DRM_WARN("failed to init reg base from ip discovery table, " + "fallback to legacy init method\n"); + goto legacy_init; + } + + amdgpu_discovery_harvest_ip(adev); + if (nv_is_headless_sku(adev->pdev)) { + adev->harvest_ip_mask |= AMD_HARVEST_IP_VCN_MASK; + adev->harvest_ip_mask |= AMD_HARVEST_IP_JPEG_MASK; + } + + return 0; + } + +legacy_init: + switch (adev->asic_type) { + case CHIP_NAVI10: + navi10_reg_base_init(adev); + break; + case CHIP_NAVI14: + navi14_reg_base_init(adev); + break; + case CHIP_NAVI12: + navi12_reg_base_init(adev); + break; + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + sienna_cichlid_reg_base_init(adev); + break; + case CHIP_VANGOGH: + vangogh_reg_base_init(adev); + break; + case CHIP_DIMGREY_CAVEFISH: + dimgrey_cavefish_reg_base_init(adev); + break; + case CHIP_BEIGE_GOBY: + beige_goby_reg_base_init(adev); + break; + case CHIP_YELLOW_CARP: + yellow_carp_reg_base_init(adev); + break; + case CHIP_CYAN_SKILLFISH: + cyan_skillfish_reg_base_init(adev); + break; + default: + return -EINVAL; + } + + return 0; +} + void nv_set_virt_ops(struct amdgpu_device *adev) { adev->virt.ops = &xgpu_nv_virt_ops; } +int nv_set_ip_blocks(struct amdgpu_device *adev) +{ + int r; + + if (adev->asic_type == CHIP_CYAN_SKILLFISH) { + adev->nbio.funcs = &nbio_v2_3_funcs; + adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; + } else if (adev->flags & AMD_IS_APU) { + adev->nbio.funcs = &nbio_v7_2_funcs; + adev->nbio.hdp_flush_reg = &nbio_v7_2_hdp_flush_reg; + } else { + adev->nbio.funcs = &nbio_v2_3_funcs; + adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; + } + adev->hdp.funcs = &hdp_v5_0_funcs; + + if (adev->asic_type >= CHIP_SIENNA_CICHLID) + adev->smuio.funcs = &smuio_v11_0_6_funcs; + else + adev->smuio.funcs = &smuio_v11_0_funcs; + + if (adev->asic_type == CHIP_SIENNA_CICHLID) + adev->gmc.xgmi.supported = true; + + /* Set IP register base before any HW register access */ + r = nv_reg_base_init(adev); + if (r) + return r; + + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && + !amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && + !amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); + if (adev->enable_mes) + amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); + break; + case CHIP_NAVI12: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + if (!amdgpu_sriov_vf(adev)) { + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + } else { + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + } + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && + !amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); + if (!amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); + break; + case CHIP_SIENNA_CICHLID: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + if (!amdgpu_sriov_vf(adev)) { + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + } else { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + } + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + if (!amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); + if (adev->enable_mes) + amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); + break; + case CHIP_NAVY_FLOUNDER: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + break; + case CHIP_VANGOGH: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); + break; + case CHIP_DIMGREY_CAVEFISH: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); + break; + case CHIP_BEIGE_GOBY: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && + is_support_sw_smu(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + break; + case CHIP_YELLOW_CARP: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); + amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); + break; + case CHIP_CYAN_SKILLFISH: + amdgpu_device_ip_block_add(adev, &nv_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); + if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_8_ip_block); + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + } + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); + break; + default: + return -EINVAL; + } + + return 0; +} + static uint32_t nv_get_rev_id(struct amdgpu_device *adev) { return adev->nbio.funcs->get_rev_id(adev); @@ -732,10 +1034,8 @@ static int nv_common_early_init(void *handle) #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (!amdgpu_sriov_vf(adev)) { - adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; - adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; - } + adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; + adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; adev->smc_rreg = NULL; adev->smc_wreg = NULL; adev->pcie_rreg = &nv_pcie_rreg; @@ -756,11 +1056,8 @@ static int nv_common_early_init(void *handle) adev->rev_id = nv_get_rev_id(adev); adev->external_rev_id = 0xff; - /* TODO: split the GC and PG flags based on the relevant IP version for which - * they are relevant. - */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(10, 1, 10): + switch (adev->asic_type) { + case CHIP_NAVI10: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_IH_CG | @@ -782,7 +1079,7 @@ static int nv_common_early_init(void *handle) AMD_PG_SUPPORT_ATHUB; adev->external_rev_id = adev->rev_id + 0x1; break; - case IP_VERSION(10, 1, 1): + case CHIP_NAVI14: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_IH_CG | @@ -803,7 +1100,7 @@ static int nv_common_early_init(void *handle) AMD_PG_SUPPORT_VCN_DPG; adev->external_rev_id = adev->rev_id + 20; break; - case IP_VERSION(10, 1, 2): + case CHIP_NAVI12: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | @@ -832,7 +1129,7 @@ static int nv_common_early_init(void *handle) adev->rev_id = 0; adev->external_rev_id = adev->rev_id + 0xa; break; - case IP_VERSION(10, 3, 0): + case CHIP_SIENNA_CICHLID: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | @@ -856,7 +1153,7 @@ static int nv_common_early_init(void *handle) } adev->external_rev_id = adev->rev_id + 0x28; break; - case IP_VERSION(10, 3, 2): + case CHIP_NAVY_FLOUNDER: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | @@ -875,7 +1172,8 @@ static int nv_common_early_init(void *handle) AMD_PG_SUPPORT_MMHUB; adev->external_rev_id = adev->rev_id + 0x32; break; - case IP_VERSION(10, 3, 1): + + case CHIP_VANGOGH: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | @@ -898,7 +1196,7 @@ static int nv_common_early_init(void *handle) if (adev->apu_flags & AMD_APU_IS_VANGOGH) adev->external_rev_id = adev->rev_id + 0x01; break; - case IP_VERSION(10, 3, 4): + case CHIP_DIMGREY_CAVEFISH: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | @@ -917,7 +1215,7 @@ static int nv_common_early_init(void *handle) AMD_PG_SUPPORT_MMHUB; adev->external_rev_id = adev->rev_id + 0x3c; break; - case IP_VERSION(10, 3, 5): + case CHIP_BEIGE_GOBY: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | @@ -934,7 +1232,7 @@ static int nv_common_early_init(void *handle) AMD_PG_SUPPORT_MMHUB; adev->external_rev_id = adev->rev_id + 0x46; break; - case IP_VERSION(10, 3, 3): + case CHIP_YELLOW_CARP: adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CGCG | @@ -963,7 +1261,7 @@ static int nv_common_early_init(void *handle) else adev->external_rev_id = adev->rev_id + 0x01; break; - case IP_VERSION(10, 1, 3): + case CHIP_CYAN_SKILLFISH: adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x82; @@ -1035,7 +1333,7 @@ static int nv_common_hw_init(void *handle) * for the purpose of expose those registers * to process space */ - if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) + if (adev->nbio.funcs->remap_hdp_registers) adev->nbio.funcs->remap_hdp_registers(adev); /* enable the doorbell aperture */ nv_enable_doorbell_aperture(adev, true); @@ -1090,14 +1388,14 @@ static int nv_common_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[NBIO_HWIP][0]) { - case IP_VERSION(2, 3, 0): - case IP_VERSION(2, 3, 1): - case IP_VERSION(2, 3, 2): - case IP_VERSION(3, 3, 0): - case IP_VERSION(3, 3, 1): - case IP_VERSION(3, 3, 2): - case IP_VERSION(3, 3, 3): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: adev->nbio.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->nbio.funcs->update_medium_grain_light_sleep(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/nv.h b/drivers/gpu/drm/amd/amdgpu/nv.h index 83e9782aef..1f40ba3b04 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.h +++ b/drivers/gpu/drm/amd/amdgpu/nv.h @@ -26,10 +26,18 @@ #include "nbio_v2_3.h" -extern const struct amdgpu_ip_block_version nv_common_ip_block; - void nv_grbm_select(struct amdgpu_device *adev, u32 me, u32 pipe, u32 queue, u32 vmid); void nv_set_virt_ops(struct amdgpu_device *adev); +int nv_set_ip_blocks(struct amdgpu_device *adev); +int navi10_reg_base_init(struct amdgpu_device *adev); +int navi14_reg_base_init(struct amdgpu_device *adev); +int navi12_reg_base_init(struct amdgpu_device *adev); +int sienna_cichlid_reg_base_init(struct amdgpu_device *adev); +void vangogh_reg_base_init(struct amdgpu_device *adev); +int dimgrey_cavefish_reg_base_init(struct amdgpu_device *adev); +int beige_goby_reg_base_init(struct amdgpu_device *adev); +int yellow_carp_reg_base_init(struct amdgpu_device *adev); +int cyan_skillfish_reg_base_init(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c index ed2293686f..5872d68ed1 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c @@ -84,28 +84,28 @@ static int psp_v10_0_init_microcode(struct psp_context *psp) ta_hdr = (const struct ta_firmware_header_v1_0 *) adev->psp.ta_fw->data; - adev->psp.hdcp_context.context.bin_desc.fw_version = + adev->psp.hdcp.feature_version = le32_to_cpu(ta_hdr->hdcp.fw_version); - adev->psp.hdcp_context.context.bin_desc.size_bytes = + adev->psp.hdcp.size_bytes = le32_to_cpu(ta_hdr->hdcp.size_bytes); - adev->psp.hdcp_context.context.bin_desc.start_addr = + adev->psp.hdcp.start_addr = (uint8_t *)ta_hdr + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); - adev->psp.dtm_context.context.bin_desc.fw_version = + adev->psp.dtm.feature_version = le32_to_cpu(ta_hdr->dtm.fw_version); - adev->psp.dtm_context.context.bin_desc.size_bytes = + adev->psp.dtm.size_bytes = le32_to_cpu(ta_hdr->dtm.size_bytes); - adev->psp.dtm_context.context.bin_desc.start_addr = - (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + + adev->psp.dtm.start_addr = + (uint8_t *)adev->psp.hdcp.start_addr + le32_to_cpu(ta_hdr->dtm.offset_bytes); - adev->psp.securedisplay_context.context.bin_desc.fw_version = + adev->psp.securedisplay.feature_version = le32_to_cpu(ta_hdr->securedisplay.fw_version); - adev->psp.securedisplay_context.context.bin_desc.size_bytes = + adev->psp.securedisplay.size_bytes = le32_to_cpu(ta_hdr->securedisplay.size_bytes); - adev->psp.securedisplay_context.context.bin_desc.start_addr = - (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + + adev->psp.securedisplay.start_addr = + (uint8_t *)adev->psp.hdcp.start_addr + le32_to_cpu(ta_hdr->securedisplay.offset_bytes); adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index d0e76b36d4..29bf9f0994 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -93,35 +93,35 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) DRM_DEBUG("\n"); - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(11, 0, 2): + switch (adev->asic_type) { + case CHIP_VEGA20: chip_name = "vega20"; break; - case IP_VERSION(11, 0, 0): + case CHIP_NAVI10: chip_name = "navi10"; break; - case IP_VERSION(11, 0, 5): + case CHIP_NAVI14: chip_name = "navi14"; break; - case IP_VERSION(11, 0, 9): + case CHIP_NAVI12: chip_name = "navi12"; break; - case IP_VERSION(11, 0, 4): + case CHIP_ARCTURUS: chip_name = "arcturus"; break; - case IP_VERSION(11, 0, 7): + case CHIP_SIENNA_CICHLID: chip_name = "sienna_cichlid"; break; - case IP_VERSION(11, 0, 11): + case CHIP_NAVY_FLOUNDER: chip_name = "navy_flounder"; break; - case IP_VERSION(11, 5, 0): + case CHIP_VANGOGH: chip_name = "vangogh"; break; - case IP_VERSION(11, 0, 12): + case CHIP_DIMGREY_CAVEFISH: chip_name = "dimgrey_cavefish"; break; - case IP_VERSION(11, 0, 13): + case CHIP_BEIGE_GOBY: chip_name = "beige_goby"; break; default: @@ -129,9 +129,9 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) } - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(11, 0, 2): - case IP_VERSION(11, 0, 4): + switch (adev->asic_type) { + case CHIP_VEGA20: + case CHIP_ARCTURUS: err = psp_init_sos_microcode(psp, chip_name); if (err) return err; @@ -151,26 +151,20 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) goto out2; ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; - adev->psp.xgmi_context.context.bin_desc.fw_version = - le32_to_cpu(ta_hdr->xgmi.fw_version); - adev->psp.xgmi_context.context.bin_desc.size_bytes = - le32_to_cpu(ta_hdr->xgmi.size_bytes); - adev->psp.xgmi_context.context.bin_desc.start_addr = - (uint8_t *)ta_hdr + + adev->psp.xgmi.feature_version = le32_to_cpu(ta_hdr->xgmi.fw_version); + adev->psp.xgmi.size_bytes = le32_to_cpu(ta_hdr->xgmi.size_bytes); + adev->psp.xgmi.start_addr = (uint8_t *)ta_hdr + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); - adev->psp.ras_context.context.bin_desc.fw_version = - le32_to_cpu(ta_hdr->ras.fw_version); - adev->psp.ras_context.context.bin_desc.size_bytes = - le32_to_cpu(ta_hdr->ras.size_bytes); - adev->psp.ras_context.context.bin_desc.start_addr = - (uint8_t *)adev->psp.xgmi_context.context.bin_desc.start_addr + + adev->psp.ras.feature_version = le32_to_cpu(ta_hdr->ras.fw_version); + adev->psp.ras.size_bytes = le32_to_cpu(ta_hdr->ras.size_bytes); + adev->psp.ras.start_addr = (uint8_t *)adev->psp.xgmi.start_addr + le32_to_cpu(ta_hdr->ras.offset_bytes); } break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: err = psp_init_sos_microcode(psp, chip_name); if (err) return err; @@ -192,31 +186,22 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) goto out2; ta_hdr = (const struct ta_firmware_header_v1_0 *)adev->psp.ta_fw->data; - adev->psp.hdcp_context.context.bin_desc.fw_version = - le32_to_cpu(ta_hdr->hdcp.fw_version); - adev->psp.hdcp_context.context.bin_desc.size_bytes = - le32_to_cpu(ta_hdr->hdcp.size_bytes); - adev->psp.hdcp_context.context.bin_desc.start_addr = - (uint8_t *)ta_hdr + - le32_to_cpu( - ta_hdr->header.ucode_array_offset_bytes); + adev->psp.hdcp.feature_version = le32_to_cpu(ta_hdr->hdcp.fw_version); + adev->psp.hdcp.size_bytes = le32_to_cpu(ta_hdr->hdcp.size_bytes); + adev->psp.hdcp.start_addr = (uint8_t *)ta_hdr + + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); - adev->psp.dtm_context.context.bin_desc.fw_version = - le32_to_cpu(ta_hdr->dtm.fw_version); - adev->psp.dtm_context.context.bin_desc.size_bytes = - le32_to_cpu(ta_hdr->dtm.size_bytes); - adev->psp.dtm_context.context.bin_desc.start_addr = - (uint8_t *)adev->psp.hdcp_context.context - .bin_desc.start_addr + + adev->psp.dtm.feature_version = le32_to_cpu(ta_hdr->dtm.fw_version); + adev->psp.dtm.size_bytes = le32_to_cpu(ta_hdr->dtm.size_bytes); + adev->psp.dtm.start_addr = (uint8_t *)adev->psp.hdcp.start_addr + le32_to_cpu(ta_hdr->dtm.offset_bytes); } break; - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: err = psp_init_sos_microcode(psp, chip_name); if (err) return err; @@ -224,7 +209,15 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) if (err) return err; break; - case IP_VERSION(11, 5, 0): + case CHIP_BEIGE_GOBY: + err = psp_init_sos_microcode(psp, chip_name); + if (err) + return err; + err = psp_init_ta_microcode(psp, chip_name); + if (err) + return err; + break; + case CHIP_VANGOGH: err = psp_init_asd_microcode(psp, chip_name); if (err) return err; @@ -277,9 +270,69 @@ static bool psp_v11_0_is_sos_alive(struct psp_context *psp) return sol_reg != 0x0; } -static int psp_v11_0_bootloader_load_component(struct psp_context *psp, - struct psp_bin_desc *bin_desc, - enum psp_bootloader_cmd bl_cmd) +static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) +{ + int ret; + uint32_t psp_gfxdrv_command_reg = 0; + struct amdgpu_device *adev = psp->adev; + + /* Check tOS sign of life register to confirm sys driver and sOS + * are already been loaded. + */ + if (psp_v11_0_is_sos_alive(psp)) + return 0; + + ret = psp_v11_0_wait_for_bootloader(psp); + if (ret) + return ret; + + /* Copy PSP KDB binary to memory */ + psp_copy_fw(psp, psp->kdb.start_addr, psp->kdb.size_bytes); + + /* Provide the PSP KDB to bootloader */ + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, + (uint32_t)(psp->fw_pri_mc_addr >> 20)); + psp_gfxdrv_command_reg = PSP_BL__LOAD_KEY_DATABASE; + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, + psp_gfxdrv_command_reg); + + ret = psp_v11_0_wait_for_bootloader(psp); + + return ret; +} + +static int psp_v11_0_bootloader_load_spl(struct psp_context *psp) +{ + int ret; + uint32_t psp_gfxdrv_command_reg = 0; + struct amdgpu_device *adev = psp->adev; + + /* Check tOS sign of life register to confirm sys driver and sOS + * are already been loaded. + */ + if (psp_v11_0_is_sos_alive(psp)) + return 0; + + ret = psp_v11_0_wait_for_bootloader(psp); + if (ret) + return ret; + + /* Copy PSP SPL binary to memory */ + psp_copy_fw(psp, psp->spl.start_addr, psp->spl.size_bytes); + + /* Provide the PSP SPL to bootloader */ + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, + (uint32_t)(psp->fw_pri_mc_addr >> 20)); + psp_gfxdrv_command_reg = PSP_BL__LOAD_TOS_SPL_TABLE; + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, + psp_gfxdrv_command_reg); + + ret = psp_v11_0_wait_for_bootloader(psp); + + return ret; +} + +static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) { int ret; uint32_t psp_gfxdrv_command_reg = 0; @@ -296,35 +349,23 @@ static int psp_v11_0_bootloader_load_component(struct psp_context *psp, return ret; /* Copy PSP System Driver binary to memory */ - psp_copy_fw(psp, bin_desc->start_addr, bin_desc->size_bytes); + psp_copy_fw(psp, psp->sys.start_addr, psp->sys.size_bytes); /* Provide the sys driver to bootloader */ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, (uint32_t)(psp->fw_pri_mc_addr >> 20)); - psp_gfxdrv_command_reg = bl_cmd; + psp_gfxdrv_command_reg = PSP_BL__LOAD_SYSDRV; WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_35, psp_gfxdrv_command_reg); + /* there might be handshake issue with hardware which needs delay */ + mdelay(20); + ret = psp_v11_0_wait_for_bootloader(psp); return ret; } -static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp) -{ - return psp_v11_0_bootloader_load_component(psp, &psp->kdb, PSP_BL__LOAD_KEY_DATABASE); -} - -static int psp_v11_0_bootloader_load_spl(struct psp_context *psp) -{ - return psp_v11_0_bootloader_load_component(psp, &psp->spl, PSP_BL__LOAD_TOS_SPL_TABLE); -} - -static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) -{ - return psp_v11_0_bootloader_load_component(psp, &psp->sys, PSP_BL__LOAD_SYSDRV); -} - static int psp_v11_0_bootloader_load_sos(struct psp_context *psp) { int ret; @@ -650,7 +691,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) return -ENOMEM; } - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN); if (ret) { diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c index a2588200ea..cc64940623 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c @@ -84,22 +84,22 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) ta_hdr = (const struct ta_firmware_header_v1_0 *) adev->psp.ta_fw->data; - adev->psp.hdcp_context.context.bin_desc.fw_version = + adev->psp.hdcp.feature_version = le32_to_cpu(ta_hdr->hdcp.fw_version); - adev->psp.hdcp_context.context.bin_desc.size_bytes = + adev->psp.hdcp.size_bytes = le32_to_cpu(ta_hdr->hdcp.size_bytes); - adev->psp.hdcp_context.context.bin_desc.start_addr = + adev->psp.hdcp.start_addr = (uint8_t *)ta_hdr + le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes); adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version); - adev->psp.dtm_context.context.bin_desc.fw_version = + adev->psp.dtm.feature_version = le32_to_cpu(ta_hdr->dtm.fw_version); - adev->psp.dtm_context.context.bin_desc.size_bytes = + adev->psp.dtm.size_bytes = le32_to_cpu(ta_hdr->dtm.size_bytes); - adev->psp.dtm_context.context.bin_desc.start_addr = - (uint8_t *)adev->psp.hdcp_context.context.bin_desc.start_addr + + adev->psp.dtm.start_addr = + (uint8_t *)adev->psp.hdcp.start_addr + le32_to_cpu(ta_hdr->dtm.offset_bytes); } diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 17655bc6d2..47a500f64d 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -47,19 +47,18 @@ static int psp_v13_0_init_microcode(struct psp_context *psp) const char *chip_name; int err = 0; - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(13, 0, 2): + switch (adev->asic_type) { + case CHIP_ALDEBARAN: chip_name = "aldebaran"; break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + case CHIP_YELLOW_CARP: chip_name = "yellow_carp"; break; default: BUG(); } - switch (adev->ip_versions[MP0_HWIP][0]) { - case IP_VERSION(13, 0, 2): + switch (adev->asic_type) { + case CHIP_ALDEBARAN: err = psp_init_sos_microcode(psp, chip_name); if (err) return err; @@ -67,8 +66,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp) if (err) return err; break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + case CHIP_YELLOW_CARP: err = psp_init_asd_microcode(psp, chip_name); if (err) return err; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index f0638db571..e37948c157 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -469,8 +469,8 @@ static int sdma_v4_0_irq_id_to_seq(unsigned client_id) static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: soc15_program_register_sequence(adev, golden_settings_sdma_4, ARRAY_SIZE(golden_settings_sdma_4)); @@ -478,7 +478,7 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_vg10, ARRAY_SIZE(golden_settings_sdma_vg10)); break; - case IP_VERSION(4, 0, 1): + case CHIP_VEGA12: soc15_program_register_sequence(adev, golden_settings_sdma_4, ARRAY_SIZE(golden_settings_sdma_4)); @@ -486,7 +486,7 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_vg12, ARRAY_SIZE(golden_settings_sdma_vg12)); break; - case IP_VERSION(4, 2, 0): + case CHIP_VEGA20: soc15_program_register_sequence(adev, golden_settings_sdma0_4_2_init, ARRAY_SIZE(golden_settings_sdma0_4_2_init)); @@ -497,18 +497,17 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma1_4_2, ARRAY_SIZE(golden_settings_sdma1_4_2)); break; - case IP_VERSION(4, 2, 2): + case CHIP_ARCTURUS: soc15_program_register_sequence(adev, golden_settings_sdma_arct, ARRAY_SIZE(golden_settings_sdma_arct)); break; - case IP_VERSION(4, 4, 0): + case CHIP_ALDEBARAN: soc15_program_register_sequence(adev, golden_settings_sdma_aldebaran, ARRAY_SIZE(golden_settings_sdma_aldebaran)); break; - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): + case CHIP_RAVEN: soc15_program_register_sequence(adev, golden_settings_sdma_4_1, ARRAY_SIZE(golden_settings_sdma_4_1)); @@ -521,7 +520,7 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_rv1, ARRAY_SIZE(golden_settings_sdma_rv1)); break; - case IP_VERSION(4, 1, 2): + case CHIP_RENOIR: soc15_program_register_sequence(adev, golden_settings_sdma_4_3, ARRAY_SIZE(golden_settings_sdma_4_3)); @@ -539,12 +538,12 @@ static void sdma_v4_0_setup_ulv(struct amdgpu_device *adev) * The only chips with SDMAv4 and ULV are VG10 and VG20. * Server SKUs take a different hysteresis setting from other SKUs. */ - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: if (adev->pdev->device == 0x6860) break; return; - case IP_VERSION(4, 2, 0): + case CHIP_VEGA20: if (adev->pdev->device == 0x66a1) break; return; @@ -590,8 +589,8 @@ static void sdma_v4_0_destroy_inst_ctx(struct amdgpu_device *adev) /* arcturus shares the same FW memory across all SDMA isntances */ - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) || - adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) + if (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) break; } @@ -621,18 +620,17 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: chip_name = "vega10"; break; - case IP_VERSION(4, 0, 1): + case CHIP_VEGA12: chip_name = "vega12"; break; - case IP_VERSION(4, 2, 0): + case CHIP_VEGA20: chip_name = "vega20"; break; - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): + case CHIP_RAVEN: if (adev->apu_flags & AMD_APU_IS_RAVEN2) chip_name = "raven2"; else if (adev->apu_flags & AMD_APU_IS_PICASSO) @@ -640,16 +638,16 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) else chip_name = "raven"; break; - case IP_VERSION(4, 2, 2): + case CHIP_ARCTURUS: chip_name = "arcturus"; break; - case IP_VERSION(4, 1, 2): + case CHIP_RENOIR: if (adev->apu_flags & AMD_APU_IS_RENOIR) chip_name = "renoir"; else chip_name = "green_sardine"; break; - case IP_VERSION(4, 4, 0): + case CHIP_ALDEBARAN: chip_name = "aldebaran"; break; default: @@ -667,8 +665,8 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) goto out; for (i = 1; i < adev->sdma.num_instances; i++) { - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) || - adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0)) { + if (adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) { /* Acturus & Aldebaran will leverage the same FW memory for every SDMA instance */ memcpy((void *)&adev->sdma.instance[i], @@ -1108,7 +1106,7 @@ static void sdma_v4_0_ctx_switch_enable(struct amdgpu_device *adev, bool enable) * Arcturus for the moment and firmware version 14 * and above. */ - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) && + if (adev->asic_type == CHIP_ARCTURUS && adev->sdma.instance[i].fw_version >= 14) WREG32_SDMA(i, mmSDMA0_PUB_DUMMY_REG2, enable); /* Extend page fault timeout to avoid interrupt storm */ @@ -1395,10 +1393,9 @@ static void sdma_v4_0_init_pg(struct amdgpu_device *adev) if (!(adev->pg_flags & AMD_PG_SUPPORT_SDMA)) return; - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - case IP_VERSION(4, 1, 2): + switch (adev->asic_type) { + case CHIP_RAVEN: + case CHIP_RENOIR: sdma_v4_1_init_power_gating(adev); sdma_v4_1_update_power_gating(adev, true); break; @@ -1838,13 +1835,13 @@ static bool sdma_v4_0_fw_support_paging_queue(struct amdgpu_device *adev) { uint fw_version = adev->sdma.instance[0].fw_version; - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 0, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: return fw_version >= 430; - case IP_VERSION(4, 0, 1): + case CHIP_VEGA12: /*return fw_version >= 31;*/ return false; - case IP_VERSION(4, 2, 0): + case CHIP_VEGA20: return fw_version >= 123; default: return false; @@ -1856,6 +1853,15 @@ static int sdma_v4_0_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int r; + if (adev->flags & AMD_IS_APU) + adev->sdma.num_instances = 1; + else if (adev->asic_type == CHIP_ARCTURUS) + adev->sdma.num_instances = 8; + else if (adev->asic_type == CHIP_ALDEBARAN) + adev->sdma.num_instances = 5; + else + adev->sdma.num_instances = 2; + r = sdma_v4_0_init_microcode(adev); if (r) { DRM_ERROR("Failed to load sdma firmware!\n"); @@ -1863,8 +1869,7 @@ static int sdma_v4_0_early_init(void *handle) } /* TODO: Page queue breaks driver reload under SRIOV */ - if ((adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 0, 0)) && - amdgpu_sriov_vf((adev))) + if ((adev->asic_type == CHIP_VEGA10) && amdgpu_sriov_vf((adev))) adev->sdma.has_page_queue = false; else if (sdma_v4_0_fw_support_paging_queue(adev)) adev->sdma.has_page_queue = true; @@ -2144,14 +2149,14 @@ static int sdma_v4_0_process_trap_irq(struct amdgpu_device *adev, amdgpu_fence_process(&adev->sdma.instance[instance].ring); break; case 1: - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 0)) + if (adev->asic_type == CHIP_VEGA20) amdgpu_fence_process(&adev->sdma.instance[instance].page); break; case 2: /* XXX compute */ break; case 3: - if (adev->ip_versions[SDMA0_HWIP][0] != IP_VERSION(4, 2, 0)) + if (adev->asic_type != CHIP_VEGA20) amdgpu_fence_process(&adev->sdma.instance[instance].page); break; } @@ -2367,10 +2372,9 @@ static int sdma_v4_0_set_powergating_state(void *handle, { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 1, 0): - case IP_VERSION(4, 1, 1): - case IP_VERSION(4, 1, 2): + switch (adev->asic_type) { + case CHIP_RAVEN: + case CHIP_RENOIR: sdma_v4_1_update_power_gating(adev, state == AMD_PG_STATE_GATE); break; @@ -2555,7 +2559,7 @@ static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) int i; for (i = 0; i < adev->sdma.num_instances; i++) { - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) && i >= 5) + if (adev->asic_type == CHIP_ARCTURUS && i >= 5) adev->sdma.instance[i].ring.funcs = &sdma_v4_0_ring_funcs_2nd_mmhub; else @@ -2563,7 +2567,7 @@ static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev) &sdma_v4_0_ring_funcs; adev->sdma.instance[i].ring.me = i; if (adev->sdma.has_page_queue) { - if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) && i >= 5) + if (adev->asic_type == CHIP_ARCTURUS && i >= 5) adev->sdma.instance[i].page.funcs = &sdma_v4_0_page_ring_funcs_2nd_mmhub; else @@ -2790,12 +2794,12 @@ static const struct amdgpu_sdma_ras_funcs sdma_v4_0_ras_funcs = { static void sdma_v4_0_set_ras_funcs(struct amdgpu_device *adev) { - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(4, 2, 0): - case IP_VERSION(4, 2, 2): + switch (adev->asic_type) { + case CHIP_VEGA20: + case CHIP_ARCTURUS: adev->sdma.funcs = &sdma_v4_0_ras_funcs; break; - case IP_VERSION(4, 4, 0): + case CHIP_ALDEBARAN: adev->sdma.funcs = &sdma_v4_4_ras_funcs; break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index 81e033549d..50bf3b71bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -187,8 +187,8 @@ static u32 sdma_v5_0_get_reg_offset(struct amdgpu_device *adev, u32 instance, u3 static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev) { - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(5, 0, 0): + switch (adev->asic_type) { + case CHIP_NAVI10: soc15_program_register_sequence(adev, golden_settings_sdma_5, (const u32)ARRAY_SIZE(golden_settings_sdma_5)); @@ -196,7 +196,7 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_nv10, (const u32)ARRAY_SIZE(golden_settings_sdma_nv10)); break; - case IP_VERSION(5, 0, 2): + case CHIP_NAVI14: soc15_program_register_sequence(adev, golden_settings_sdma_5, (const u32)ARRAY_SIZE(golden_settings_sdma_5)); @@ -204,7 +204,7 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_nv14, (const u32)ARRAY_SIZE(golden_settings_sdma_nv14)); break; - case IP_VERSION(5, 0, 5): + case CHIP_NAVI12: if (amdgpu_sriov_vf(adev)) soc15_program_register_sequence(adev, golden_settings_sdma_5_sriov, @@ -217,7 +217,7 @@ static void sdma_v5_0_init_golden_registers(struct amdgpu_device *adev) golden_settings_sdma_nv12, (const u32)ARRAY_SIZE(golden_settings_sdma_nv12)); break; - case IP_VERSION(5, 0, 1): + case CHIP_CYAN_SKILLFISH: soc15_program_register_sequence(adev, golden_settings_sdma_cyan_skillfish, (const u32)ARRAY_SIZE(golden_settings_sdma_cyan_skillfish)); @@ -248,22 +248,22 @@ static int sdma_v5_0_init_microcode(struct amdgpu_device *adev) const struct common_firmware_header *header = NULL; const struct sdma_firmware_header_v1_0 *hdr; - if (amdgpu_sriov_vf(adev) && (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 0, 5))) + if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_NAVI12)) return 0; DRM_DEBUG("\n"); - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(5, 0, 0): + switch (adev->asic_type) { + case CHIP_NAVI10: chip_name = "navi10"; break; - case IP_VERSION(5, 0, 2): + case CHIP_NAVI14: chip_name = "navi14"; break; - case IP_VERSION(5, 0, 5): + case CHIP_NAVI12: chip_name = "navi12"; break; - case IP_VERSION(5, 0, 1): + case CHIP_CYAN_SKILLFISH: if (adev->apu_flags & AMD_APU_IS_CYAN_SKILLFISH2) chip_name = "cyan_skillfish2"; else @@ -481,6 +481,8 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring, * sdma_v5_0_ring_emit_mem_sync - flush the IB by graphics cache rinse * * @ring: amdgpu ring pointer + * @job: job to retrieve vmid from + * @ib: IB object to schedule * * flush the IB by graphics cache rinse. */ @@ -1293,6 +1295,8 @@ static int sdma_v5_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + adev->sdma.num_instances = 2; + sdma_v5_0_set_ring_funcs(adev); sdma_v5_0_set_buffer_funcs(adev); sdma_v5_0_set_vm_pte_funcs(adev); @@ -1632,10 +1636,10 @@ static int sdma_v5_0_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(5, 0, 0): - case IP_VERSION(5, 0, 2): - case IP_VERSION(5, 0, 5): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: sdma_v5_0_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); sdma_v5_0_update_medium_grain_light_sleep(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index d3d6d5b045..e32efcfb0c 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -136,23 +136,23 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev) DRM_DEBUG("\n"); - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(5, 2, 0): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: chip_name = "sienna_cichlid"; break; - case IP_VERSION(5, 2, 2): + case CHIP_NAVY_FLOUNDER: chip_name = "navy_flounder"; break; - case IP_VERSION(5, 2, 1): + case CHIP_VANGOGH: chip_name = "vangogh"; break; - case IP_VERSION(5, 2, 4): + case CHIP_DIMGREY_CAVEFISH: chip_name = "dimgrey_cavefish"; break; - case IP_VERSION(5, 2, 5): + case CHIP_BEIGE_GOBY: chip_name = "beige_goby"; break; - case IP_VERSION(5, 2, 3): + case CHIP_YELLOW_CARP: chip_name = "yellow_carp"; break; default: @@ -174,7 +174,7 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev) (void *)&adev->sdma.instance[0], sizeof(struct amdgpu_sdma_instance)); - if (amdgpu_sriov_vf(adev) && (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 2, 0))) + if (amdgpu_sriov_vf(adev) && (adev->asic_type == CHIP_SIENNA_CICHLID)) return 0; DRM_DEBUG("psp_load == '%s'\n", @@ -368,15 +368,17 @@ static void sdma_v5_2_ring_emit_ib(struct amdgpu_ring *ring, * sdma_v5_2_ring_emit_mem_sync - flush the IB by graphics cache rinse * * @ring: amdgpu ring pointer + * @job: job to retrieve vmid from + * @ib: IB object to schedule * * flush the IB by graphics cache rinse. */ static void sdma_v5_2_ring_emit_mem_sync(struct amdgpu_ring *ring) { - uint32_t gcr_cntl = SDMA_GCR_GL2_INV | SDMA_GCR_GL2_WB | - SDMA_GCR_GLM_INV | SDMA_GCR_GL1_INV | - SDMA_GCR_GLV_INV | SDMA_GCR_GLK_INV | - SDMA_GCR_GLI_INV(1); + uint32_t gcr_cntl = + SDMA_GCR_GL2_INV | SDMA_GCR_GL2_WB | SDMA_GCR_GLM_INV | + SDMA_GCR_GL1_INV | SDMA_GCR_GLV_INV | SDMA_GCR_GLK_INV | + SDMA_GCR_GLI_INV(1); /* flush entire cache L0/L1/L2, this can be optimized by performance requirement */ amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ)); @@ -542,6 +544,9 @@ static void sdma_v5_2_ctx_switch_enable(struct amdgpu_device *adev, bool enable) } for (i = 0; i < adev->sdma.num_instances; i++) { + f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, + AUTO_CTXSW_ENABLE, enable ? 1 : 0); if (enable && amdgpu_sdma_phase_quantum) { WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM), phase_quantum); @@ -550,13 +555,7 @@ static void sdma_v5_2_ctx_switch_enable(struct amdgpu_device *adev, bool enable) WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM), phase_quantum); } - - if (!amdgpu_sriov_vf(adev)) { - f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, - AUTO_CTXSW_ENABLE, enable ? 1 : 0); - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl); - } + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl); } } @@ -579,12 +578,10 @@ static void sdma_v5_2_enable(struct amdgpu_device *adev, bool enable) sdma_v5_2_rlc_stop(adev); } - if (!amdgpu_sriov_vf(adev)) { - for (i = 0; i < adev->sdma.num_instances; i++) { - f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1); - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl); - } + for (i = 0; i < adev->sdma.num_instances; i++) { + f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1); + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl); } } @@ -613,8 +610,7 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) ring = &adev->sdma.instance[i].ring; wb_offset = (ring->rptr_offs * 4); - if (!amdgpu_sriov_vf(adev)) - WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0); + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0); /* Set ring buffer size in dwords */ rb_bufsz = order_base_2(ring->ring_size / 4); @@ -689,34 +685,32 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) sdma_v5_2_ring_set_wptr(ring); /* set minor_ptr_update to 0 after wptr programed */ - WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 0); - /* SRIOV VF has no control of any of registers below */ + /* set utc l1 enable flag always to 1 */ + temp = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); + temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1); + + /* enable MCBP */ + temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1); + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), temp); + + /* Set up RESP_MODE to non-copy addresses */ + temp = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL)); + temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3); + temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9); + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp); + + /* program default cache read and write policy */ + temp = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE)); + /* clean read policy and write policy bits */ + temp &= 0xFF0FFF; + temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | + (CACHE_WRITE_POLICY_L2__DEFAULT << 14) | + SDMA0_UTCL1_PAGE__LLC_NOALLOC_MASK); + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp); + if (!amdgpu_sriov_vf(adev)) { - /* set utc l1 enable flag always to 1 */ - temp = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); - temp = REG_SET_FIELD(temp, SDMA0_CNTL, UTC_L1_ENABLE, 1); - - /* enable MCBP */ - temp = REG_SET_FIELD(temp, SDMA0_CNTL, MIDCMD_PREEMPT_ENABLE, 1); - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), temp); - - /* Set up RESP_MODE to non-copy addresses */ - temp = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL)); - temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3); - temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9); - WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_CNTL), temp); - - /* program default cache read and write policy */ - temp = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE)); - /* clean read policy and write policy bits */ - temp &= 0xFF0FFF; - temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | - (CACHE_WRITE_POLICY_L2__DEFAULT << 14) | - SDMA0_UTCL1_PAGE__LLC_NOALLOC_MASK); - WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp); - /* unhalt engine */ temp = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0); @@ -1223,6 +1217,23 @@ static int sdma_v5_2_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + adev->sdma.num_instances = 4; + break; + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + adev->sdma.num_instances = 2; + break; + case CHIP_VANGOGH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + adev->sdma.num_instances = 1; + break; + default: + break; + } + sdma_v5_2_set_ring_funcs(adev); sdma_v5_2_set_buffer_funcs(adev); sdma_v5_2_set_vm_pte_funcs(adev); @@ -1444,14 +1455,13 @@ static int sdma_v5_2_set_trap_irq_state(struct amdgpu_device *adev, enum amdgpu_interrupt_state state) { u32 sdma_cntl; + u32 reg_offset = sdma_v5_2_get_reg_offset(adev, type, mmSDMA0_CNTL); - if (!amdgpu_sriov_vf(adev)) { - sdma_cntl = RREG32(reg_offset); - sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE, - state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); - WREG32(reg_offset, sdma_cntl); - } + sdma_cntl = RREG32(reg_offset); + sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE, + state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); + WREG32(reg_offset, sdma_cntl); return 0; } @@ -1545,7 +1555,7 @@ static void sdma_v5_2_update_medium_grain_clock_gating(struct amdgpu_device *ade for (i = 0; i < adev->sdma.num_instances; i++) { - if (adev->sdma.instance[i].fw_version < 70 && adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 2, 1)) + if (adev->sdma.instance[i].fw_version < 70 && adev->asic_type == CHIP_VANGOGH) adev->cg_flags &= ~AMD_CG_SUPPORT_SDMA_MGCG; if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG)) { @@ -1582,7 +1592,7 @@ static void sdma_v5_2_update_medium_grain_light_sleep(struct amdgpu_device *adev for (i = 0; i < adev->sdma.num_instances; i++) { - if (adev->sdma.instance[i].fw_version < 70 && adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(5, 2, 1)) + if (adev->sdma.instance[i].fw_version < 70 && adev->asic_type == CHIP_VANGOGH) adev->cg_flags &= ~AMD_CG_SUPPORT_SDMA_LS; if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_LS)) { @@ -1611,13 +1621,13 @@ static int sdma_v5_2_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[SDMA0_HWIP][0]) { - case IP_VERSION(5, 2, 0): - case IP_VERSION(5, 2, 2): - case IP_VERSION(5, 2, 1): - case IP_VERSION(5, 2, 4): - case IP_VERSION(5, 2, 5): - case IP_VERSION(5, 2, 3): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: sdma_v5_2_update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); sdma_v5_2_update_medium_grain_light_sleep(adev, diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 12f80fdc1f..6439d5c3d8 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -85,8 +85,6 @@ #define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba #define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 -static const struct amd_ip_funcs soc15_common_ip_funcs; - /* Vega, Raven, Arcturus */ static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = { @@ -156,38 +154,31 @@ static const struct amdgpu_video_codecs rn_video_codecs_decode = static int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode, const struct amdgpu_video_codecs **codecs) { - if (adev->ip_versions[VCE_HWIP][0]) { - switch (adev->ip_versions[VCE_HWIP][0]) { - case IP_VERSION(4, 0, 0): - case IP_VERSION(4, 1, 0): - if (encode) - *codecs = &vega_video_codecs_encode; - else - *codecs = &vega_video_codecs_decode; - return 0; - default: - return -EINVAL; - } - } else { - switch (adev->ip_versions[UVD_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - if (encode) - *codecs = &vega_video_codecs_encode; - else - *codecs = &rv_video_codecs_decode; - return 0; - case IP_VERSION(2, 5, 0): - case IP_VERSION(2, 6, 0): - case IP_VERSION(2, 2, 0): - if (encode) - *codecs = &vega_video_codecs_encode; - else - *codecs = &rn_video_codecs_decode; - return 0; - default: - return -EINVAL; - } + switch (adev->asic_type) { + case CHIP_VEGA20: + case CHIP_VEGA10: + case CHIP_VEGA12: + if (encode) + *codecs = &vega_video_codecs_encode; + else + *codecs = &vega_video_codecs_decode; + return 0; + case CHIP_RAVEN: + if (encode) + *codecs = &vega_video_codecs_encode; + else + *codecs = &rv_video_codecs_decode; + return 0; + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: + case CHIP_RENOIR: + if (encode) + *codecs = &vega_video_codecs_encode; + else + *codecs = &rn_video_codecs_decode; + return 0; + default: + return -EINVAL; } } @@ -341,11 +332,9 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev) { u32 reference_clock = adev->clock.spll.reference_freq; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) + if (adev->asic_type == CHIP_RENOIR) return 10000; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1)) + if (adev->asic_type == CHIP_RAVEN) return reference_clock / 4; return reference_clock; @@ -576,29 +565,28 @@ soc15_asic_reset_method(struct amdgpu_device *adev) dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", amdgpu_reset_method); - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(10, 0, 0): - case IP_VERSION(10, 0, 1): - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): + switch (adev->asic_type) { + case CHIP_RAVEN: + case CHIP_RENOIR: return AMD_RESET_METHOD_MODE2; - case IP_VERSION(9, 0, 0): - case IP_VERSION(11, 0, 2): - if (adev->asic_type == CHIP_VEGA20) { - if (adev->psp.sos.fw_version >= 0x80067) - baco_reset = amdgpu_dpm_is_baco_supported(adev); - /* - * 1. PMFW version > 0x284300: all cases use baco - * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco - */ - if (ras && adev->ras_enabled && - adev->pm.fw_version <= 0x283400) - baco_reset = false; - } else { - baco_reset = amdgpu_dpm_is_baco_supported(adev); - } + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_ARCTURUS: + baco_reset = amdgpu_dpm_is_baco_supported(adev); break; - case IP_VERSION(13, 0, 2): + case CHIP_VEGA20: + if (adev->psp.sos.fw_version >= 0x80067) + baco_reset = amdgpu_dpm_is_baco_supported(adev); + + /* + * 1. PMFW version > 0x284300: all cases use baco + * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco + */ + if (ras && adev->ras_enabled && + adev->pm.fw_version <= 0x283400) + baco_reset = false; + break; + case CHIP_ALDEBARAN: /* * 1.connected to cpu: driver issue mode2 reset * 2.discret gpu: driver issue mode1 reset @@ -641,17 +629,15 @@ static int soc15_asic_reset(struct amdgpu_device *adev) static bool soc15_supports_baco(struct amdgpu_device *adev) { - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(9, 0, 0): - case IP_VERSION(11, 0, 2): - if (adev->asic_type == CHIP_VEGA20) { - if (adev->psp.sos.fw_version >= 0x80067) - return amdgpu_dpm_is_baco_supported(adev); - return false; - } else { + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_ARCTURUS: + return amdgpu_dpm_is_baco_supported(adev); + case CHIP_VEGA20: + if (adev->psp.sos.fw_version >= 0x80067) return amdgpu_dpm_is_baco_supported(adev); - } - break; + return false; default: return false; } @@ -718,7 +704,7 @@ static void soc15_enable_doorbell_aperture(struct amdgpu_device *adev, adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); } -const struct amdgpu_ip_block_version vega10_common_ip_block = +static const struct amdgpu_ip_block_version vega10_common_ip_block = { .type = AMD_IP_BLOCK_TYPE_COMMON, .major = 2, @@ -744,7 +730,7 @@ static void soc15_reg_base_init(struct amdgpu_device *adev) vega10_reg_base_init(adev); break; case CHIP_RENOIR: - /* It's safe to do ip discovery here for Renoir, + /* It's safe to do ip discovery here for Renior, * it doesn't support SRIOV. */ if (amdgpu_discovery) { r = amdgpu_discovery_reg_base_init(adev); @@ -780,6 +766,185 @@ void soc15_set_virt_ops(struct amdgpu_device *adev) soc15_reg_base_init(adev); } +int soc15_set_ip_blocks(struct amdgpu_device *adev) +{ + /* for bare metal case */ + if (!amdgpu_sriov_vf(adev)) + soc15_reg_base_init(adev); + + if (adev->flags & AMD_IS_APU) { + adev->nbio.funcs = &nbio_v7_0_funcs; + adev->nbio.hdp_flush_reg = &nbio_v7_0_hdp_flush_reg; + } else if (adev->asic_type == CHIP_VEGA20 || + adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) { + adev->nbio.funcs = &nbio_v7_4_funcs; + adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg; + } else { + adev->nbio.funcs = &nbio_v6_1_funcs; + adev->nbio.hdp_flush_reg = &nbio_v6_1_hdp_flush_reg; + } + adev->hdp.funcs = &hdp_v4_0_funcs; + + if (adev->asic_type == CHIP_VEGA20 || + adev->asic_type == CHIP_ARCTURUS || + adev->asic_type == CHIP_ALDEBARAN) + adev->df.funcs = &df_v3_6_funcs; + else + adev->df.funcs = &df_v1_7_funcs; + + if (adev->asic_type == CHIP_VEGA20 || + adev->asic_type == CHIP_ARCTURUS) + adev->smuio.funcs = &smuio_v11_0_funcs; + else if (adev->asic_type == CHIP_ALDEBARAN) + adev->smuio.funcs = &smuio_v13_0_funcs; + else + adev->smuio.funcs = &smuio_v9_0_funcs; + + adev->rev_id = soc15_get_rev_id(adev); + + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); + + /* For Vega10 SR-IOV, PSP need to be initialized before IH */ + if (amdgpu_sriov_vf(adev)) { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { + if (adev->asic_type == CHIP_VEGA20) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + else + amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); + } + if (adev->asic_type == CHIP_VEGA20) + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + else + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); + } else { + if (adev->asic_type == CHIP_VEGA20) + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + else + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { + if (adev->asic_type == CHIP_VEGA20) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + else + amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); + } + } + amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); + if (is_support_sw_smu(adev)) { + if (!amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + } else { + amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); + } + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + if (!(adev->asic_type == CHIP_VEGA20 && amdgpu_sriov_vf(adev))) { + amdgpu_device_ip_block_add(adev, &uvd_v7_0_ip_block); + amdgpu_device_ip_block_add(adev, &vce_v4_0_ip_block); + } + break; + case CHIP_RAVEN: + amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v10_0_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); + amdgpu_device_ip_block_add(adev, &pp_smu_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &vcn_v1_0_ip_block); + break; + case CHIP_ARCTURUS: + amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); + + if (amdgpu_sriov_vf(adev)) { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + } else { + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); + } + + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); + amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); + + if (amdgpu_sriov_vf(adev)) { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); + } else { + amdgpu_device_ip_block_add(adev, &vcn_v2_5_ip_block); + } + if (!amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &jpeg_v2_5_ip_block); + break; + case CHIP_RENOIR: + amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &vega10_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v12_0_ip_block); + amdgpu_device_ip_block_add(adev, &smu_v12_0_ip_block); + amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); + if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) + amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block); +#if defined(CONFIG_DRM_AMD_DC) + else if (amdgpu_device_has_dc_support(adev)) + amdgpu_device_ip_block_add(adev, &dm_ip_block); +#endif + amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); + break; + case CHIP_ALDEBARAN: + amdgpu_device_ip_block_add(adev, &vega10_common_ip_block); + amdgpu_device_ip_block_add(adev, &gmc_v9_0_ip_block); + + if (amdgpu_sriov_vf(adev)) { + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + } else { + amdgpu_device_ip_block_add(adev, &vega20_ih_ip_block); + if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) + amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block); + } + + amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block); + amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block); + + amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); + amdgpu_device_ip_block_add(adev, &vcn_v2_6_ip_block); + amdgpu_device_ip_block_add(adev, &jpeg_v2_6_ip_block); + break; + default: + return -EINVAL; + } + + return 0; +} + static bool soc15_need_full_reset(struct amdgpu_device *adev) { /* change this when we implement soft reset */ @@ -971,10 +1136,8 @@ static int soc15_common_early_init(void *handle) #define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (!amdgpu_sriov_vf(adev)) { - adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; - adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; - } + adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; + adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; adev->smc_rreg = NULL; adev->smc_wreg = NULL; adev->pcie_rreg = &soc15_pcie_rreg; @@ -990,13 +1153,10 @@ static int soc15_common_early_init(void *handle) adev->se_cac_rreg = &soc15_se_cac_rreg; adev->se_cac_wreg = &soc15_se_cac_wreg; - adev->rev_id = soc15_get_rev_id(adev); + adev->external_rev_id = 0xFF; - /* TODO: split the GC and PG flags based on the relevant IP version for which - * they are relevant. - */ - switch (adev->ip_versions[GC_HWIP][0]) { - case IP_VERSION(9, 0, 1): + switch (adev->asic_type) { + case CHIP_VEGA10: adev->asic_funcs = &soc15_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | @@ -1020,7 +1180,7 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = 0; adev->external_rev_id = 0x1; break; - case IP_VERSION(9, 2, 1): + case CHIP_VEGA12: adev->asic_funcs = &soc15_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | @@ -1043,7 +1203,7 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x14; break; - case IP_VERSION(9, 4, 0): + case CHIP_VEGA20: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | @@ -1066,8 +1226,7 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x28; break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): + case CHIP_RAVEN: adev->asic_funcs = &soc15_asic_funcs; if (adev->rev_id >= 0x8) @@ -1143,7 +1302,7 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; } break; - case IP_VERSION(9, 4, 1): + case CHIP_ARCTURUS: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | @@ -1162,7 +1321,7 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG; adev->external_rev_id = adev->rev_id + 0x32; break; - case IP_VERSION(9, 3, 0): + case CHIP_RENOIR: adev->asic_funcs = &soc15_asic_funcs; if (adev->apu_flags & AMD_APU_IS_RENOIR) @@ -1193,7 +1352,7 @@ static int soc15_common_early_init(void *handle) AMD_PG_SUPPORT_JPEG | AMD_PG_SUPPORT_VCN_DPG; break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: adev->asic_funcs = &vega20_asic_funcs; adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | @@ -1241,9 +1400,7 @@ static int soc15_common_sw_init(void *handle) if (amdgpu_sriov_vf(adev)) xgpu_ai_mailbox_add_irq_id(adev); - if (adev->df.funcs && - adev->df.funcs->sw_init) - adev->df.funcs->sw_init(adev); + adev->df.funcs->sw_init(adev); return 0; } @@ -1255,10 +1412,7 @@ static int soc15_common_sw_fini(void *handle) if (adev->nbio.ras_funcs && adev->nbio.ras_funcs->ras_fini) adev->nbio.ras_funcs->ras_fini(adev); - - if (adev->df.funcs && - adev->df.funcs->sw_fini) - adev->df.funcs->sw_fini(adev); + adev->df.funcs->sw_fini(adev); return 0; } @@ -1295,7 +1449,7 @@ static int soc15_common_hw_init(void *handle) * for the purpose of expose those registers * to process space */ - if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) + if (adev->nbio.funcs->remap_hdp_registers) adev->nbio.funcs->remap_hdp_registers(adev); /* enable the doorbell aperture */ @@ -1413,10 +1567,10 @@ static int soc15_common_set_clockgating_state(void *handle, if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[NBIO_HWIP][0]) { - case IP_VERSION(6, 1, 0): - case IP_VERSION(6, 2, 0): - case IP_VERSION(7, 4, 0): + switch (adev->asic_type) { + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: adev->nbio.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->nbio.funcs->update_medium_grain_light_sleep(adev, @@ -1432,9 +1586,8 @@ static int soc15_common_set_clockgating_state(void *handle, adev->df.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); break; - case IP_VERSION(7, 0, 0): - case IP_VERSION(7, 0, 1): - case IP_VERSION(2, 5, 0): + case CHIP_RAVEN: + case CHIP_RENOIR: adev->nbio.funcs->update_medium_grain_clock_gating(adev, state == AMD_CG_STATE_GATE); adev->nbio.funcs->update_medium_grain_light_sleep(adev, @@ -1446,8 +1599,8 @@ static int soc15_common_set_clockgating_state(void *handle, soc15_update_drm_light_sleep(adev, state == AMD_CG_STATE_GATE); break; - case IP_VERSION(7, 4, 1): - case IP_VERSION(7, 4, 4): + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: adev->hdp.funcs->update_clock_gating(adev, state == AMD_CG_STATE_GATE); break; @@ -1469,7 +1622,7 @@ static void soc15_common_get_clockgating_state(void *handle, u32 *flags) adev->hdp.funcs->get_clock_gating_state(adev, flags); - if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2)) { + if (adev->asic_type != CHIP_ALDEBARAN) { /* AMD_CG_SUPPORT_DRM_MGCG */ data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); @@ -1495,7 +1648,7 @@ static int soc15_common_set_powergating_state(void *handle, return 0; } -static const struct amd_ip_funcs soc15_common_ip_funcs = { +const struct amd_ip_funcs soc15_common_ip_funcs = { .name = "soc15_common", .early_init = soc15_common_early_init, .late_init = soc15_common_late_init, diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.h b/drivers/gpu/drm/amd/amdgpu/soc15.h index efc2a253e8..034cfdfc4d 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15.h @@ -28,11 +28,11 @@ #include "nbio_v7_0.h" #include "nbio_v7_4.h" -extern const struct amdgpu_ip_block_version vega10_common_ip_block; - #define SOC15_FLUSH_GPU_TLB_NUM_WREG 6 #define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 3 +extern const struct amd_ip_funcs soc15_common_ip_funcs; + struct soc15_reg_golden { u32 hwip; u32 instance; @@ -102,6 +102,7 @@ struct soc15_ras_field_entry { void soc15_grbm_select(struct amdgpu_device *adev, u32 me, u32 pipe, u32 queue, u32 vmid); void soc15_set_virt_ops(struct amdgpu_device *adev); +int soc15_set_ip_blocks(struct amdgpu_device *adev); void soc15_program_register_sequence(struct amdgpu_device *adev, const struct soc15_reg_golden *registers, diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index 473767e036..8a9ca87d86 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -51,8 +51,6 @@ #define RREG32_SOC15_IP(ip, reg) __RREG32_SOC15_RLC__(reg, 0, ip##_HWIP) -#define RREG32_SOC15_IP_NO_KIQ(ip, reg) __RREG32_SOC15_RLC__(reg, AMDGPU_REGS_NO_KIQ, ip##_HWIP) - #define RREG32_SOC15_NO_KIQ(ip, inst, reg) \ __RREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \ AMDGPU_REGS_NO_KIQ, ip##_HWIP) @@ -67,9 +65,6 @@ #define WREG32_SOC15_IP(ip, reg, value) \ __WREG32_SOC15_RLC__(reg, value, 0, ip##_HWIP) -#define WREG32_SOC15_IP_NO_KIQ(ip, reg, value) \ - __WREG32_SOC15_RLC__(reg, value, AMDGPU_REGS_NO_KIQ, ip##_HWIP) - #define WREG32_SOC15_NO_KIQ(ip, inst, reg, value) \ __WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg, \ value, AMDGPU_REGS_NO_KIQ, ip##_HWIP) diff --git a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h index 5093826a43..0f214a398d 100644 --- a/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h +++ b/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h @@ -38,8 +38,9 @@ enum ras_command { TA_RAS_COMMAND__TRIGGER_ERROR, }; -enum ta_ras_status { - TA_RAS_STATUS__SUCCESS = 0x0000, +enum ta_ras_status +{ + TA_RAS_STATUS__SUCCESS = 0x00, TA_RAS_STATUS__RESET_NEEDED = 0xA001, TA_RAS_STATUS__ERROR_INVALID_PARAMETER = 0xA002, TA_RAS_STATUS__ERROR_RAS_NOT_AVAILABLE = 0xA003, @@ -54,17 +55,7 @@ enum ta_ras_status { TA_RAS_STATUS__ERROR_GET_DEV_INFO = 0xA00C, TA_RAS_STATUS__ERROR_UNSUPPORTED_DEV = 0xA00D, TA_RAS_STATUS__ERROR_NOT_INITIALIZED = 0xA00E, - TA_RAS_STATUS__ERROR_TEE_INTERNAL = 0xA00F, - TA_RAS_STATUS__ERROR_UNSUPPORTED_FUNCTION = 0xA010, - TA_RAS_STATUS__ERROR_SYS_DRV_REG_ACCESS = 0xA011, - TA_RAS_STATUS__ERROR_RAS_READ_WRITE = 0xA012, - TA_RAS_STATUS__ERROR_NULL_PTR = 0xA013, - TA_RAS_STATUS__ERROR_UNSUPPORTED_IP = 0xA014, - TA_RAS_STATUS__ERROR_PCS_STATE_QUIET = 0xA015, - TA_RAS_STATUS__ERROR_PCS_STATE_ERROR = 0xA016, - TA_RAS_STATUS__ERROR_PCS_STATE_HANG = 0xA017, - TA_RAS_STATUS__ERROR_PCS_STATE_UNKNOWN = 0xA018, - TA_RAS_STATUS__ERROR_UNSUPPORTED_ERROR_INJ = 0xA019 + TA_RAS_STATUS__ERROR_TEE_INTERNAL = 0xA00F }; enum ta_ras_block { @@ -82,18 +73,9 @@ enum ta_ras_block { TA_RAS_BLOCK__MP0, TA_RAS_BLOCK__MP1, TA_RAS_BLOCK__FUSE, - TA_RAS_BLOCK__MCA, TA_NUM_BLOCK_MAX }; -enum ta_ras_mca_block { - TA_RAS_MCA_BLOCK__MP0 = 0, - TA_RAS_MCA_BLOCK__MP1 = 1, - TA_RAS_MCA_BLOCK__MPIO = 2, - TA_RAS_MCA_BLOCK__IOHC = 3, - TA_MCA_NUM_BLOCK_MAX -}; - enum ta_ras_error_type { TA_RAS_ERROR__NONE = 0, TA_RAS_ERROR__PARITY = 1, @@ -123,15 +105,17 @@ struct ta_ras_trigger_error_input { uint64_t value; // method if error injection. i.e persistent, coherent etc. }; -struct ta_ras_init_flags { - uint8_t poison_mode_en; - uint8_t dgpu_mode; +struct ta_ras_init_flags +{ + uint8_t poison_mode_en; + uint8_t dgpu_mode; }; -struct ta_ras_output_flags { - uint8_t ras_init_success_flag; - uint8_t err_inject_switch_disable_flag; - uint8_t reg_access_failure_flag; +struct ta_ras_output_flags +{ + uint8_t ras_init_success_flag; + uint8_t err_inject_switch_disable_flag; + uint8_t reg_access_failure_flag; }; /* Common input structure for RAS callbacks */ @@ -142,13 +126,14 @@ union ta_ras_cmd_input { struct ta_ras_disable_features_input disable_features; struct ta_ras_trigger_error_input trigger_error; - uint32_t reserve_pad[256]; + uint32_t reserve_pad[256]; }; -union ta_ras_cmd_output { - struct ta_ras_output_flags flags; +union ta_ras_cmd_output +{ + struct ta_ras_output_flags flags; - uint32_t reserve_pad[256]; + uint32_t reserve_pad[256]; }; /* Shared Memory structures */ diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c index 6dd1e19e8d..bb30336b1e 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v6_7.c @@ -50,165 +50,6 @@ static inline uint32_t get_umc_v6_7_reg_offset(struct amdgpu_device *adev, return adev->umc.channel_offs * ch_inst + UMC_V6_7_INST_DIST * umc_inst; } -static inline uint32_t get_umc_v6_7_channel_index(struct amdgpu_device *adev, - uint32_t umc_inst, - uint32_t ch_inst) -{ - return adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst]; -} - -static void umc_v6_7_ecc_info_query_correctable_error_count(struct amdgpu_device *adev, - uint32_t channel_index, - unsigned long *error_count) -{ - uint32_t ecc_err_cnt; - uint64_t mc_umc_status; - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - - /* - * select the lower chip and check the error count - * skip add error count, calc error counter only from mca_umc_status - */ - ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_lo_chip; - - /* - * select the higher chip and check the err counter - * skip add error count, calc error counter only from mca_umc_status - */ - ecc_err_cnt = ras->umc_ecc.ecc[channel_index].ce_count_hi_chip; - - /* check for SRAM correctable error - MCUMC_STATUS is a 64 bit register */ - mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status; - if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 && - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1) - *error_count += 1; -} - -static void umc_v6_7_ecc_info_querry_uncorrectable_error_count(struct amdgpu_device *adev, - uint32_t channel_index, - unsigned long *error_count) -{ - uint64_t mc_umc_status; - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - - /* check the MCUMC_STATUS */ - mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status; - if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) && - (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 || - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 || - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 || - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 || - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1)) - *error_count += 1; -} - -static void umc_v6_7_ecc_info_query_ras_error_count(struct amdgpu_device *adev, - void *ras_error_status) -{ - struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; - - uint32_t umc_inst = 0; - uint32_t ch_inst = 0; - uint32_t umc_reg_offset = 0; - uint32_t channel_index = 0; - - /*TODO: driver needs to toggle DF Cstate to ensure - * safe access of UMC registers. Will add the protection */ - LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) { - umc_reg_offset = get_umc_v6_7_reg_offset(adev, - umc_inst, - ch_inst); - channel_index = get_umc_v6_7_channel_index(adev, - umc_inst, - ch_inst); - umc_v6_7_ecc_info_query_correctable_error_count(adev, - channel_index, - &(err_data->ce_count)); - umc_v6_7_ecc_info_querry_uncorrectable_error_count(adev, - channel_index, - &(err_data->ue_count)); - } -} - -static void umc_v6_7_ecc_info_query_error_address(struct amdgpu_device *adev, - struct ras_err_data *err_data, - uint32_t umc_reg_offset, - uint32_t ch_inst, - uint32_t umc_inst) -{ - uint64_t mc_umc_status, err_addr, retired_page; - struct eeprom_table_record *err_rec; - uint32_t channel_index; - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - - channel_index = - adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst]; - - mc_umc_status = ras->umc_ecc.ecc[channel_index].mca_umc_status; - - if (mc_umc_status == 0) - return; - - if (!err_data->err_addr) - return; - - err_rec = &err_data->err_addr[err_data->err_addr_cnt]; - - /* calculate error address if ue/ce error is detected */ - if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 && - (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 || - REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) { - - err_addr = ras->umc_ecc.ecc[channel_index].mca_umc_addr; - err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr); - - /* translate umc channel address to soc pa, 3 parts are included */ - retired_page = ADDR_OF_8KB_BLOCK(err_addr) | - ADDR_OF_256B_BLOCK(channel_index) | - OFFSET_IN_256B_BLOCK(err_addr); - - /* we only save ue error information currently, ce is skipped */ - if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) - == 1) { - err_rec->address = err_addr; - /* page frame address is saved */ - err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT; - err_rec->ts = (uint64_t)ktime_get_real_seconds(); - err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE; - err_rec->cu = 0; - err_rec->mem_channel = channel_index; - err_rec->mcumc_id = umc_inst; - - err_data->err_addr_cnt++; - } - } -} - -static void umc_v6_7_ecc_info_query_ras_error_address(struct amdgpu_device *adev, - void *ras_error_status) -{ - struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status; - - uint32_t umc_inst = 0; - uint32_t ch_inst = 0; - uint32_t umc_reg_offset = 0; - - /*TODO: driver needs to toggle DF Cstate to ensure - * safe access of UMC resgisters. Will add the protection - * when firmware interface is ready */ - LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) { - umc_reg_offset = get_umc_v6_7_reg_offset(adev, - umc_inst, - ch_inst); - umc_v6_7_ecc_info_query_error_address(adev, - err_data, - umc_reg_offset, - ch_inst, - umc_inst); - } -} - static void umc_v6_7_query_correctable_error_count(struct amdgpu_device *adev, uint32_t umc_reg_offset, unsigned long *error_count) @@ -447,45 +288,9 @@ static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev, } } -static uint32_t umc_v6_7_query_ras_poison_mode_per_channel( - struct amdgpu_device *adev, - uint32_t umc_reg_offset) -{ - uint32_t ecc_ctrl_addr, ecc_ctrl; - - ecc_ctrl_addr = - SOC15_REG_OFFSET(UMC, 0, regUMCCH0_0_EccCtrl); - ecc_ctrl = RREG32_PCIE((ecc_ctrl_addr + - umc_reg_offset) * 4); - - return REG_GET_FIELD(ecc_ctrl, UMCCH0_0_EccCtrl, UCFatalEn); -} - -static bool umc_v6_7_query_ras_poison_mode(struct amdgpu_device *adev) -{ - uint32_t umc_inst = 0; - uint32_t ch_inst = 0; - uint32_t umc_reg_offset = 0; - - LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) { - umc_reg_offset = get_umc_v6_7_reg_offset(adev, - umc_inst, - ch_inst); - /* Enabling fatal error in one channel will be considered - as fatal error mode */ - if (umc_v6_7_query_ras_poison_mode_per_channel(adev, umc_reg_offset)) - return false; - } - - return true; -} - const struct amdgpu_umc_ras_funcs umc_v6_7_ras_funcs = { .ras_late_init = amdgpu_umc_ras_late_init, .ras_fini = amdgpu_umc_ras_fini, .query_ras_error_count = umc_v6_7_query_ras_error_count, .query_ras_error_address = umc_v6_7_query_ras_error_address, - .query_ras_poison_mode = umc_v6_7_query_ras_poison_mode, - .ecc_info_query_ras_error_count = umc_v6_7_ecc_info_query_ras_error_count, - .ecc_info_query_ras_error_address = umc_v6_7_ecc_info_query_ras_error_address, }; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 2d558c2f41..72f8762907 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -332,9 +332,15 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; - struct amdgpu_bo *bo = ring->adev->uvd.ib_bo; + struct amdgpu_bo *bo = NULL; long r; + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + r = uvd_v6_0_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; @@ -351,6 +357,9 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unpin(bo); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index b483f03b45..1fd9ca21a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -338,9 +338,15 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; - struct amdgpu_bo *bo = ring->adev->uvd.ib_bo; + struct amdgpu_bo *bo = NULL; long r; + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + r = uvd_v7_0_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; @@ -357,6 +363,9 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unpin(bo); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index 67eb01fef7..98952fd387 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -431,12 +431,10 @@ static int vce_v2_0_sw_init(void *handle) return r; for (i = 0; i < adev->vce.num_rings; i++) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vce_get_ring_prio(i); - ring = &adev->vce.ring[i]; sprintf(ring->name, "vce%d", i); r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 142e291983..8fb5df7181 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -440,12 +440,10 @@ static int vce_v3_0_sw_init(void *handle) return r; for (i = 0; i < adev->vce.num_rings; i++) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vce_get_ring_prio(i); - ring = &adev->vce.ring[i]; sprintf(ring->name, "vce%d", i); r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index d1fc4e0b82..70b8c88d30 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -463,8 +463,6 @@ static int vce_v4_0_sw_init(void *handle) } for (i = 0; i < adev->vce.num_rings; i++) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vce_get_ring_prio(i); - ring = &adev->vce.ring[i]; sprintf(ring->name, "vce%d", i); if (amdgpu_sriov_vf(adev)) { @@ -480,7 +478,7 @@ static int vce_v4_0_sw_init(void *handle) ring->doorbell_index = adev->doorbell_index.uvd_vce.vce_ring2_3 * 2 + 1; } r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } @@ -565,7 +563,7 @@ static int vce_v4_0_suspend(void *handle) if (adev->vce.vcpu_bo == NULL) return 0; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); void *ptr = adev->vce.cpu_addr; @@ -615,7 +613,7 @@ static int vce_v4_0_resume(void *handle) if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); void *ptr = adev->vce.cpu_addr; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 3799226def..462008d506 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -66,6 +66,7 @@ static int vcn_v1_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + adev->vcn.num_vcn_inst = 1; adev->vcn.num_enc_rings = 2; vcn_v1_0_set_dec_ring_funcs(adev); @@ -111,7 +112,15 @@ static int vcn_v1_0_sw_init(void *handle) /* Override the work func */ adev->vcn.idle_work.work.func = vcn_v1_0_idle_work_handler; - amdgpu_vcn_setup_ucode(adev); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + const struct common_firmware_header *hdr; + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); + } r = amdgpu_vcn_resume(adev); if (r) @@ -136,12 +145,10 @@ static int vcn_v1_0_sw_init(void *handle) SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP); for (i = 0; i < adev->vcn.num_enc_rings; ++i) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i); - ring = &adev->vcn.inst->ring_enc[i]; sprintf(ring->name, "vcn_enc%d", i); r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c index 313fc1b539..c405075a57 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c @@ -69,6 +69,7 @@ static int vcn_v2_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + adev->vcn.num_vcn_inst = 1; if (amdgpu_sriov_vf(adev)) adev->vcn.num_enc_rings = 1; else @@ -115,7 +116,15 @@ static int vcn_v2_0_sw_init(void *handle) if (r) return r; - amdgpu_vcn_setup_ucode(adev); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + const struct common_firmware_header *hdr; + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); + } r = amdgpu_vcn_resume(adev); if (r) @@ -151,8 +160,6 @@ static int vcn_v2_0_sw_init(void *handle) adev->vcn.inst->external.nop = SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP); for (i = 0; i < adev->vcn.num_enc_rings; ++i) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i); - ring = &adev->vcn.inst->ring_enc[i]; ring->use_doorbell = true; if (!amdgpu_sriov_vf(adev)) @@ -161,7 +168,7 @@ static int vcn_v2_0_sw_init(void *handle) ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + i; sprintf(ring->name, "vcn_enc%d", i); r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } @@ -190,7 +197,7 @@ static int vcn_v2_0_sw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { fw_shared->present_flag_0 = 0; drm_dev_exit(idx); } @@ -1876,14 +1883,15 @@ static int vcn_v2_0_start_sriov(struct amdgpu_device *adev) /* mc resume*/ if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + tmp = AMDGPU_UCODE_ID_VCN; MMSCH_V2_0_INSERT_DIRECT_WT( SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), - adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo); + adev->firmware.ucode[tmp].tmr_mc_addr_lo); MMSCH_V2_0_INSERT_DIRECT_WT( SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), - adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi); + adev->firmware.ucode[tmp].tmr_mc_addr_hi); offset = 0; } else { MMSCH_V2_0_INSERT_DIRECT_WT( diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index 44fc4c2184..a0956d8623 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -83,7 +83,7 @@ static int vcn_v2_5_early_init(void *handle) } else { u32 harvest; int i; - + adev->vcn.num_vcn_inst = VCN25_MAX_HW_INSTANCES_ARCTURUS; for (i = 0; i < adev->vcn.num_vcn_inst; i++) { harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING); if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK) @@ -139,7 +139,22 @@ static int vcn_v2_5_sw_init(void *handle) if (r) return r; - amdgpu_vcn_setup_ucode(adev); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + const struct common_firmware_header *hdr; + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + + if (adev->vcn.num_vcn_inst == VCN25_MAX_HW_INSTANCES_ARCTURUS) { + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + } + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); + } r = amdgpu_vcn_resume(adev); if (r) @@ -180,8 +195,6 @@ static int vcn_v2_5_sw_init(void *handle) return r; for (i = 0; i < adev->vcn.num_enc_rings; ++i) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i); - ring = &adev->vcn.inst[j].ring_enc[i]; ring->use_doorbell = true; @@ -191,7 +204,7 @@ static int vcn_v2_5_sw_init(void *handle) sprintf(ring->name, "vcn_enc_%d.%d", j, i); r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0, - hw_prio, NULL); + AMDGPU_RING_PRIO_DEFAULT, NULL); if (r) return r; } @@ -225,7 +238,7 @@ static int vcn_v2_5_sw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; volatile struct amdgpu_fw_shared *fw_shared; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { for (i = 0; i < adev->vcn.num_vcn_inst; i++) { if (adev->vcn.harvest_config & (1 << i)) continue; @@ -1705,7 +1718,7 @@ static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev) for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { if (adev->vcn.harvest_config & (1 << i)) continue; - if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0)) + if (adev->asic_type == CHIP_ARCTURUS) adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs; else /* CHIP_ALDEBARAN */ adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_6_dec_ring_vm_funcs; @@ -1722,7 +1735,7 @@ static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev) if (adev->vcn.harvest_config & (1 << j)) continue; for (i = 0; i < adev->vcn.num_enc_rings; ++i) { - if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0)) + if (adev->asic_type == CHIP_ARCTURUS) adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs; else /* CHIP_ALDEBARAN */ adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_6_enc_ring_vm_funcs; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index da11ceba06..3d18aab88b 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -60,6 +60,11 @@ static int amdgpu_ih_clientid_vcns[] = { SOC15_IH_CLIENTID_VCN1 }; +static int amdgpu_ucode_id_vcns[] = { + AMDGPU_UCODE_ID_VCN, + AMDGPU_UCODE_ID_VCN1 +}; + static int vcn_v3_0_start_sriov(struct amdgpu_device *adev); static void vcn_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev); static void vcn_v3_0_set_enc_ring_funcs(struct amdgpu_device *adev); @@ -82,6 +87,7 @@ static void vcn_v3_0_enc_ring_set_wptr(struct amdgpu_ring *ring); static int vcn_v3_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int i; if (amdgpu_sriov_vf(adev)) { adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID; @@ -89,12 +95,24 @@ static int vcn_v3_0_early_init(void *handle) adev->vcn.num_enc_rings = 1; } else { - if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 | - AMDGPU_VCN_HARVEST_VCN1)) - /* both instances are harvested, disable the block */ - return -ENOENT; + if (adev->asic_type == CHIP_SIENNA_CICHLID) { + u32 harvest; - if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(3, 0, 33)) + adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID; + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING); + if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK) + adev->vcn.harvest_config |= 1 << i; + } + + if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 | + AMDGPU_VCN_HARVEST_VCN1)) + /* both instances are harvested, disable the block */ + return -ENOENT; + } else + adev->vcn.num_vcn_inst = 1; + + if (adev->asic_type == CHIP_BEIGE_GOBY) adev->vcn.num_enc_rings = 0; else adev->vcn.num_enc_rings = 2; @@ -125,7 +143,22 @@ static int vcn_v3_0_sw_init(void *handle) if (r) return r; - amdgpu_vcn_setup_ucode(adev); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + const struct common_firmware_header *hdr; + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + + if (adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) { + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1; + adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE); + } + dev_info(adev->dev, "Will use PSP to load VCN firmware\n"); + } r = amdgpu_vcn_resume(adev); if (r) @@ -191,8 +224,6 @@ static int vcn_v3_0_sw_init(void *handle) return r; for (j = 0; j < adev->vcn.num_enc_rings; ++j) { - enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(j); - /* VCN ENC TRAP */ r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[i], j + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[i].irq); @@ -208,7 +239,8 @@ static int vcn_v3_0_sw_init(void *handle) } sprintf(ring->name, "vcn_enc_%d.%d", i, j); r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0, - hw_prio, &adev->vcn.inst[i].sched_score); + AMDGPU_RING_PRIO_DEFAULT, + &adev->vcn.inst[i].sched_score); if (r) return r; } @@ -243,7 +275,7 @@ static int vcn_v3_0_sw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int i, r, idx; - if (drm_dev_enter(adev_to_drm(adev), &idx)) { + if (drm_dev_enter(&adev->ddev, &idx)) { for (i = 0; i < adev->vcn.num_vcn_inst; i++) { volatile struct amdgpu_fw_shared *fw_shared; @@ -1239,7 +1271,7 @@ static int vcn_v3_0_start(struct amdgpu_device *adev) fw_shared->rb.wptr = lower_32_bits(ring->wptr); fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); - if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(3, 0, 33)) { + if (adev->asic_type != CHIP_BEIGE_GOBY) { fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET); ring = &adev->vcn.inst[i].ring_enc[0]; WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); @@ -1273,6 +1305,7 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev) uint32_t param, resp, expected; uint32_t offset, cache_size; uint32_t tmp, timeout; + uint32_t id; struct amdgpu_mm_table *table = &adev->virt.mm_table; uint32_t *table_loc; @@ -1316,12 +1349,13 @@ static int vcn_v3_0_start_sriov(struct amdgpu_device *adev) cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + id = amdgpu_ucode_id_vcns[i]; MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), - adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo); + adev->firmware.ucode[id].tmr_mc_addr_lo); MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), - adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi); + adev->firmware.ucode[id].tmr_mc_addr_hi); offset = 0; MMSCH_V3_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), @@ -1609,7 +1643,7 @@ static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev, UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); - if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(3, 0, 33)) { + if (adev->asic_type != CHIP_BEIGE_GOBY) { /* Restore */ fw_shared = adev->vcn.inst[inst_idx].fw_shared_cpu_addr; fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET); diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 3070466f54..a9ca698800 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -640,7 +640,6 @@ const struct amd_ip_funcs vega10_ih_ip_funcs = { static const struct amdgpu_ih_funcs vega10_ih_funcs = { .get_wptr = vega10_ih_get_wptr, .decode_iv = amdgpu_ih_decode_iv_helper, - .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper, .set_rptr = vega10_ih_set_rptr }; diff --git a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c index 3b4eb82859..f51dfc38ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega20_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega20_ih.c @@ -688,7 +688,6 @@ const struct amd_ip_funcs vega20_ih_ip_funcs = { static const struct amdgpu_ih_funcs vega20_ih_funcs = { .get_wptr = vega20_ih_get_wptr, .decode_iv = amdgpu_ih_decode_iv_helper, - .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper, .set_rptr = vega20_ih_set_rptr }; diff --git a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c index d60576ce10..f6233019f0 100644 --- a/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c @@ -43,15 +43,15 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev, */ if ((ihre->source_id == CIK_INTSRC_GFX_PAGE_INV_FAULT || ihre->source_id == CIK_INTSRC_GFX_MEM_PROT_FAULT) && - dev->adev->asic_type == CHIP_HAWAII) { + dev->device_info->asic_family == CHIP_HAWAII) { struct cik_ih_ring_entry *tmp_ihre = (struct cik_ih_ring_entry *)patched_ihre; *patched_flag = true; *tmp_ihre = *ihre; - vmid = f2g->read_vmid_from_vmfault_reg(dev->adev); - ret = f2g->get_atc_vmid_pasid_mapping_info(dev->adev, vmid, &pasid); + vmid = f2g->read_vmid_from_vmfault_reg(dev->kgd); + ret = f2g->get_atc_vmid_pasid_mapping_info(dev->kgd, vmid, &pasid); tmp_ihre->ring_id &= 0x000000ff; tmp_ihre->ring_id |= vmid << 8; @@ -113,7 +113,7 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev, kfd_process_vm_fault(dev->dqm, pasid); memset(&info, 0, sizeof(info)); - amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->adev, &info); + amdgpu_amdkfd_gpuvm_get_vm_fault_info(dev->kgd, &info); if (!info.page_addr && !info.status) return; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 4bfc0c8ab7..86afd37b09 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -321,7 +321,7 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, /* Return gpu_id as doorbell offset for mmap usage */ args->doorbell_offset = KFD_MMAP_TYPE_DOORBELL; args->doorbell_offset |= KFD_MMAP_GPU_ID(args->gpu_id); - if (KFD_IS_SOC15(dev)) + if (KFD_IS_SOC15(dev->device_info->asic_family)) /* On SOC15 ASICs, include the doorbell offset within the * process doorbell frame, which is 2 pages. */ @@ -405,7 +405,7 @@ static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, mutex_lock(&p->mutex); - retval = pqm_update_queue_properties(&p->pqm, args->queue_id, &properties); + retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); mutex_unlock(&p->mutex); @@ -418,7 +418,7 @@ static int kfd_ioctl_set_cu_mask(struct file *filp, struct kfd_process *p, int retval; const int max_num_cus = 1024; struct kfd_ioctl_set_cu_mask_args *args = data; - struct mqd_update_info minfo = {0}; + struct queue_properties properties; uint32_t __user *cu_mask_ptr = (uint32_t __user *)args->cu_mask_ptr; size_t cu_mask_size = sizeof(uint32_t) * (args->num_cu_mask / 32); @@ -428,8 +428,8 @@ static int kfd_ioctl_set_cu_mask(struct file *filp, struct kfd_process *p, return -EINVAL; } - minfo.cu_mask.count = args->num_cu_mask; - if (minfo.cu_mask.count == 0) { + properties.cu_mask_count = args->num_cu_mask; + if (properties.cu_mask_count == 0) { pr_debug("CU mask cannot be 0"); return -EINVAL; } @@ -438,33 +438,32 @@ static int kfd_ioctl_set_cu_mask(struct file *filp, struct kfd_process *p, * limit of max_num_cus bits. We can then just drop any CU mask bits * past max_num_cus bits and just use the first max_num_cus bits. */ - if (minfo.cu_mask.count > max_num_cus) { + if (properties.cu_mask_count > max_num_cus) { pr_debug("CU mask cannot be greater than 1024 bits"); - minfo.cu_mask.count = max_num_cus; + properties.cu_mask_count = max_num_cus; cu_mask_size = sizeof(uint32_t) * (max_num_cus/32); } - minfo.cu_mask.ptr = kzalloc(cu_mask_size, GFP_KERNEL); - if (!minfo.cu_mask.ptr) + properties.cu_mask = kzalloc(cu_mask_size, GFP_KERNEL); + if (!properties.cu_mask) return -ENOMEM; - retval = copy_from_user(minfo.cu_mask.ptr, cu_mask_ptr, cu_mask_size); + retval = copy_from_user(properties.cu_mask, cu_mask_ptr, cu_mask_size); if (retval) { pr_debug("Could not copy CU mask from userspace"); - retval = -EFAULT; - goto out; + kfree(properties.cu_mask); + return -EFAULT; } - minfo.update_flag = UPDATE_FLAG_CU_MASK; - mutex_lock(&p->mutex); - retval = pqm_update_mqd(&p->pqm, args->queue_id, &minfo); + retval = pqm_set_cu_mask(&p->pqm, args->queue_id, &properties); mutex_unlock(&p->mutex); -out: - kfree(minfo.cu_mask.ptr); + if (retval) + kfree(properties.cu_mask); + return retval; } @@ -580,7 +579,7 @@ static int kfd_ioctl_dbg_register(struct file *filep, if (!dev) return -EINVAL; - if (dev->adev->asic_type == CHIP_CARRIZO) { + if (dev->device_info->asic_family == CHIP_CARRIZO) { pr_debug("kfd_ioctl_dbg_register not supported on CZ\n"); return -EINVAL; } @@ -631,7 +630,7 @@ static int kfd_ioctl_dbg_unregister(struct file *filep, if (!dev || !dev->dbgmgr) return -EINVAL; - if (dev->adev->asic_type == CHIP_CARRIZO) { + if (dev->device_info->asic_family == CHIP_CARRIZO) { pr_debug("kfd_ioctl_dbg_unregister not supported on CZ\n"); return -EINVAL; } @@ -676,7 +675,7 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep, if (!dev) return -EINVAL; - if (dev->adev->asic_type == CHIP_CARRIZO) { + if (dev->device_info->asic_family == CHIP_CARRIZO) { pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n"); return -EINVAL; } @@ -784,7 +783,7 @@ static int kfd_ioctl_dbg_wave_control(struct file *filep, if (!dev) return -EINVAL; - if (dev->adev->asic_type == CHIP_CARRIZO) { + if (dev->device_info->asic_family == CHIP_CARRIZO) { pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n"); return -EINVAL; } @@ -851,7 +850,7 @@ static int kfd_ioctl_get_clock_counters(struct file *filep, dev = kfd_device_by_id(args->gpu_id); if (dev) /* Reading GPU clock counter from KGD */ - args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->adev); + args->gpu_clock_counter = amdgpu_amdkfd_get_gpu_clock_counter(dev->kgd); else /* Node without GPU resource */ args->gpu_clock_counter = 0; @@ -1012,6 +1011,11 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p, void *mem, *kern_addr; uint64_t size; + if (p->signal_page) { + pr_err("Event page is already set\n"); + return -EINVAL; + } + kfd = kfd_device_by_id(GET_GPU_ID(args->event_page_offset)); if (!kfd) { pr_err("Getting device by id failed in %s\n", __func__); @@ -1019,13 +1023,6 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p, } mutex_lock(&p->mutex); - - if (p->signal_page) { - pr_err("Event page is already set\n"); - err = -EINVAL; - goto out_unlock; - } - pdd = kfd_bind_process_to_device(kfd, p); if (IS_ERR(pdd)) { err = PTR_ERR(pdd); @@ -1040,24 +1037,20 @@ static int kfd_ioctl_create_event(struct file *filp, struct kfd_process *p, err = -EINVAL; goto out_unlock; } + mutex_unlock(&p->mutex); - err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->adev, + err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kfd->kgd, mem, &kern_addr, &size); if (err) { pr_err("Failed to map event page to kernel\n"); - goto out_unlock; + return err; } err = kfd_event_page_set(p, kern_addr, size); if (err) { pr_err("Failed to set event page\n"); - amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kfd->adev, mem); - goto out_unlock; + return err; } - - p->signal_handle = args->event_page_offset; - - mutex_unlock(&p->mutex); } err = kfd_event_create(filp, p, args->event_type, @@ -1137,7 +1130,7 @@ static int kfd_ioctl_set_scratch_backing_va(struct file *filep, if (dev->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS && pdd->qpd.vmid != 0 && dev->kfd2kgd->set_scratch_backing_va) dev->kfd2kgd->set_scratch_backing_va( - dev->adev, args->va_addr, pdd->qpd.vmid); + dev->kgd, args->va_addr, pdd->qpd.vmid); return 0; @@ -1158,7 +1151,7 @@ static int kfd_ioctl_get_tile_config(struct file *filep, if (!dev) return -EINVAL; - amdgpu_amdkfd_get_tile_config(dev->adev, &config); + amdgpu_amdkfd_get_tile_config(dev->kgd, &config); args->gb_addr_config = config.gb_addr_config; args->num_banks = config.num_banks; @@ -1244,7 +1237,7 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev) if (dev->use_iommu_v2) return false; - amdgpu_amdkfd_get_local_mem_info(dev->adev, &mem_info); + amdgpu_amdkfd_get_local_mem_info(dev->kgd, &mem_info); if (mem_info.local_mem_size_private == 0 && mem_info.local_mem_size_public > 0) return true; @@ -1266,23 +1259,6 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, if (args->size == 0) return -EINVAL; -#if IS_ENABLED(CONFIG_HSA_AMD_SVM) - /* Flush pending deferred work to avoid racing with deferred actions - * from previous memory map changes (e.g. munmap). - */ - svm_range_list_lock_and_flush_work(&p->svms, current->mm); - mutex_lock(&p->svms.lock); - mmap_write_unlock(current->mm); - if (interval_tree_iter_first(&p->svms.objects, - args->va_addr >> PAGE_SHIFT, - (args->va_addr + args->size - 1) >> PAGE_SHIFT)) { - pr_err("Address: 0x%llx already allocated by SVM\n", - args->va_addr); - mutex_unlock(&p->svms.lock); - return -EADDRINUSE; - } - mutex_unlock(&p->svms.lock); -#endif dev = kfd_device_by_id(args->gpu_id); if (!dev) return -EINVAL; @@ -1313,7 +1289,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, err = -EINVAL; goto err_unlock; } - offset = dev->adev->rmmio_remap.bus_addr; + offset = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); if (!offset) { err = -ENOMEM; goto err_unlock; @@ -1321,7 +1297,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, } err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( - dev->adev, args->va_addr, args->size, + dev->kgd, args->va_addr, args->size, pdd->drm_priv, (struct kgd_mem **) &mem, &offset, flags); @@ -1353,7 +1329,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, return 0; err_free: - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem, + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem, pdd->drm_priv, NULL); err_unlock: mutex_unlock(&p->mutex); @@ -1375,15 +1351,6 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep, return -EINVAL; mutex_lock(&p->mutex); - /* - * Safeguard to prevent user space from freeing signal BO. - * It will be freed at process termination. - */ - if (p->signal_handle && (p->signal_handle == args->handle)) { - pr_err("Free signal BO is not allowed\n"); - ret = -EPERM; - goto err_unlock; - } pdd = kfd_get_process_device_data(dev, p); if (!pdd) { @@ -1399,7 +1366,7 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep, goto err_unlock; } - ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, + ret = amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem, pdd->drm_priv, &size); /* If freeing the buffer failed, leave the handle in place for @@ -1484,7 +1451,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep, goto get_mem_obj_from_handle_failed; } err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu( - peer->adev, (struct kgd_mem *)mem, + peer->kgd, (struct kgd_mem *)mem, peer_pdd->drm_priv, &table_freed); if (err) { pr_err("Failed to map to gpu %d/%d\n", @@ -1496,7 +1463,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep, mutex_unlock(&p->mutex); - err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, (struct kgd_mem *) mem, true); + err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd, (struct kgd_mem *) mem, true); if (err) { pr_debug("Sync memory failed, wait interrupted by user signal\n"); goto sync_memory_failed; @@ -1593,7 +1560,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, goto get_mem_obj_from_handle_failed; } err = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( - peer->adev, (struct kgd_mem *)mem, peer_pdd->drm_priv); + peer->kgd, (struct kgd_mem *)mem, peer_pdd->drm_priv); if (err) { pr_err("Failed to unmap from gpu %d/%d\n", i, args->n_devices); @@ -1603,8 +1570,8 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, } mutex_unlock(&p->mutex); - if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2)) { - err = amdgpu_amdkfd_gpuvm_sync_memory(dev->adev, + if (dev->device_info->asic_family == CHIP_ALDEBARAN) { + err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd, (struct kgd_mem *) mem, true); if (err) { pr_debug("Sync memory failed, wait interrupted by user signal\n"); @@ -1680,7 +1647,7 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep, { struct kfd_ioctl_get_dmabuf_info_args *args = data; struct kfd_dev *dev = NULL; - struct amdgpu_device *dmabuf_adev; + struct kgd_dev *dma_buf_kgd; void *metadata_buffer = NULL; uint32_t flags; unsigned int i; @@ -1700,15 +1667,15 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep, } /* Get dmabuf info from KGD */ - r = amdgpu_amdkfd_get_dmabuf_info(dev->adev, args->dmabuf_fd, - &dmabuf_adev, &args->size, + r = amdgpu_amdkfd_get_dmabuf_info(dev->kgd, args->dmabuf_fd, + &dma_buf_kgd, &args->size, metadata_buffer, args->metadata_size, &args->metadata_size, &flags); if (r) goto exit; /* Reverse-lookup gpu_id from kgd pointer */ - dev = kfd_device_by_adev(dmabuf_adev); + dev = kfd_device_by_kgd(dma_buf_kgd); if (!dev) { r = -EINVAL; goto exit; @@ -1758,7 +1725,7 @@ static int kfd_ioctl_import_dmabuf(struct file *filep, goto err_unlock; } - r = amdgpu_amdkfd_gpuvm_import_dmabuf(dev->adev, dmabuf, + r = amdgpu_amdkfd_gpuvm_import_dmabuf(dev->kgd, dmabuf, args->va_addr, pdd->drm_priv, (struct kgd_mem **)&mem, &size, NULL); @@ -1779,7 +1746,7 @@ static int kfd_ioctl_import_dmabuf(struct file *filep, return 0; err_free: - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, (struct kgd_mem *)mem, + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem, pdd->drm_priv, NULL); err_unlock: mutex_unlock(&p->mutex); @@ -2066,7 +2033,7 @@ static int kfd_mmio_mmap(struct kfd_dev *dev, struct kfd_process *process, if (vma->vm_end - vma->vm_start != PAGE_SIZE) return -EINVAL; - address = dev->adev->rmmio_remap.bus_addr; + address = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 9624bbe8b5..c33d689f29 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -1343,7 +1343,7 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev, int ret; unsigned int num_cu_shared; - switch (kdev->adev->asic_type) { + switch (kdev->device_info->asic_family) { case CHIP_KAVERI: pcache_info = kaveri_cache_info; num_of_cache_types = ARRAY_SIZE(kaveri_cache_info); @@ -1380,71 +1380,67 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev, pcache_info = vegam_cache_info; num_of_cache_types = ARRAY_SIZE(vegam_cache_info); break; + case CHIP_VEGA10: + pcache_info = vega10_cache_info; + num_of_cache_types = ARRAY_SIZE(vega10_cache_info); + break; + case CHIP_VEGA12: + pcache_info = vega12_cache_info; + num_of_cache_types = ARRAY_SIZE(vega12_cache_info); + break; + case CHIP_VEGA20: + case CHIP_ARCTURUS: + pcache_info = vega20_cache_info; + num_of_cache_types = ARRAY_SIZE(vega20_cache_info); + break; + case CHIP_ALDEBARAN: + pcache_info = aldebaran_cache_info; + num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info); + break; + case CHIP_RAVEN: + pcache_info = raven_cache_info; + num_of_cache_types = ARRAY_SIZE(raven_cache_info); + break; + case CHIP_RENOIR: + pcache_info = renoir_cache_info; + num_of_cache_types = ARRAY_SIZE(renoir_cache_info); + break; + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_CYAN_SKILLFISH: + pcache_info = navi10_cache_info; + num_of_cache_types = ARRAY_SIZE(navi10_cache_info); + break; + case CHIP_NAVI14: + pcache_info = navi14_cache_info; + num_of_cache_types = ARRAY_SIZE(navi14_cache_info); + break; + case CHIP_SIENNA_CICHLID: + pcache_info = sienna_cichlid_cache_info; + num_of_cache_types = ARRAY_SIZE(sienna_cichlid_cache_info); + break; + case CHIP_NAVY_FLOUNDER: + pcache_info = navy_flounder_cache_info; + num_of_cache_types = ARRAY_SIZE(navy_flounder_cache_info); + break; + case CHIP_DIMGREY_CAVEFISH: + pcache_info = dimgrey_cavefish_cache_info; + num_of_cache_types = ARRAY_SIZE(dimgrey_cavefish_cache_info); + break; + case CHIP_VANGOGH: + pcache_info = vangogh_cache_info; + num_of_cache_types = ARRAY_SIZE(vangogh_cache_info); + break; + case CHIP_BEIGE_GOBY: + pcache_info = beige_goby_cache_info; + num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info); + break; + case CHIP_YELLOW_CARP: + pcache_info = yellow_carp_cache_info; + num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info); + break; default: - switch(KFD_GC_VERSION(kdev)) { - case IP_VERSION(9, 0, 1): - pcache_info = vega10_cache_info; - num_of_cache_types = ARRAY_SIZE(vega10_cache_info); - break; - case IP_VERSION(9, 2, 1): - pcache_info = vega12_cache_info; - num_of_cache_types = ARRAY_SIZE(vega12_cache_info); - break; - case IP_VERSION(9, 4, 0): - case IP_VERSION(9, 4, 1): - pcache_info = vega20_cache_info; - num_of_cache_types = ARRAY_SIZE(vega20_cache_info); - break; - case IP_VERSION(9, 4, 2): - pcache_info = aldebaran_cache_info; - num_of_cache_types = ARRAY_SIZE(aldebaran_cache_info); - break; - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): - pcache_info = raven_cache_info; - num_of_cache_types = ARRAY_SIZE(raven_cache_info); - break; - case IP_VERSION(9, 3, 0): - pcache_info = renoir_cache_info; - num_of_cache_types = ARRAY_SIZE(renoir_cache_info); - break; - case IP_VERSION(10, 1, 10): - case IP_VERSION(10, 1, 2): - case IP_VERSION(10, 1, 3): - pcache_info = navi10_cache_info; - num_of_cache_types = ARRAY_SIZE(navi10_cache_info); - break; - case IP_VERSION(10, 1, 1): - pcache_info = navi14_cache_info; - num_of_cache_types = ARRAY_SIZE(navi14_cache_info); - break; - case IP_VERSION(10, 3, 0): - pcache_info = sienna_cichlid_cache_info; - num_of_cache_types = ARRAY_SIZE(sienna_cichlid_cache_info); - break; - case IP_VERSION(10, 3, 2): - pcache_info = navy_flounder_cache_info; - num_of_cache_types = ARRAY_SIZE(navy_flounder_cache_info); - break; - case IP_VERSION(10, 3, 4): - pcache_info = dimgrey_cavefish_cache_info; - num_of_cache_types = ARRAY_SIZE(dimgrey_cavefish_cache_info); - break; - case IP_VERSION(10, 3, 1): - pcache_info = vangogh_cache_info; - num_of_cache_types = ARRAY_SIZE(vangogh_cache_info); - break; - case IP_VERSION(10, 3, 5): - pcache_info = beige_goby_cache_info; - num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info); - break; - case IP_VERSION(10, 3, 3): - pcache_info = yellow_carp_cache_info; - num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info); - break; - default: - return -EINVAL; - } + return -EINVAL; } *size_filled = 0; @@ -1970,6 +1966,8 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size, struct crat_subtype_iolink *sub_type_hdr, uint32_t proximity_domain) { + struct amdgpu_device *adev = (struct amdgpu_device *)kdev->kgd; + *avail_size -= sizeof(struct crat_subtype_iolink); if (*avail_size < 0) return -ENOMEM; @@ -1986,7 +1984,7 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size, /* Fill in IOLINK subtype. * TODO: Fill-in other fields of iolink subtype */ - if (kdev->adev->gmc.xgmi.connected_to_cpu) { + if (adev->gmc.xgmi.connected_to_cpu) { /* * with host gpu xgmi link, host can access gpu memory whether * or not pcie bar type is large, so always create bidirectional @@ -1995,19 +1993,19 @@ static int kfd_fill_gpu_direct_io_link_to_cpu(int *avail_size, sub_type_hdr->flags |= CRAT_IOLINK_FLAGS_BI_DIRECTIONAL; sub_type_hdr->io_interface_type = CRAT_IOLINK_TYPE_XGMI; sub_type_hdr->num_hops_xgmi = 1; - if (KFD_GC_VERSION(kdev) == IP_VERSION(9, 4, 2)) { + if (adev->asic_type == CHIP_ALDEBARAN) { sub_type_hdr->minimum_bandwidth_mbs = amdgpu_amdkfd_get_xgmi_bandwidth_mbytes( - kdev->adev, NULL, true); + kdev->kgd, NULL, true); sub_type_hdr->maximum_bandwidth_mbs = sub_type_hdr->minimum_bandwidth_mbs; } } else { sub_type_hdr->io_interface_type = CRAT_IOLINK_TYPE_PCIEXPRESS; sub_type_hdr->minimum_bandwidth_mbs = - amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->adev, true); + amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->kgd, true); sub_type_hdr->maximum_bandwidth_mbs = - amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->adev, false); + amdgpu_amdkfd_get_pcie_bandwidth_mbytes(kdev->kgd, false); } sub_type_hdr->proximity_domain_from = proximity_domain; @@ -2049,11 +2047,11 @@ static int kfd_fill_gpu_xgmi_link_to_gpu(int *avail_size, sub_type_hdr->proximity_domain_from = proximity_domain_from; sub_type_hdr->proximity_domain_to = proximity_domain_to; sub_type_hdr->num_hops_xgmi = - amdgpu_amdkfd_get_xgmi_hops_count(kdev->adev, peer_kdev->adev); + amdgpu_amdkfd_get_xgmi_hops_count(kdev->kgd, peer_kdev->kgd); sub_type_hdr->maximum_bandwidth_mbs = - amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->adev, peer_kdev->adev, false); + amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->kgd, peer_kdev->kgd, false); sub_type_hdr->minimum_bandwidth_mbs = sub_type_hdr->maximum_bandwidth_mbs ? - amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->adev, NULL, true) : 0; + amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(kdev->kgd, NULL, true) : 0; return 0; } @@ -2119,7 +2117,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, cu->flags |= CRAT_CU_FLAGS_GPU_PRESENT; cu->proximity_domain = proximity_domain; - amdgpu_amdkfd_get_cu_info(kdev->adev, &cu_info); + amdgpu_amdkfd_get_cu_info(kdev->kgd, &cu_info); cu->num_simd_per_cu = cu_info.simd_per_cu; cu->num_simd_cores = cu_info.simd_per_cu * cu_info.cu_active_number; cu->max_waves_simd = cu_info.max_waves_per_simd; @@ -2150,7 +2148,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, * report the total FB size (public+private) as a single * private heap. */ - amdgpu_amdkfd_get_local_mem_info(kdev->adev, &local_mem_info); + amdgpu_amdkfd_get_local_mem_info(kdev->kgd, &local_mem_info); sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + sub_type_hdr->length); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index 1e30717b52..159add0f5a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -41,7 +41,7 @@ static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev) { - dev->kfd2kgd->address_watch_disable(dev->adev); + dev->kfd2kgd->address_watch_disable(dev->kgd); } static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev, @@ -322,7 +322,7 @@ static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev, pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *"); pdd->dev->kfd2kgd->address_watch_execute( - dbgdev->dev->adev, + dbgdev->dev->kgd, i, cntl.u32All, addrHi.u32All, @@ -420,7 +420,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev, aw_reg_add_dword = dbgdev->dev->kfd2kgd->address_watch_get_offset( - dbgdev->dev->adev, + dbgdev->dev->kgd, i, ADDRESS_WATCH_REG_CNTL); @@ -431,7 +431,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev, aw_reg_add_dword = dbgdev->dev->kfd2kgd->address_watch_get_offset( - dbgdev->dev->adev, + dbgdev->dev->kgd, i, ADDRESS_WATCH_REG_ADDR_HI); @@ -441,7 +441,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev, aw_reg_add_dword = dbgdev->dev->kfd2kgd->address_watch_get_offset( - dbgdev->dev->adev, + dbgdev->dev->kgd, i, ADDRESS_WATCH_REG_ADDR_LO); @@ -457,7 +457,7 @@ static int dbgdev_address_watch_diq(struct kfd_dbgdev *dbgdev, aw_reg_add_dword = dbgdev->dev->kfd2kgd->address_watch_get_offset( - dbgdev->dev->adev, + dbgdev->dev->kgd, i, ADDRESS_WATCH_REG_CNTL); @@ -752,7 +752,7 @@ static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev, pr_debug("\t\t %30s\n", "* * * * * * * * * * * * * * * * * *"); - return dbgdev->dev->kfd2kgd->wave_control_execute(dbgdev->dev->adev, + return dbgdev->dev->kfd2kgd->wave_control_execute(dbgdev->dev->kgd, reg_gfx_index.u32All, reg_sq_cmd.u32All); } @@ -784,7 +784,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p) for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) { status = dev->kfd2kgd->get_atc_vmid_pasid_mapping_info - (dev->adev, vmid, &queried_pasid); + (dev->kgd, vmid, &queried_pasid); if (status && queried_pasid == p->pasid) { pr_debug("Killing wave fronts of vmid %d and pasid 0x%x\n", @@ -811,7 +811,7 @@ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p) /* for non DIQ we need to patch the VMID: */ reg_sq_cmd.bits.vm_id = vmid; - dev->kfd2kgd->wave_control_execute(dev->adev, + dev->kfd2kgd->wave_control_execute(dev->kgd, reg_gfx_index.u32All, reg_sq_cmd.u32All); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 2b65d0acae..88c483f699 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -32,7 +32,6 @@ #include "amdgpu_amdkfd.h" #include "kfd_smi_events.h" #include "kfd_migrate.h" -#include "amdgpu.h" #define MQD_SIZE_ALIGNED 768 @@ -53,310 +52,664 @@ extern const struct kfd2kgd_calls aldebaran_kfd2kgd; extern const struct kfd2kgd_calls gfx_v10_kfd2kgd; extern const struct kfd2kgd_calls gfx_v10_3_kfd2kgd; +static const struct kfd2kgd_calls *kfd2kgd_funcs[] = { +#ifdef KFD_SUPPORT_IOMMU_V2 +#ifdef CONFIG_DRM_AMDGPU_CIK + [CHIP_KAVERI] = &gfx_v7_kfd2kgd, +#endif + [CHIP_CARRIZO] = &gfx_v8_kfd2kgd, + [CHIP_RAVEN] = &gfx_v9_kfd2kgd, +#endif +#ifdef CONFIG_DRM_AMDGPU_CIK + [CHIP_HAWAII] = &gfx_v7_kfd2kgd, +#endif + [CHIP_TONGA] = &gfx_v8_kfd2kgd, + [CHIP_FIJI] = &gfx_v8_kfd2kgd, + [CHIP_POLARIS10] = &gfx_v8_kfd2kgd, + [CHIP_POLARIS11] = &gfx_v8_kfd2kgd, + [CHIP_POLARIS12] = &gfx_v8_kfd2kgd, + [CHIP_VEGAM] = &gfx_v8_kfd2kgd, + [CHIP_VEGA10] = &gfx_v9_kfd2kgd, + [CHIP_VEGA12] = &gfx_v9_kfd2kgd, + [CHIP_VEGA20] = &gfx_v9_kfd2kgd, + [CHIP_RENOIR] = &gfx_v9_kfd2kgd, + [CHIP_ARCTURUS] = &arcturus_kfd2kgd, + [CHIP_ALDEBARAN] = &aldebaran_kfd2kgd, + [CHIP_NAVI10] = &gfx_v10_kfd2kgd, + [CHIP_NAVI12] = &gfx_v10_kfd2kgd, + [CHIP_NAVI14] = &gfx_v10_kfd2kgd, + [CHIP_SIENNA_CICHLID] = &gfx_v10_3_kfd2kgd, + [CHIP_NAVY_FLOUNDER] = &gfx_v10_3_kfd2kgd, + [CHIP_VANGOGH] = &gfx_v10_3_kfd2kgd, + [CHIP_DIMGREY_CAVEFISH] = &gfx_v10_3_kfd2kgd, + [CHIP_BEIGE_GOBY] = &gfx_v10_3_kfd2kgd, + [CHIP_YELLOW_CARP] = &gfx_v10_3_kfd2kgd, + [CHIP_CYAN_SKILLFISH] = &gfx_v10_kfd2kgd, +}; + +#ifdef KFD_SUPPORT_IOMMU_V2 +static const struct kfd_device_info kaveri_device_info = { + .asic_family = CHIP_KAVERI, + .asic_name = "kaveri", + .gfx_target_version = 70000, + .max_pasid_bits = 16, + /* max num of queues for KV.TODO should be a dynamic value */ + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = false, + .needs_iommu_device = true, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info carrizo_device_info = { + .asic_family = CHIP_CARRIZO, + .asic_name = "carrizo", + .gfx_target_version = 80001, + .max_pasid_bits = 16, + /* max num of queues for CZ.TODO should be a dynamic value */ + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = true, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; +#endif + +static const struct kfd_device_info raven_device_info = { + .asic_family = CHIP_RAVEN, + .asic_name = "raven", + .gfx_target_version = 90002, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = true, + .needs_pci_atomics = true, + .num_sdma_engines = 1, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info hawaii_device_info = { + .asic_family = CHIP_HAWAII, + .asic_name = "hawaii", + .gfx_target_version = 70001, + .max_pasid_bits = 16, + /* max num of queues for KV.TODO should be a dynamic value */ + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = false, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info tonga_device_info = { + .asic_family = CHIP_TONGA, + .asic_name = "tonga", + .gfx_target_version = 80002, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = false, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info fiji_device_info = { + .asic_family = CHIP_FIJI, + .asic_name = "fiji", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info fiji_vf_device_info = { + .asic_family = CHIP_FIJI, + .asic_name = "fiji", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + + +static const struct kfd_device_info polaris10_device_info = { + .asic_family = CHIP_POLARIS10, + .asic_name = "polaris10", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info polaris10_vf_device_info = { + .asic_family = CHIP_POLARIS10, + .asic_name = "polaris10", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info polaris11_device_info = { + .asic_family = CHIP_POLARIS11, + .asic_name = "polaris11", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info polaris12_device_info = { + .asic_family = CHIP_POLARIS12, + .asic_name = "polaris12", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info vegam_device_info = { + .asic_family = CHIP_VEGAM, + .asic_name = "vegam", + .gfx_target_version = 80003, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 4, + .ih_ring_entry_size = 4 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_cik, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info vega10_device_info = { + .asic_family = CHIP_VEGA10, + .asic_name = "vega10", + .gfx_target_version = 90000, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info vega10_vf_device_info = { + .asic_family = CHIP_VEGA10, + .asic_name = "vega10", + .gfx_target_version = 90000, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info vega12_device_info = { + .asic_family = CHIP_VEGA12, + .asic_name = "vega12", + .gfx_target_version = 90004, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info vega20_device_info = { + .asic_family = CHIP_VEGA20, + .asic_name = "vega20", + .gfx_target_version = 90006, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info arcturus_device_info = { + .asic_family = CHIP_ARCTURUS, + .asic_name = "arcturus", + .gfx_target_version = 90008, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 6, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info aldebaran_device_info = { + .asic_family = CHIP_ALDEBARAN, + .asic_name = "aldebaran", + .gfx_target_version = 90010, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 3, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info renoir_device_info = { + .asic_family = CHIP_RENOIR, + .asic_name = "renoir", + .gfx_target_version = 90002, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, + .needs_iommu_device = false, + .needs_pci_atomics = false, + .num_sdma_engines = 1, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info navi10_device_info = { + .asic_family = CHIP_NAVI10, + .asic_name = "navi10", + .gfx_target_version = 100100, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 145, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info navi12_device_info = { + .asic_family = CHIP_NAVI12, + .asic_name = "navi12", + .gfx_target_version = 100101, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 145, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info navi14_device_info = { + .asic_family = CHIP_NAVI14, + .asic_name = "navi14", + .gfx_target_version = 100102, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 145, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info sienna_cichlid_device_info = { + .asic_family = CHIP_SIENNA_CICHLID, + .asic_name = "sienna_cichlid", + .gfx_target_version = 100300, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 4, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info navy_flounder_device_info = { + .asic_family = CHIP_NAVY_FLOUNDER, + .asic_name = "navy_flounder", + .gfx_target_version = 100301, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info vangogh_device_info = { + .asic_family = CHIP_VANGOGH, + .asic_name = "vangogh", + .gfx_target_version = 100303, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 1, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info dimgrey_cavefish_device_info = { + .asic_family = CHIP_DIMGREY_CAVEFISH, + .asic_name = "dimgrey_cavefish", + .gfx_target_version = 100302, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info beige_goby_device_info = { + .asic_family = CHIP_BEIGE_GOBY, + .asic_name = "beige_goby", + .gfx_target_version = 100304, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 1, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +static const struct kfd_device_info yellow_carp_device_info = { + .asic_family = CHIP_YELLOW_CARP, + .asic_name = "yellow_carp", + .gfx_target_version = 100305, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .no_atomic_fw_version = 92, + .num_sdma_engines = 1, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 2, +}; + +static const struct kfd_device_info cyan_skillfish_device_info = { + .asic_family = CHIP_CYAN_SKILLFISH, + .asic_name = "cyan_skillfish", + .gfx_target_version = 100103, + .max_pasid_bits = 16, + .max_no_of_hqd = 24, + .doorbell_size = 8, + .ih_ring_entry_size = 8 * sizeof(uint32_t), + .event_interrupt_class = &event_interrupt_class_v9, + .num_of_watch_points = 4, + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .needs_iommu_device = false, + .supports_cwsr = true, + .needs_pci_atomics = true, + .num_sdma_engines = 2, + .num_xgmi_sdma_engines = 0, + .num_sdma_queues_per_engine = 8, +}; + +/* For each entry, [0] is regular and [1] is virtualisation device. */ +static const struct kfd_device_info *kfd_supported_devices[][2] = { +#ifdef KFD_SUPPORT_IOMMU_V2 + [CHIP_KAVERI] = {&kaveri_device_info, NULL}, + [CHIP_CARRIZO] = {&carrizo_device_info, NULL}, +#endif + [CHIP_RAVEN] = {&raven_device_info, NULL}, + [CHIP_HAWAII] = {&hawaii_device_info, NULL}, + [CHIP_TONGA] = {&tonga_device_info, NULL}, + [CHIP_FIJI] = {&fiji_device_info, &fiji_vf_device_info}, + [CHIP_POLARIS10] = {&polaris10_device_info, &polaris10_vf_device_info}, + [CHIP_POLARIS11] = {&polaris11_device_info, NULL}, + [CHIP_POLARIS12] = {&polaris12_device_info, NULL}, + [CHIP_VEGAM] = {&vegam_device_info, NULL}, + [CHIP_VEGA10] = {&vega10_device_info, &vega10_vf_device_info}, + [CHIP_VEGA12] = {&vega12_device_info, NULL}, + [CHIP_VEGA20] = {&vega20_device_info, NULL}, + [CHIP_RENOIR] = {&renoir_device_info, NULL}, + [CHIP_ARCTURUS] = {&arcturus_device_info, &arcturus_device_info}, + [CHIP_ALDEBARAN] = {&aldebaran_device_info, &aldebaran_device_info}, + [CHIP_NAVI10] = {&navi10_device_info, NULL}, + [CHIP_NAVI12] = {&navi12_device_info, &navi12_device_info}, + [CHIP_NAVI14] = {&navi14_device_info, NULL}, + [CHIP_SIENNA_CICHLID] = {&sienna_cichlid_device_info, &sienna_cichlid_device_info}, + [CHIP_NAVY_FLOUNDER] = {&navy_flounder_device_info, &navy_flounder_device_info}, + [CHIP_VANGOGH] = {&vangogh_device_info, NULL}, + [CHIP_DIMGREY_CAVEFISH] = {&dimgrey_cavefish_device_info, &dimgrey_cavefish_device_info}, + [CHIP_BEIGE_GOBY] = {&beige_goby_device_info, &beige_goby_device_info}, + [CHIP_YELLOW_CARP] = {&yellow_carp_device_info, NULL}, + [CHIP_CYAN_SKILLFISH] = {&cyan_skillfish_device_info, NULL}, +}; + static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, unsigned int chunk_size); static void kfd_gtt_sa_fini(struct kfd_dev *kfd); static int kfd_resume(struct kfd_dev *kfd); -static void kfd_device_info_set_sdma_queue_num(struct kfd_dev *kfd) +struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, + struct pci_dev *pdev, unsigned int asic_type, bool vf) { - uint32_t sdma_version = kfd->adev->ip_versions[SDMA0_HWIP][0]; + struct kfd_dev *kfd; + const struct kfd_device_info *device_info; + const struct kfd2kgd_calls *f2g; - switch (sdma_version) { - case IP_VERSION(4, 0, 0):/* VEGA10 */ - case IP_VERSION(4, 0, 1):/* VEGA12 */ - case IP_VERSION(4, 1, 0):/* RAVEN */ - case IP_VERSION(4, 1, 1):/* RAVEN */ - case IP_VERSION(4, 1, 2):/* RENOIR */ - case IP_VERSION(5, 2, 1):/* VANGOGH */ - case IP_VERSION(5, 2, 3):/* YELLOW_CARP */ - kfd->device_info.num_sdma_queues_per_engine = 2; - break; - case IP_VERSION(4, 2, 0):/* VEGA20 */ - case IP_VERSION(4, 2, 2):/* ARCTURUS */ - case IP_VERSION(4, 4, 0):/* ALDEBARAN */ - case IP_VERSION(5, 0, 0):/* NAVI10 */ - case IP_VERSION(5, 0, 1):/* CYAN_SKILLFISH */ - case IP_VERSION(5, 0, 2):/* NAVI14 */ - case IP_VERSION(5, 0, 5):/* NAVI12 */ - case IP_VERSION(5, 2, 0):/* SIENNA_CICHLID */ - case IP_VERSION(5, 2, 2):/* NAVY_FLOUNDER */ - case IP_VERSION(5, 2, 4):/* DIMGREY_CAVEFISH */ - case IP_VERSION(5, 2, 5):/* BEIGE_GOBY */ - kfd->device_info.num_sdma_queues_per_engine = 8; - break; - default: - dev_warn(kfd_device, - "Default sdma queue per engine(8) is set due to " - "mismatch of sdma ip block(SDMA_HWIP:0x%x).\n", - sdma_version); - kfd->device_info.num_sdma_queues_per_engine = 8; - } -} - -static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd) -{ - uint32_t gc_version = KFD_GC_VERSION(kfd); - - switch (gc_version) { - case IP_VERSION(9, 0, 1): /* VEGA10 */ - case IP_VERSION(9, 1, 0): /* RAVEN */ - case IP_VERSION(9, 2, 1): /* VEGA12 */ - case IP_VERSION(9, 2, 2): /* RAVEN */ - case IP_VERSION(9, 3, 0): /* RENOIR */ - case IP_VERSION(9, 4, 0): /* VEGA20 */ - case IP_VERSION(9, 4, 1): /* ARCTURUS */ - case IP_VERSION(9, 4, 2): /* ALDEBARAN */ - case IP_VERSION(10, 3, 1): /* VANGOGH */ - case IP_VERSION(10, 3, 3): /* YELLOW_CARP */ - case IP_VERSION(10, 1, 3): /* CYAN_SKILLFISH */ - case IP_VERSION(10, 1, 10): /* NAVI10 */ - case IP_VERSION(10, 1, 2): /* NAVI12 */ - case IP_VERSION(10, 1, 1): /* NAVI14 */ - case IP_VERSION(10, 3, 0): /* SIENNA_CICHLID */ - case IP_VERSION(10, 3, 2): /* NAVY_FLOUNDER */ - case IP_VERSION(10, 3, 4): /* DIMGREY_CAVEFISH */ - case IP_VERSION(10, 3, 5): /* BEIGE_GOBY */ - kfd->device_info.event_interrupt_class = &event_interrupt_class_v9; - break; - default: - dev_warn(kfd_device, "v9 event interrupt handler is set due to " - "mismatch of gc ip block(GC_HWIP:0x%x).\n", gc_version); - kfd->device_info.event_interrupt_class = &event_interrupt_class_v9; - } -} - -static void kfd_device_info_init(struct kfd_dev *kfd, - bool vf, uint32_t gfx_target_version) -{ - uint32_t gc_version = KFD_GC_VERSION(kfd); - uint32_t asic_type = kfd->adev->asic_type; - - kfd->device_info.max_pasid_bits = 16; - kfd->device_info.max_no_of_hqd = 24; - kfd->device_info.num_of_watch_points = 4; - kfd->device_info.mqd_size_aligned = MQD_SIZE_ALIGNED; - kfd->device_info.gfx_target_version = gfx_target_version; - - if (KFD_IS_SOC15(kfd)) { - kfd->device_info.doorbell_size = 8; - kfd->device_info.ih_ring_entry_size = 8 * sizeof(uint32_t); - kfd->device_info.supports_cwsr = true; - - kfd_device_info_set_sdma_queue_num(kfd); - - kfd_device_info_set_event_interrupt_class(kfd); - - /* Raven */ - if (gc_version == IP_VERSION(9, 1, 0) || - gc_version == IP_VERSION(9, 2, 2)) - kfd->device_info.needs_iommu_device = true; - - if (gc_version < IP_VERSION(11, 0, 0)) { - /* Navi2x+, Navi1x+ */ - if (gc_version >= IP_VERSION(10, 3, 0)) - kfd->device_info.no_atomic_fw_version = 92; - else if (gc_version >= IP_VERSION(10, 1, 1)) - kfd->device_info.no_atomic_fw_version = 145; - - /* Navi1x+ */ - if (gc_version >= IP_VERSION(10, 1, 1)) - kfd->device_info.needs_pci_atomics = true; - } - } else { - kfd->device_info.doorbell_size = 4; - kfd->device_info.ih_ring_entry_size = 4 * sizeof(uint32_t); - kfd->device_info.event_interrupt_class = &event_interrupt_class_cik; - kfd->device_info.num_sdma_queues_per_engine = 2; - - if (asic_type != CHIP_KAVERI && - asic_type != CHIP_HAWAII && - asic_type != CHIP_TONGA) - kfd->device_info.supports_cwsr = true; - - if (asic_type == CHIP_KAVERI || - asic_type == CHIP_CARRIZO) - kfd->device_info.needs_iommu_device = true; - - if (asic_type != CHIP_HAWAII && !vf) - kfd->device_info.needs_pci_atomics = true; - } -} - -struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) -{ - struct kfd_dev *kfd = NULL; - const struct kfd2kgd_calls *f2g = NULL; - struct pci_dev *pdev = adev->pdev; - uint32_t gfx_target_version = 0; - - switch (adev->asic_type) { -#ifdef KFD_SUPPORT_IOMMU_V2 -#ifdef CONFIG_DRM_AMDGPU_CIK - case CHIP_KAVERI: - gfx_target_version = 70000; - if (!vf) - f2g = &gfx_v7_kfd2kgd; - break; -#endif - case CHIP_CARRIZO: - gfx_target_version = 80001; - if (!vf) - f2g = &gfx_v8_kfd2kgd; - break; -#endif -#ifdef CONFIG_DRM_AMDGPU_CIK - case CHIP_HAWAII: - gfx_target_version = 70001; - if (!amdgpu_exp_hw_support) - pr_info( - "KFD support on Hawaii is experimental. See modparam exp_hw_support\n" - ); - else if (!vf) - f2g = &gfx_v7_kfd2kgd; - break; -#endif - case CHIP_TONGA: - gfx_target_version = 80002; - if (!vf) - f2g = &gfx_v8_kfd2kgd; - break; - case CHIP_FIJI: - gfx_target_version = 80003; - f2g = &gfx_v8_kfd2kgd; - break; - case CHIP_POLARIS10: - gfx_target_version = 80003; - f2g = &gfx_v8_kfd2kgd; - break; - case CHIP_POLARIS11: - gfx_target_version = 80003; - if (!vf) - f2g = &gfx_v8_kfd2kgd; - break; - case CHIP_POLARIS12: - gfx_target_version = 80003; - if (!vf) - f2g = &gfx_v8_kfd2kgd; - break; - case CHIP_VEGAM: - gfx_target_version = 80003; - if (!vf) - f2g = &gfx_v8_kfd2kgd; - break; - default: - switch (adev->ip_versions[GC_HWIP][0]) { - /* Vega 10 */ - case IP_VERSION(9, 0, 1): - gfx_target_version = 90000; - f2g = &gfx_v9_kfd2kgd; - break; -#ifdef KFD_SUPPORT_IOMMU_V2 - /* Raven */ - case IP_VERSION(9, 1, 0): - case IP_VERSION(9, 2, 2): - gfx_target_version = 90002; - if (!vf) - f2g = &gfx_v9_kfd2kgd; - break; -#endif - /* Vega12 */ - case IP_VERSION(9, 2, 1): - gfx_target_version = 90004; - if (!vf) - f2g = &gfx_v9_kfd2kgd; - break; - /* Renoir */ - case IP_VERSION(9, 3, 0): - gfx_target_version = 90012; - if (!vf) - f2g = &gfx_v9_kfd2kgd; - break; - /* Vega20 */ - case IP_VERSION(9, 4, 0): - gfx_target_version = 90006; - if (!vf) - f2g = &gfx_v9_kfd2kgd; - break; - /* Arcturus */ - case IP_VERSION(9, 4, 1): - gfx_target_version = 90008; - f2g = &arcturus_kfd2kgd; - break; - /* Aldebaran */ - case IP_VERSION(9, 4, 2): - gfx_target_version = 90010; - f2g = &aldebaran_kfd2kgd; - break; - /* Navi10 */ - case IP_VERSION(10, 1, 10): - gfx_target_version = 100100; - if (!vf) - f2g = &gfx_v10_kfd2kgd; - break; - /* Navi12 */ - case IP_VERSION(10, 1, 2): - gfx_target_version = 100101; - f2g = &gfx_v10_kfd2kgd; - break; - /* Navi14 */ - case IP_VERSION(10, 1, 1): - gfx_target_version = 100102; - if (!vf) - f2g = &gfx_v10_kfd2kgd; - break; - /* Cyan Skillfish */ - case IP_VERSION(10, 1, 3): - gfx_target_version = 100103; - if (!vf) - f2g = &gfx_v10_kfd2kgd; - break; - /* Sienna Cichlid */ - case IP_VERSION(10, 3, 0): - gfx_target_version = 100300; - f2g = &gfx_v10_3_kfd2kgd; - break; - /* Navy Flounder */ - case IP_VERSION(10, 3, 2): - gfx_target_version = 100301; - f2g = &gfx_v10_3_kfd2kgd; - break; - /* Van Gogh */ - case IP_VERSION(10, 3, 1): - gfx_target_version = 100303; - if (!vf) - f2g = &gfx_v10_3_kfd2kgd; - break; - /* Dimgrey Cavefish */ - case IP_VERSION(10, 3, 4): - gfx_target_version = 100302; - f2g = &gfx_v10_3_kfd2kgd; - break; - /* Beige Goby */ - case IP_VERSION(10, 3, 5): - gfx_target_version = 100304; - f2g = &gfx_v10_3_kfd2kgd; - break; - /* Yellow Carp */ - case IP_VERSION(10, 3, 3): - gfx_target_version = 100305; - if (!vf) - f2g = &gfx_v10_3_kfd2kgd; - break; - default: - break; - } - break; + if (asic_type >= sizeof(kfd_supported_devices) / (sizeof(void *) * 2) + || asic_type >= sizeof(kfd2kgd_funcs) / sizeof(void *)) { + dev_err(kfd_device, "asic_type %d out of range\n", asic_type); + return NULL; /* asic_type out of range */ } - if (!f2g) { - if (adev->ip_versions[GC_HWIP][0]) - dev_err(kfd_device, "GC IP %06x %s not supported in kfd\n", - adev->ip_versions[GC_HWIP][0], vf ? "VF" : ""); - else - dev_err(kfd_device, "%s %s not supported in kfd\n", - amdgpu_asic_name[adev->asic_type], vf ? "VF" : ""); + device_info = kfd_supported_devices[asic_type][vf]; + f2g = kfd2kgd_funcs[asic_type]; + + if (!device_info || !f2g) { + dev_err(kfd_device, "%s %s not supported in kfd\n", + amdgpu_asic_name[asic_type], vf ? "VF" : ""); return NULL; } @@ -364,8 +717,8 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) if (!kfd) return NULL; - kfd->adev = adev; - kfd_device_info_init(kfd, vf, gfx_target_version); + kfd->kgd = kgd; + kfd->device_info = device_info; kfd->pdev = pdev; kfd->init_complete = false; kfd->kfd2kgd = f2g; @@ -384,24 +737,24 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) static void kfd_cwsr_init(struct kfd_dev *kfd) { - if (cwsr_enable && kfd->device_info.supports_cwsr) { - if (KFD_GC_VERSION(kfd) < IP_VERSION(9, 0, 1)) { + if (cwsr_enable && kfd->device_info->supports_cwsr) { + if (kfd->device_info->asic_family < CHIP_VEGA10) { BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE); kfd->cwsr_isa = cwsr_trap_gfx8_hex; kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex); - } else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 1)) { + } else if (kfd->device_info->asic_family == CHIP_ARCTURUS) { BUILD_BUG_ON(sizeof(cwsr_trap_arcturus_hex) > PAGE_SIZE); kfd->cwsr_isa = cwsr_trap_arcturus_hex; kfd->cwsr_isa_size = sizeof(cwsr_trap_arcturus_hex); - } else if (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2)) { + } else if (kfd->device_info->asic_family == CHIP_ALDEBARAN) { BUILD_BUG_ON(sizeof(cwsr_trap_aldebaran_hex) > PAGE_SIZE); kfd->cwsr_isa = cwsr_trap_aldebaran_hex; kfd->cwsr_isa_size = sizeof(cwsr_trap_aldebaran_hex); - } else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 1, 1)) { + } else if (kfd->device_info->asic_family < CHIP_NAVI10) { BUILD_BUG_ON(sizeof(cwsr_trap_gfx9_hex) > PAGE_SIZE); kfd->cwsr_isa = cwsr_trap_gfx9_hex; kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx9_hex); - } else if (KFD_GC_VERSION(kfd) < IP_VERSION(10, 3, 0)) { + } else if (kfd->device_info->asic_family < CHIP_SIENNA_CICHLID) { BUILD_BUG_ON(sizeof(cwsr_trap_nv1x_hex) > PAGE_SIZE); kfd->cwsr_isa = cwsr_trap_nv1x_hex; kfd->cwsr_isa_size = sizeof(cwsr_trap_nv1x_hex); @@ -422,17 +775,18 @@ static int kfd_gws_init(struct kfd_dev *kfd) if (kfd->dqm->sched_policy == KFD_SCHED_POLICY_NO_HWS) return 0; - if (hws_gws_support || (KFD_IS_SOC15(kfd) && - ((KFD_GC_VERSION(kfd) == IP_VERSION(9, 0, 1) - && kfd->mec2_fw_version >= 0x81b3) || - (KFD_GC_VERSION(kfd) <= IP_VERSION(9, 4, 0) - && kfd->mec2_fw_version >= 0x1b3) || - (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 1) - && kfd->mec2_fw_version >= 0x30) || - (KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2) - && kfd->mec2_fw_version >= 0x28)))) - ret = amdgpu_amdkfd_alloc_gws(kfd->adev, - kfd->adev->gds.gws_size, &kfd->gws); + if (hws_gws_support + || (kfd->device_info->asic_family == CHIP_VEGA10 + && kfd->mec2_fw_version >= 0x81b3) + || (kfd->device_info->asic_family >= CHIP_VEGA12 + && kfd->device_info->asic_family <= CHIP_RAVEN + && kfd->mec2_fw_version >= 0x1b3) + || (kfd->device_info->asic_family == CHIP_ARCTURUS + && kfd->mec2_fw_version >= 0x30) + || (kfd->device_info->asic_family == CHIP_ALDEBARAN + && kfd->mec2_fw_version >= 0x28)) + ret = amdgpu_amdkfd_alloc_gws(kfd->kgd, + amdgpu_amdkfd_get_num_gws(kfd->kgd), &kfd->gws); return ret; } @@ -449,11 +803,11 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, unsigned int size, map_process_packet_size; kfd->ddev = ddev; - kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev, + kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, KGD_ENGINE_MEC1); - kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev, + kfd->mec2_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, KGD_ENGINE_MEC2); - kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->adev, + kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, KGD_ENGINE_SDMA1); kfd->shared_resources = *gpu_resources; @@ -466,16 +820,16 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, * 32 and 64-bit requests are possible and must be * supported. */ - kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kfd->adev); + kfd->pci_atomic_requested = amdgpu_amdkfd_have_atomics_support(kfd->kgd); if (!kfd->pci_atomic_requested && - kfd->device_info.needs_pci_atomics && - (!kfd->device_info.no_atomic_fw_version || - kfd->mec_fw_version < kfd->device_info.no_atomic_fw_version)) { + kfd->device_info->needs_pci_atomics && + (!kfd->device_info->no_atomic_fw_version || + kfd->mec_fw_version < kfd->device_info->no_atomic_fw_version)) { dev_info(kfd_device, "skipped device %x:%x, PCI rejects atomics %d<%d\n", kfd->pdev->vendor, kfd->pdev->device, kfd->mec_fw_version, - kfd->device_info.no_atomic_fw_version); + kfd->device_info->no_atomic_fw_version); return false; } @@ -492,15 +846,16 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, /* calculate max size of mqds needed for queues */ size = max_num_of_queues_per_device * - kfd->device_info.mqd_size_aligned; + kfd->device_info->mqd_size_aligned; /* * calculate max size of runlist packet. * There can be only 2 packets at once */ - map_process_packet_size = KFD_GC_VERSION(kfd) == IP_VERSION(9, 4, 2) ? + map_process_packet_size = + kfd->device_info->asic_family == CHIP_ALDEBARAN ? sizeof(struct pm4_mes_map_process_aldebaran) : - sizeof(struct pm4_mes_map_process); + sizeof(struct pm4_mes_map_process); size += (KFD_MAX_NUM_OF_PROCESSES * map_process_packet_size + max_num_of_queues_per_device * sizeof(struct pm4_mes_map_queues) + sizeof(struct pm4_mes_runlist)) * 2; @@ -512,7 +867,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, size += 512 * 1024; if (amdgpu_amdkfd_alloc_gtt_mem( - kfd->adev, size, &kfd->gtt_mem, + kfd->kgd, size, &kfd->gtt_mem, &kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr, false)) { dev_err(kfd_device, "Could not allocate %d bytes\n", size); @@ -533,9 +888,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto kfd_doorbell_error; } - kfd->hive_id = kfd->adev->gmc.xgmi.hive_id; + kfd->hive_id = amdgpu_amdkfd_get_hive_id(kfd->kgd); - kfd->noretry = kfd->adev->gmc.noretry; + kfd->noretry = amdgpu_amdkfd_get_noretry(kfd->kgd); if (kfd_interrupt_init(kfd)) { dev_err(kfd_device, "Error initializing interrupts\n"); @@ -553,7 +908,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, */ if (kfd_gws_init(kfd)) { dev_err(kfd_device, "Could not allocate %d gws\n", - kfd->adev->gds.gws_size); + amdgpu_amdkfd_get_num_gws(kfd->kgd)); goto gws_error; } @@ -568,7 +923,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd_cwsr_init(kfd); - svm_migrate_init(kfd->adev); + svm_migrate_init((struct amdgpu_device *)kfd->kgd); if(kgd2kfd_resume_iommu(kfd)) goto device_iommu_error; @@ -606,10 +961,10 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd_doorbell_error: kfd_gtt_sa_fini(kfd); kfd_gtt_sa_init_error: - amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem); + amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); alloc_gtt_mem_failure: if (kfd->gws) - amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws); + amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws); dev_err(kfd_device, "device %x:%x NOT added due to errors\n", kfd->pdev->vendor, kfd->pdev->device); @@ -626,9 +981,9 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) kfd_doorbell_fini(kfd); ida_destroy(&kfd->doorbell_ida); kfd_gtt_sa_fini(kfd); - amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem); + amdgpu_amdkfd_free_gtt_mem(kfd->kgd, kfd->gtt_mem); if (kfd->gws) - amdgpu_amdkfd_free_gws(kfd->adev, kfd->gws); + amdgpu_amdkfd_free_gws(kfd->kgd, kfd->gws); } kfree(kfd); @@ -767,7 +1122,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) if (!kfd->init_complete) return; - if (kfd->device_info.ih_ring_entry_size > sizeof(patched_ihre)) { + if (kfd->device_info->ih_ring_entry_size > sizeof(patched_ihre)) { dev_err_once(kfd_device, "Ring entry too small\n"); return; } @@ -1064,7 +1419,7 @@ void kgd2kfd_set_sram_ecc_flag(struct kfd_dev *kfd) void kfd_inc_compute_active(struct kfd_dev *kfd) { if (atomic_inc_return(&kfd->compute_profile) == 1) - amdgpu_amdkfd_set_compute_idle(kfd->adev, false); + amdgpu_amdkfd_set_compute_idle(kfd->kgd, false); } void kfd_dec_compute_active(struct kfd_dev *kfd) @@ -1072,7 +1427,7 @@ void kfd_dec_compute_active(struct kfd_dev *kfd) int count = atomic_dec_return(&kfd->compute_profile); if (count == 0) - amdgpu_amdkfd_set_compute_idle(kfd->adev, true); + amdgpu_amdkfd_set_compute_idle(kfd->kgd, true); WARN_ONCE(count < 0, "Compute profile ref. count error"); } @@ -1082,26 +1437,6 @@ void kgd2kfd_smi_event_throttle(struct kfd_dev *kfd, uint64_t throttle_bitmask) kfd_smi_event_update_thermal_throttling(kfd, throttle_bitmask); } -/* kfd_get_num_sdma_engines returns the number of PCIe optimized SDMA and - * kfd_get_num_xgmi_sdma_engines returns the number of XGMI SDMA. - * When the device has more than two engines, we reserve two for PCIe to enable - * full-duplex and the rest are used as XGMI. - */ -unsigned int kfd_get_num_sdma_engines(struct kfd_dev *kdev) -{ - /* If XGMI is not supported, all SDMA engines are PCIe */ - if (!kdev->adev->gmc.xgmi.supported) - return kdev->adev->sdma.num_instances; - - return min(kdev->adev->sdma.num_instances, 2); -} - -unsigned int kfd_get_num_xgmi_sdma_engines(struct kfd_dev *kdev) -{ - /* After reserved for PCIe, the rest of engines are XGMI */ - return kdev->adev->sdma.num_instances - kfd_get_num_sdma_engines(kdev); -} - #if defined(CONFIG_DEBUG_FS) /* This function will send a package to HIQ to hang the HWS diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 4b6814949a..4f2e0cc8a5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -47,7 +47,7 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, uint32_t filter_param); static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, - uint32_t filter_param, bool reset); + uint32_t filter_param); static int map_queues_cpsch(struct device_queue_manager *dqm); @@ -99,29 +99,38 @@ unsigned int get_pipes_per_mec(struct device_queue_manager *dqm) return dqm->dev->shared_resources.num_pipe_per_mec; } +static unsigned int get_num_sdma_engines(struct device_queue_manager *dqm) +{ + return dqm->dev->device_info->num_sdma_engines; +} + +static unsigned int get_num_xgmi_sdma_engines(struct device_queue_manager *dqm) +{ + return dqm->dev->device_info->num_xgmi_sdma_engines; +} + static unsigned int get_num_all_sdma_engines(struct device_queue_manager *dqm) { - return kfd_get_num_sdma_engines(dqm->dev) + - kfd_get_num_xgmi_sdma_engines(dqm->dev); + return get_num_sdma_engines(dqm) + get_num_xgmi_sdma_engines(dqm); } unsigned int get_num_sdma_queues(struct device_queue_manager *dqm) { - return kfd_get_num_sdma_engines(dqm->dev) * - dqm->dev->device_info.num_sdma_queues_per_engine; + return dqm->dev->device_info->num_sdma_engines + * dqm->dev->device_info->num_sdma_queues_per_engine; } unsigned int get_num_xgmi_sdma_queues(struct device_queue_manager *dqm) { - return kfd_get_num_xgmi_sdma_engines(dqm->dev) * - dqm->dev->device_info.num_sdma_queues_per_engine; + return dqm->dev->device_info->num_xgmi_sdma_engines + * dqm->dev->device_info->num_sdma_queues_per_engine; } void program_sh_mem_settings(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { return dqm->dev->kfd2kgd->program_sh_mem_settings( - dqm->dev->adev, qpd->vmid, + dqm->dev->kgd, qpd->vmid, qpd->sh_mem_config, qpd->sh_mem_ape1_base, qpd->sh_mem_ape1_limit, @@ -148,7 +157,7 @@ static int allocate_doorbell(struct qcm_process_device *qpd, struct queue *q) { struct kfd_dev *dev = qpd->dqm->dev; - if (!KFD_IS_SOC15(dev)) { + if (!KFD_IS_SOC15(dev->device_info->asic_family)) { /* On pre-SOC15 chips we need to use the queue ID to * preserve the user mode ABI. */ @@ -193,7 +202,7 @@ static void deallocate_doorbell(struct qcm_process_device *qpd, unsigned int old; struct kfd_dev *dev = qpd->dqm->dev; - if (!KFD_IS_SOC15(dev) || + if (!KFD_IS_SOC15(dev->device_info->asic_family) || q->properties.type == KFD_QUEUE_TYPE_SDMA || q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) return; @@ -207,7 +216,7 @@ static void program_trap_handler_settings(struct device_queue_manager *dqm, { if (dqm->dev->kfd2kgd->program_trap_handler_settings) dqm->dev->kfd2kgd->program_trap_handler_settings( - dqm->dev->adev, qpd->vmid, + dqm->dev->kgd, qpd->vmid, qpd->tba_addr, qpd->tma_addr); } @@ -241,20 +250,21 @@ static int allocate_vmid(struct device_queue_manager *dqm, program_sh_mem_settings(dqm, qpd); - if (KFD_IS_SOC15(dqm->dev) && dqm->dev->cwsr_enabled) + if (dqm->dev->device_info->asic_family >= CHIP_VEGA10 && + dqm->dev->cwsr_enabled) program_trap_handler_settings(dqm, qpd); /* qpd->page_table_base is set earlier when register_process() * is called, i.e. when the first queue is created. */ - dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->adev, + dqm->dev->kfd2kgd->set_vm_context_page_table_base(dqm->dev->kgd, qpd->vmid, qpd->page_table_base); /* invalidate the VM context after pasid and vmid mapping is set up */ kfd_flush_tlb(qpd_to_pdd(qpd), TLB_FLUSH_LEGACY); if (dqm->dev->kfd2kgd->set_scratch_backing_va) - dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->adev, + dqm->dev->kfd2kgd->set_scratch_backing_va(dqm->dev->kgd, qpd->sh_hidden_private_base, qpd->vmid); return 0; @@ -273,7 +283,7 @@ static int flush_texture_cache_nocpsch(struct kfd_dev *kdev, if (ret) return ret; - return amdgpu_amdkfd_submit_ib(kdev->adev, KGD_ENGINE_MEC1, qpd->vmid, + return amdgpu_amdkfd_submit_ib(kdev->kgd, KGD_ENGINE_MEC1, qpd->vmid, qpd->ib_base, (uint32_t *)qpd->ib_kaddr, pmf->release_mem_size / sizeof(uint32_t)); } @@ -283,7 +293,7 @@ static void deallocate_vmid(struct device_queue_manager *dqm, struct queue *q) { /* On GFX v7, CP doesn't flush TC at dequeue */ - if (q->device->adev->asic_type == CHIP_HAWAII) + if (q->device->device_info->asic_family == CHIP_HAWAII) if (flush_texture_cache_nocpsch(q->device, qpd)) pr_err("Failed to flush TC\n"); @@ -547,8 +557,7 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, return retval; } -static int update_queue(struct device_queue_manager *dqm, struct queue *q, - struct mqd_update_info *minfo) +static int update_queue(struct device_queue_manager *dqm, struct queue *q) { int retval = 0; struct mqd_manager *mqd_mgr; @@ -570,7 +579,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q, /* Make sure the queue is unmapped before updating the MQD */ if (dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) { retval = unmap_queues_cpsch(dqm, - KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false); + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); if (retval) { pr_err("unmap queue failed\n"); goto out_unlock; @@ -596,7 +605,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q, } } - mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties, minfo); + mqd_mgr->update_mqd(mqd_mgr, q->mqd, &q->properties); /* * check active state vs. the previous state and modify @@ -766,7 +775,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm, if (!list_empty(&qpd->queues_list)) { dqm->dev->kfd2kgd->set_vm_context_page_table_base( - dqm->dev->adev, + dqm->dev->kgd, qpd->vmid, qpd->page_table_base); kfd_flush_tlb(pdd, TLB_FLUSH_LEGACY); @@ -944,7 +953,7 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, u32 pasid, unsigned int vmid) { return dqm->dev->kfd2kgd->set_pasid_vmid_mapping( - dqm->dev->adev, pasid, vmid); + dqm->dev->kgd, pasid, vmid); } static void init_interrupts(struct device_queue_manager *dqm) @@ -953,7 +962,7 @@ static void init_interrupts(struct device_queue_manager *dqm) for (i = 0 ; i < get_pipes_per_mec(dqm) ; i++) if (is_pipe_enabled(dqm, 0, i)) - dqm->dev->kfd2kgd->init_interrupts(dqm->dev->adev, i); + dqm->dev->kfd2kgd->init_interrupts(dqm->dev->kgd, i); } static int initialize_nocpsch(struct device_queue_manager *dqm) @@ -1004,22 +1013,19 @@ static void uninitialize(struct device_queue_manager *dqm) static int start_nocpsch(struct device_queue_manager *dqm) { - int r = 0; - pr_info("SW scheduler is used"); init_interrupts(dqm); - if (dqm->dev->adev->asic_type == CHIP_HAWAII) - r = pm_init(&dqm->packet_mgr, dqm); - if (!r) - dqm->sched_running = true; + if (dqm->dev->device_info->asic_family == CHIP_HAWAII) + return pm_init(&dqm->packet_mgr, dqm); + dqm->sched_running = true; - return r; + return 0; } static int stop_nocpsch(struct device_queue_manager *dqm) { - if (dqm->dev->adev->asic_type == CHIP_HAWAII) + if (dqm->dev->device_info->asic_family == CHIP_HAWAII) pm_uninit(&dqm->packet_mgr, false); dqm->sched_running = false; @@ -1048,9 +1054,9 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm, dqm->sdma_bitmap &= ~(1ULL << bit); q->sdma_id = bit; q->properties.sdma_engine_id = q->sdma_id % - kfd_get_num_sdma_engines(dqm->dev); + get_num_sdma_engines(dqm); q->properties.sdma_queue_id = q->sdma_id / - kfd_get_num_sdma_engines(dqm->dev); + get_num_sdma_engines(dqm); } else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) { if (dqm->xgmi_sdma_bitmap == 0) { pr_err("No more XGMI SDMA queue to allocate\n"); @@ -1065,11 +1071,10 @@ static int allocate_sdma_queue(struct device_queue_manager *dqm, * assumes the first N engines are always * PCIe-optimized ones */ - q->properties.sdma_engine_id = - kfd_get_num_sdma_engines(dqm->dev) + - q->sdma_id % kfd_get_num_xgmi_sdma_engines(dqm->dev); + q->properties.sdma_engine_id = get_num_sdma_engines(dqm) + + q->sdma_id % get_num_xgmi_sdma_engines(dqm); q->properties.sdma_queue_id = q->sdma_id / - kfd_get_num_xgmi_sdma_engines(dqm->dev); + get_num_xgmi_sdma_engines(dqm); } pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id); @@ -1126,7 +1131,7 @@ static int set_sched_resources(struct device_queue_manager *dqm) res.queue_mask |= 1ull << amdgpu_queue_mask_bit_to_set_resource_bit( - dqm->dev->adev, i); + (struct amdgpu_device *)dqm->dev->kgd, i); } res.gws_mask = ~0ull; res.oac_mask = res.gds_heap_base = res.gds_heap_size = 0; @@ -1226,7 +1231,7 @@ static int stop_cpsch(struct device_queue_manager *dqm) } if (!dqm->is_hws_hang) - unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0, false); + unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); hanging = dqm->is_hws_hang || dqm->is_resetting; dqm->sched_running = false; @@ -1422,20 +1427,20 @@ static int map_queues_cpsch(struct device_queue_manager *dqm) /* dqm->lock mutex has to be locked before calling this function */ static int unmap_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, - uint32_t filter_param, bool reset) + uint32_t filter_param) { int retval = 0; struct mqd_manager *mqd_mgr; if (!dqm->sched_running) return 0; - if (dqm->is_hws_hang || dqm->is_resetting) + if (dqm->is_hws_hang) return -EIO; if (!dqm->active_runlist) return retval; retval = pm_send_unmap_queue(&dqm->packet_mgr, KFD_QUEUE_TYPE_COMPUTE, - filter, filter_param, reset, 0); + filter, filter_param, false, 0); if (retval) return retval; @@ -1479,21 +1484,6 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, return retval; } -/* only for compute queue */ -static int reset_queues_cpsch(struct device_queue_manager *dqm, - uint16_t pasid) -{ - int retval; - - dqm_lock(dqm); - - retval = unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_BY_PASID, - pasid, true); - - dqm_unlock(dqm); - return retval; -} - /* dqm->lock mutex has to be locked before calling this function */ static int execute_queues_cpsch(struct device_queue_manager *dqm, enum kfd_unmap_queues_filter filter, @@ -1503,7 +1493,7 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, if (dqm->is_hws_hang) return -EIO; - retval = unmap_queues_cpsch(dqm, filter, filter_param, false); + retval = unmap_queues_cpsch(dqm, filter, filter_param); if (retval) return retval; @@ -1856,10 +1846,10 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm) struct kfd_mem_obj *mem_obj = &dqm->hiq_sdma_mqd; uint32_t size = dqm->mqd_mgrs[KFD_MQD_TYPE_SDMA]->mqd_size * get_num_all_sdma_engines(dqm) * - dev->device_info.num_sdma_queues_per_engine + + dev->device_info->num_sdma_queues_per_engine + dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]->mqd_size; - retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev, size, + retval = amdgpu_amdkfd_alloc_gtt_mem(dev->kgd, size, &(mem_obj->gtt_mem), &(mem_obj->gpu_addr), (void *)&(mem_obj->cpu_ptr), false); @@ -1876,7 +1866,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) if (!dqm) return NULL; - switch (dev->adev->asic_type) { + switch (dev->device_info->asic_family) { /* HWS is not available on Hawaii. */ case CHIP_HAWAII: /* HWS depends on CWSR for timely dequeue. CWSR is not @@ -1914,7 +1904,6 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.evict_process_queues = evict_process_queues_cpsch; dqm->ops.restore_process_queues = restore_process_queues_cpsch; dqm->ops.get_wave_state = get_wave_state; - dqm->ops.reset_queues = reset_queues_cpsch; break; case KFD_SCHED_POLICY_NO_HWS: /* initialize dqm for no cp scheduling */ @@ -1940,7 +1929,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) goto out_free; } - switch (dev->adev->asic_type) { + switch (dev->device_info->asic_family) { case CHIP_CARRIZO: device_queue_manager_init_vi(&dqm->asic_ops); break; @@ -1962,16 +1951,31 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) device_queue_manager_init_vi_tonga(&dqm->asic_ops); break; + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_RENOIR: + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: + device_queue_manager_init_v9(&dqm->asic_ops); + break; + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + device_queue_manager_init_v10_navi10(&dqm->asic_ops); + break; default: - if (KFD_GC_VERSION(dev) >= IP_VERSION(10, 1, 1)) - device_queue_manager_init_v10_navi10(&dqm->asic_ops); - else if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1)) - device_queue_manager_init_v9(&dqm->asic_ops); - else { - WARN(1, "Unexpected ASIC family %u", - dev->adev->asic_type); - goto out_free; - } + WARN(1, "Unexpected ASIC family %u", + dev->device_info->asic_family); + goto out_free; } if (init_mqd_managers(dqm)) @@ -1995,7 +1999,7 @@ static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev, { WARN(!mqd, "No hiq sdma mqd trunk to free"); - amdgpu_amdkfd_free_gtt_mem(dev->adev, mqd->gtt_mem); + amdgpu_amdkfd_free_gtt_mem(dev->kgd, mqd->gtt_mem); } void device_queue_manager_uninit(struct device_queue_manager *dqm) @@ -2026,7 +2030,7 @@ static void kfd_process_hw_exception(struct work_struct *work) { struct device_queue_manager *dqm = container_of(work, struct device_queue_manager, hw_exception_work); - amdgpu_amdkfd_gpu_reset(dqm->dev->adev); + amdgpu_amdkfd_gpu_reset(dqm->dev->kgd); } #if defined(CONFIG_DEBUG_FS) @@ -2065,7 +2069,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data) return 0; } - r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->adev, + r = dqm->dev->kfd2kgd->hqd_dump(dqm->dev->kgd, KFD_CIK_HIQ_PIPE, KFD_CIK_HIQ_QUEUE, &dump, &n_regs); if (!r) { @@ -2087,7 +2091,7 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data) continue; r = dqm->dev->kfd2kgd->hqd_dump( - dqm->dev->adev, pipe, queue, &dump, &n_regs); + dqm->dev->kgd, pipe, queue, &dump, &n_regs); if (r) break; @@ -2101,10 +2105,10 @@ int dqm_debugfs_hqds(struct seq_file *m, void *data) for (pipe = 0; pipe < get_num_all_sdma_engines(dqm); pipe++) { for (queue = 0; - queue < dqm->dev->device_info.num_sdma_queues_per_engine; + queue < dqm->dev->device_info->num_sdma_queues_per_engine; queue++) { r = dqm->dev->kfd2kgd->hqd_sdma_dump( - dqm->dev->adev, pipe, queue, &dump, &n_regs); + dqm->dev->kgd, pipe, queue, &dump, &n_regs); if (r) break; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index e145e4deb5..c8719682c4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -81,8 +81,6 @@ struct device_process_node { * * @get_wave_state: Retrieves context save state and optionally copies the * control stack, if kept in the MQD, to the given userspace address. - * - * @reset_queues: reset queues which consume RAS poison */ struct device_queue_manager_ops { @@ -95,7 +93,7 @@ struct device_queue_manager_ops { struct queue *q); int (*update_queue)(struct device_queue_manager *dqm, - struct queue *q, struct mqd_update_info *minfo); + struct queue *q); int (*register_process)(struct device_queue_manager *dqm, struct qcm_process_device *qpd); @@ -136,9 +134,6 @@ struct device_queue_manager_ops { void __user *ctl_stack, u32 *ctl_stack_used_size, u32 *save_area_used_size); - - int (*reset_queues)(struct device_queue_manager *dqm, - uint16_t pasid); }; struct device_queue_manager_asic_ops { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c index f20434d998..b5c3d13643 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v9.c @@ -62,7 +62,7 @@ static int update_qpd_v9(struct device_queue_manager *dqm, SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT; - if (KFD_GC_VERSION(dqm->dev) == IP_VERSION(9, 4, 2)) { + if (dqm->dev->device_info->asic_family == CHIP_ALDEBARAN) { /* Aldebaran can safely support different XNACK modes * per process */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c index 0dbcf54657..768d153acf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c @@ -48,7 +48,7 @@ /* # of doorbell bytes allocated for each process. */ size_t kfd_doorbell_process_slice(struct kfd_dev *kfd) { - return roundup(kfd->device_info.doorbell_size * + return roundup(kfd->device_info->doorbell_size * KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, PAGE_SIZE); } @@ -180,7 +180,7 @@ void __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd, if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) return NULL; - inx *= kfd->device_info.doorbell_size / sizeof(u32); + inx *= kfd->device_info->doorbell_size / sizeof(u32); /* * Calculating the kernel doorbell offset using the first @@ -201,7 +201,7 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr) unsigned int inx; inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr) - * sizeof(u32) / kfd->device_info.doorbell_size; + * sizeof(u32) / kfd->device_info->doorbell_size; mutex_lock(&kfd->doorbell_mutex); __clear_bit(inx, kfd->doorbell_available_index); @@ -239,7 +239,7 @@ unsigned int kfd_get_doorbell_dw_offset_in_bar(struct kfd_dev *kfd, return kfd->doorbell_base_dw_offset + pdd->doorbell_index * kfd_doorbell_process_slice(kfd) / sizeof(u32) + - doorbell_id * kfd->device_info.doorbell_size / sizeof(u32); + doorbell_id * kfd->device_info->doorbell_size / sizeof(u32); } uint64_t kfd_get_number_elems(struct kfd_dev *kfd) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index afe72dd113..3eea4edee3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -935,10 +935,8 @@ void kfd_signal_iommu_event(struct kfd_dev *dev, u32 pasid, /* Workaround on Raven to not kill the process when memory is freed * before IOMMU is able to finish processing all the excessive PPRs */ - - if (KFD_GC_VERSION(dev) != IP_VERSION(9, 1, 0) && - KFD_GC_VERSION(dev) != IP_VERSION(9, 2, 2) && - KFD_GC_VERSION(dev) != IP_VERSION(9, 3, 0)) { + if (dev->device_info->asic_family != CHIP_RAVEN && + dev->device_info->asic_family != CHIP_RENOIR) { mutex_lock(&p->event_mutex); /* Lookup events by type and signal them */ diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c index 2e2b7ceb71..2e86692def 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c @@ -308,7 +308,7 @@ * 16MB are reserved for kernel use (CWSR trap handler and kernel IB * for now). */ -#define SVM_USER_BASE (u64)(KFD_CWSR_TBA_TMA_SIZE + 2*PAGE_SIZE) +#define SVM_USER_BASE 0x1000000ull #define SVM_CWSR_BASE (SVM_USER_BASE - KFD_CWSR_TBA_TMA_SIZE) #define SVM_IB_BASE (SVM_CWSR_BASE - PAGE_SIZE) @@ -394,7 +394,7 @@ int kfd_init_apertures(struct kfd_process *process) pdd->gpuvm_base = pdd->gpuvm_limit = 0; pdd->scratch_base = pdd->scratch_limit = 0; } else { - switch (dev->adev->asic_type) { + switch (dev->device_info->asic_family) { case CHIP_KAVERI: case CHIP_HAWAII: case CHIP_CARRIZO: @@ -406,14 +406,29 @@ int kfd_init_apertures(struct kfd_process *process) case CHIP_VEGAM: kfd_init_apertures_vi(pdd, id); break; + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_RENOIR: + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + kfd_init_apertures_v9(pdd, id); + break; default: - if (KFD_GC_VERSION(dev) >= IP_VERSION(9, 0, 1)) - kfd_init_apertures_v9(pdd, id); - else { - WARN(1, "Unexpected ASIC family %u", - dev->adev->asic_type); - return -EINVAL; - } + WARN(1, "Unexpected ASIC family %u", + dev->device_info->asic_family); + return -EINVAL; } if (!dev->use_iommu_v2) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c index e8bc28009c..12d91e5355 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c @@ -89,44 +89,6 @@ enum SQ_INTERRUPT_ERROR_TYPE { #define KFD_SQ_INT_DATA__ERR_TYPE_MASK 0xF00000 #define KFD_SQ_INT_DATA__ERR_TYPE__SHIFT 20 -static void event_interrupt_poison_consumption(struct kfd_dev *dev, - uint16_t pasid, uint16_t source_id) -{ - int ret = -EINVAL; - struct kfd_process *p = kfd_lookup_process_by_pasid(pasid); - - if (!p) - return; - - /* all queues of a process will be unmapped in one time */ - if (atomic_read(&p->poison)) { - kfd_unref_process(p); - return; - } - - atomic_set(&p->poison, 1); - kfd_unref_process(p); - - switch (source_id) { - case SOC15_INTSRC_SQ_INTERRUPT_MSG: - if (dev->dqm->ops.reset_queues) - ret = dev->dqm->ops.reset_queues(dev->dqm, pasid); - break; - case SOC15_INTSRC_SDMA_ECC: - default: - break; - } - - kfd_signal_poison_consumed_event(dev, pasid); - - /* resetting queue passes, do page retirement without gpu reset - resetting queue fails, fallback to gpu reset solution */ - if (!ret) - amdgpu_amdkfd_ras_poison_consumption_handler(dev->adev, false); - else - amdgpu_amdkfd_ras_poison_consumption_handler(dev->adev, true); -} - static bool event_interrupt_isr_v9(struct kfd_dev *dev, const uint32_t *ih_ring_entry, uint32_t *patched_ihre, @@ -173,7 +135,7 @@ static bool event_interrupt_isr_v9(struct kfd_dev *dev, *patched_flag = true; memcpy(patched_ihre, ih_ring_entry, - dev->device_info.ih_ring_entry_size); + dev->device_info->ih_ring_entry_size); pasid = dev->dqm->vmid_pasid[vmid]; @@ -197,7 +159,6 @@ static bool event_interrupt_isr_v9(struct kfd_dev *dev, */ return source_id == SOC15_INTSRC_CP_END_OF_PIPE || source_id == SOC15_INTSRC_SDMA_TRAP || - source_id == SOC15_INTSRC_SDMA_ECC || source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG || source_id == SOC15_INTSRC_CP_BAD_OPCODE || ((client_id == SOC15_IH_CLIENTID_VMC || @@ -269,7 +230,8 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev, sq_intr_err); if (sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_ILLEGAL_INST && sq_intr_err != SQ_INTERRUPT_ERROR_TYPE_MEMVIOL) { - event_interrupt_poison_consumption(dev, pasid, source_id); + kfd_signal_poison_consumed_event(dev, pasid); + amdgpu_amdkfd_gpu_reset(dev->kgd); return; } break; @@ -290,7 +252,8 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev, if (source_id == SOC15_INTSRC_SDMA_TRAP) { kfd_signal_event_interrupt(pasid, context_id0 & 0xfffffff, 28); } else if (source_id == SOC15_INTSRC_SDMA_ECC) { - event_interrupt_poison_consumption(dev, pasid, source_id); + kfd_signal_poison_consumed_event(dev, pasid); + amdgpu_amdkfd_gpu_reset(dev->kgd); return; } } else if (client_id == SOC15_IH_CLIENTID_VMC || diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c index 81887c2013..bc47f6a444 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -54,7 +54,7 @@ int kfd_interrupt_init(struct kfd_dev *kfd) int r; r = kfifo_alloc(&kfd->ih_fifo, - KFD_IH_NUM_ENTRIES * kfd->device_info.ih_ring_entry_size, + KFD_IH_NUM_ENTRIES * kfd->device_info->ih_ring_entry_size, GFP_KERNEL); if (r) { dev_err(kfd_chardev(), "Failed to allocate IH fifo\n"); @@ -114,8 +114,8 @@ bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) int count; count = kfifo_in(&kfd->ih_fifo, ih_ring_entry, - kfd->device_info.ih_ring_entry_size); - if (count != kfd->device_info.ih_ring_entry_size) { + kfd->device_info->ih_ring_entry_size); + if (count != kfd->device_info->ih_ring_entry_size) { dev_err_ratelimited(kfd_chardev(), "Interrupt ring overflow, dropping interrupt %d\n", count); @@ -133,11 +133,11 @@ static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) int count; count = kfifo_out(&kfd->ih_fifo, ih_ring_entry, - kfd->device_info.ih_ring_entry_size); + kfd->device_info->ih_ring_entry_size); - WARN_ON(count && count != kfd->device_info.ih_ring_entry_size); + WARN_ON(count && count != kfd->device_info->ih_ring_entry_size); - return count == kfd->device_info.ih_ring_entry_size; + return count == kfd->device_info->ih_ring_entry_size; } static void interrupt_wq(struct work_struct *work) @@ -146,13 +146,13 @@ static void interrupt_wq(struct work_struct *work) interrupt_work); uint32_t ih_ring_entry[KFD_MAX_RING_ENTRY_SIZE]; - if (dev->device_info.ih_ring_entry_size > sizeof(ih_ring_entry)) { + if (dev->device_info->ih_ring_entry_size > sizeof(ih_ring_entry)) { dev_err_once(kfd_chardev(), "Ring entry too small\n"); return; } while (dequeue_ih_ring_entry(dev, ih_ring_entry)) - dev->device_info.event_interrupt_class->interrupt_wq(dev, + dev->device_info->event_interrupt_class->interrupt_wq(dev, ih_ring_entry); } @@ -163,7 +163,7 @@ bool interrupt_is_wanted(struct kfd_dev *dev, /* integer and bitwise OR so there is no boolean short-circuiting */ unsigned int wanted = 0; - wanted |= dev->device_info.event_interrupt_class->interrupt_isr(dev, + wanted |= dev->device_info->event_interrupt_class->interrupt_isr(dev, ih_ring_entry, patched_ihre, flag); return wanted != 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c index 66ad8d0b8f..73f2257acc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c @@ -89,7 +89,7 @@ int kfd_iommu_device_init(struct kfd_dev *kfd) } pasid_limit = min_t(unsigned int, - (unsigned int)(1 << kfd->device_info.max_pasid_bits), + (unsigned int)(1 << kfd->device_info->max_pasid_bits), iommu_info.max_pasids); if (!kfd_set_pasid_limit(pasid_limit)) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index 16f8bc4ca7..a2b77d1df8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -91,7 +91,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev, kq->pq_gpu_addr = kq->pq->gpu_addr; /* For CIK family asics, kq->eop_mem is not needed */ - if (dev->adev->asic_type > CHIP_MULLINS) { + if (dev->device_info->asic_family > CHIP_MULLINS) { retval = kfd_gtt_sa_allocate(dev, PAGE_SIZE, &kq->eop_mem); if (retval != 0) goto err_eop_allocate_vidmem; @@ -111,7 +111,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev, kq->rptr_kernel = kq->rptr_mem->cpu_ptr; kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr; - retval = kfd_gtt_sa_allocate(dev, dev->device_info.doorbell_size, + retval = kfd_gtt_sa_allocate(dev, dev->device_info->doorbell_size, &kq->wptr_mem); if (retval != 0) @@ -136,6 +136,7 @@ static bool kq_initialize(struct kernel_queue *kq, struct kfd_dev *dev, prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr; prop.eop_ring_buffer_address = kq->eop_gpu_addr; prop.eop_ring_buffer_size = PAGE_SIZE; + prop.cu_mask = NULL; if (init_queue(&kq->queue, &prop) != 0) goto err_init_queue; @@ -297,7 +298,7 @@ void kq_submit_packet(struct kernel_queue *kq) } pr_debug("\n"); #endif - if (kq->dev->device_info.doorbell_size == 8) { + if (kq->dev->device_info->doorbell_size == 8) { *kq->wptr64_kernel = kq->pending_wptr64; write_kernel_doorbell64(kq->queue->properties.doorbell_ptr, kq->pending_wptr64); @@ -310,7 +311,7 @@ void kq_submit_packet(struct kernel_queue *kq) void kq_rollback_packet(struct kernel_queue *kq) { - if (kq->dev->device_info.doorbell_size == 8) { + if (kq->dev->device_info->doorbell_size == 8) { kq->pending_wptr64 = *kq->wptr64_kernel; kq->pending_wptr = *kq->wptr_kernel % (kq->queue->properties.queue_size / 4); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c index ed5385137f..4a16e3c257 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -20,6 +20,7 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ + #include #include #include @@ -33,11 +34,6 @@ #include "kfd_svm.h" #include "kfd_migrate.h" -#ifdef dev_fmt -#undef dev_fmt -#endif -#define dev_fmt(fmt) "kfd_migrate: %s: " fmt, __func__ - static uint64_t svm_migrate_direct_mapping_addr(struct amdgpu_device *adev, uint64_t addr) { @@ -108,8 +104,8 @@ svm_migrate_gart_map(struct amdgpu_ring *ring, uint64_t npages, * svm_migrate_copy_memory_gart - sdma copy data between ram and vram * * @adev: amdgpu device the sdma ring running - * @sys: system DMA pointer to be copied - * @vram: vram destination DMA pointer + * @src: source page address array + * @dst: destination page address array * @npages: number of pages to copy * @direction: enum MIGRATION_COPY_DIR * @mfence: output, sdma fence to signal after sdma is done @@ -155,14 +151,14 @@ svm_migrate_copy_memory_gart(struct amdgpu_device *adev, dma_addr_t *sys, gart_d = svm_migrate_direct_mapping_addr(adev, *vram); } if (r) { - dev_err(adev->dev, "fail %d create gart mapping\n", r); + pr_debug("failed %d to create gart mapping\n", r); goto out_unlock; } r = amdgpu_copy_buffer(ring, gart_s, gart_d, size * PAGE_SIZE, NULL, &next, false, true, false); if (r) { - dev_err(adev->dev, "fail %d to copy memory\n", r); + pr_debug("failed %d to copy memory\n", r); goto out_unlock; } @@ -268,32 +264,6 @@ static void svm_migrate_put_sys_page(unsigned long addr) put_page(page); } -static unsigned long svm_migrate_successful_pages(struct migrate_vma *migrate) -{ - unsigned long cpages = 0; - unsigned long i; - - for (i = 0; i < migrate->npages; i++) { - if (migrate->src[i] & MIGRATE_PFN_VALID && - migrate->src[i] & MIGRATE_PFN_MIGRATE) - cpages++; - } - return cpages; -} - -static unsigned long svm_migrate_unsuccessful_pages(struct migrate_vma *migrate) -{ - unsigned long upages = 0; - unsigned long i; - - for (i = 0; i < migrate->npages; i++) { - if (migrate->src[i] & MIGRATE_PFN_VALID && - !(migrate->src[i] & MIGRATE_PFN_MIGRATE)) - upages++; - } - return upages; -} - static int svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, struct migrate_vma *migrate, struct dma_fence **mfence, @@ -315,7 +285,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, r = svm_range_vram_node_new(adev, prange, true); if (r) { - dev_err(adev->dev, "fail %d to alloc vram\n", r); + pr_debug("failed %d get 0x%llx pages from vram\n", r, npages); goto out; } @@ -330,11 +300,12 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, migrate->dst[i] = svm_migrate_addr_to_pfn(adev, dst[i]); svm_migrate_get_vram_page(prange, migrate->dst[i]); migrate->dst[i] = migrate_pfn(migrate->dst[i]); + migrate->dst[i] |= MIGRATE_PFN_LOCKED; src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE, DMA_TO_DEVICE); r = dma_mapping_error(dev, src[i]); if (r) { - dev_err(adev->dev, "fail %d dma_map_page\n", r); + pr_debug("failed %d dma_map_page\n", r); goto out_free_vram_pages; } } else { @@ -354,8 +325,8 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, continue; } - pr_debug_ratelimited("dma mapping src to 0x%llx, pfn 0x%lx\n", - src[i] >> PAGE_SHIFT, page_to_pfn(spage)); + pr_debug("dma mapping src to 0x%llx, page_to_pfn 0x%lx\n", + src[i] >> PAGE_SHIFT, page_to_pfn(spage)); if (j >= (cursor.size >> PAGE_SHIFT) - 1 && i < npages - 1) { r = svm_migrate_copy_memory_gart(adev, src + i - j, @@ -401,7 +372,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, return r; } -static long +static int svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange, struct vm_area_struct *vma, uint64_t start, uint64_t end) @@ -410,7 +381,6 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange, struct kfd_process_device *pdd; struct dma_fence *mfence = NULL; struct migrate_vma migrate; - unsigned long cpages = 0; dma_addr_t *scratch; size_t size; void *buf; @@ -435,31 +405,23 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange, r = migrate_vma_setup(&migrate); if (r) { - dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r, - prange->start, prange->last); + pr_debug("failed %d prepare migrate svms 0x%p [0x%lx 0x%lx]\n", + r, prange->svms, prange->start, prange->last); goto out_free; } - - cpages = migrate.cpages; - if (!cpages) { - pr_debug("failed collect migrate sys pages [0x%lx 0x%lx]\n", - prange->start, prange->last); - goto out_free; + if (migrate.cpages != npages) { + pr_debug("Partial migration. 0x%lx/0x%llx pages can be migrated\n", + migrate.cpages, + npages); } - if (cpages != npages) - pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n", - cpages, npages); - else - pr_debug("0x%lx pages migrated\n", cpages); - r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, scratch); - migrate_vma_pages(&migrate); - - pr_debug("successful/cpages/npages 0x%lx/0x%lx/0x%lx\n", - svm_migrate_successful_pages(&migrate), cpages, migrate.npages); - - svm_migrate_copy_done(adev, mfence); - migrate_vma_finalize(&migrate); + if (migrate.cpages) { + r = svm_migrate_copy_to_vram(adev, prange, &migrate, &mfence, + scratch); + migrate_vma_pages(&migrate); + svm_migrate_copy_done(adev, mfence); + migrate_vma_finalize(&migrate); + } svm_range_dma_unmap(adev->dev, scratch, 0, npages); svm_range_free_dma_mappings(prange); @@ -467,13 +429,12 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange, out_free: kvfree(buf); out: - if (!r && cpages) { + if (!r) { pdd = svm_range_get_pdd_by_adev(prange, adev); if (pdd) - WRITE_ONCE(pdd->page_in, pdd->page_in + cpages); - - return cpages; + WRITE_ONCE(pdd->page_in, pdd->page_in + migrate.cpages); } + return r; } @@ -495,8 +456,7 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc, unsigned long addr, start, end; struct vm_area_struct *vma; struct amdgpu_device *adev; - unsigned long cpages = 0; - long r = 0; + int r = 0; if (prange->actual_loc == best_loc) { pr_debug("svms 0x%p [0x%lx 0x%lx] already on best_loc 0x%x\n", @@ -528,19 +488,17 @@ svm_migrate_ram_to_vram(struct svm_range *prange, uint32_t best_loc, next = min(vma->vm_end, end); r = svm_migrate_vma_to_vram(adev, prange, vma, addr, next); - if (r < 0) { - pr_debug("failed %ld to migrate\n", r); + if (r) { + pr_debug("failed to migrate\n"); break; - } else { - cpages += r; } addr = next; } - if (cpages) + if (!r) prange->actual_loc = best_loc; - return r < 0 ? r : 0; + return r; } static void svm_migrate_page_free(struct page *page) @@ -548,8 +506,8 @@ static void svm_migrate_page_free(struct page *page) struct svm_range_bo *svm_bo = page->zone_device_data; if (svm_bo) { - pr_debug_ratelimited("ref: %d\n", kref_read(&svm_bo->kref)); - svm_range_bo_unref_async(svm_bo); + pr_debug("svm_bo ref left: %d\n", kref_read(&svm_bo->kref)); + svm_range_bo_unref(svm_bo); } } @@ -614,14 +572,15 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE); r = dma_mapping_error(dev, dst[i]); if (r) { - dev_err(adev->dev, "fail %d dma_map_page\n", r); + pr_debug("failed %d dma_map_page\n", r); goto out_oom; } - pr_debug_ratelimited("dma mapping dst to 0x%llx, pfn 0x%lx\n", - dst[i] >> PAGE_SHIFT, page_to_pfn(dpage)); + pr_debug("dma mapping dst to 0x%llx, page_to_pfn 0x%lx\n", + dst[i] >> PAGE_SHIFT, page_to_pfn(dpage)); migrate->dst[i] = migrate_pfn(page_to_pfn(dpage)); + migrate->dst[i] |= MIGRATE_PFN_LOCKED; j++; } @@ -640,13 +599,11 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, return r; } -static long +static int svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange, struct vm_area_struct *vma, uint64_t start, uint64_t end) { uint64_t npages = (end - start) >> PAGE_SHIFT; - unsigned long upages = npages; - unsigned long cpages = 0; struct kfd_process_device *pdd; struct dma_fence *mfence = NULL; struct migrate_vma migrate; @@ -674,47 +631,36 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange, r = migrate_vma_setup(&migrate); if (r) { - dev_err(adev->dev, "vma setup fail %d range [0x%lx 0x%lx]\n", r, - prange->start, prange->last); + pr_debug("failed %d prepare migrate svms 0x%p [0x%lx 0x%lx]\n", + r, prange->svms, prange->start, prange->last); goto out_free; } - cpages = migrate.cpages; - if (!cpages) { + pr_debug("cpages %ld\n", migrate.cpages); + + if (migrate.cpages) { + r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence, + scratch, npages); + migrate_vma_pages(&migrate); + svm_migrate_copy_done(adev, mfence); + migrate_vma_finalize(&migrate); + } else { pr_debug("failed collect migrate device pages [0x%lx 0x%lx]\n", prange->start, prange->last); - upages = svm_migrate_unsuccessful_pages(&migrate); - goto out_free; } - if (cpages != npages) - pr_debug("partial migration, 0x%lx/0x%llx pages migrated\n", - cpages, npages); - else - pr_debug("0x%lx pages migrated\n", cpages); - r = svm_migrate_copy_to_ram(adev, prange, &migrate, &mfence, - scratch, npages); - migrate_vma_pages(&migrate); - - upages = svm_migrate_unsuccessful_pages(&migrate); - pr_debug("unsuccessful/cpages/npages 0x%lx/0x%lx/0x%lx\n", - upages, cpages, migrate.npages); - - svm_migrate_copy_done(adev, mfence); - migrate_vma_finalize(&migrate); svm_range_dma_unmap(adev->dev, scratch, 0, npages); out_free: kvfree(buf); out: - if (!r && cpages) { + if (!r) { pdd = svm_range_get_pdd_by_adev(prange, adev); if (pdd) - WRITE_ONCE(pdd->page_out, pdd->page_out + cpages); - - return upages; + WRITE_ONCE(pdd->page_out, + pdd->page_out + migrate.cpages); } - return r ? r : upages; + return r; } /** @@ -734,8 +680,7 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm) unsigned long addr; unsigned long start; unsigned long end; - unsigned long upages = 0; - long r = 0; + int r = 0; if (!prange->actual_loc) { pr_debug("[0x%lx 0x%lx] already migrated to ram\n", @@ -766,21 +711,18 @@ int svm_migrate_vram_to_ram(struct svm_range *prange, struct mm_struct *mm) next = min(vma->vm_end, end); r = svm_migrate_vma_to_ram(adev, prange, vma, addr, next); - if (r < 0) { - pr_debug("failed %ld to migrate\n", r); + if (r) { + pr_debug("failed %d to migrate\n", r); break; - } else { - upages += r; } addr = next; } - if (!upages) { + if (!r) { svm_range_vram_node_free(prange); prange->actual_loc = 0; } - - return r < 0 ? r : 0; + return r; } /** @@ -798,7 +740,7 @@ static int svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc, struct mm_struct *mm) { - int r, retries = 3; + int r; /* * TODO: for both devices with PCIe large bar or on same xgmi hive, skip @@ -807,14 +749,9 @@ svm_migrate_vram_to_vram(struct svm_range *prange, uint32_t best_loc, pr_debug("from gpu 0x%x to gpu 0x%x\n", prange->actual_loc, best_loc); - do { - r = svm_migrate_vram_to_ram(prange, mm); - if (r) - return r; - } while (prange->actual_loc && --retries); - - if (prange->actual_loc) - return -EDEADLK; + r = svm_migrate_vram_to_ram(prange, mm); + if (r) + return r; return svm_migrate_ram_to_vram(prange, best_loc, mm); } @@ -859,11 +796,6 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf) pr_debug("failed find process at fault address 0x%lx\n", addr); return VM_FAULT_SIGBUS; } - if (READ_ONCE(p->svms.faulting_task) == current) { - pr_debug("skipping ram migration\n"); - kfd_unref_process(p); - return 0; - } addr >>= PAGE_SHIFT; pr_debug("CPU page fault svms 0x%p address 0x%lx\n", &p->svms, addr); @@ -938,7 +870,7 @@ int svm_migrate_init(struct amdgpu_device *adev) void *r; /* Page migration works on Vega10 or newer */ - if (!KFD_IS_SOC15(kfddev)) + if (kfddev->device_info->asic_family < CHIP_VEGA10) return -EINVAL; pgmap = &kfddev->pgmap; @@ -969,7 +901,8 @@ int svm_migrate_init(struct amdgpu_device *adev) /* Disable SVM support capability */ pgmap->type = 0; - devm_release_mem_region(adev->dev, res->start, resource_size(res)); + devm_release_mem_region(adev->dev, res->start, + res->end - res->start + 1); return PTR_ERR(r); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h index 965e17c5db..6e6918cced 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h @@ -80,8 +80,7 @@ struct mqd_manager { struct mm_struct *mms); void (*update_mqd)(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo); + struct queue_properties *q); int (*destroy_mqd)(struct mqd_manager *mm, void *mqd, enum kfd_preempt_type type, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index e9a8e21e14..064914e1e8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -42,17 +42,16 @@ static inline struct cik_sdma_rlc_registers *get_sdma_mqd(void *mqd) } static void update_cu_mask(struct mqd_manager *mm, void *mqd, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct cik_mqd *m; uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ - if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || - !minfo->cu_mask.ptr) + if (q->cu_mask_count == 0) return; mqd_symmetrically_map_cu_mask(mm, - minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); + q->cu_mask, q->cu_mask_count, se_mask); m = get_mqd(mqd); m->compute_static_thread_mgmt_se0 = se_mask[0]; @@ -136,7 +135,7 @@ static void init_mqd(struct mqd_manager *mm, void **mqd, *mqd = m; if (gart_addr) *gart_addr = addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, @@ -153,7 +152,7 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, if (gart_addr) *gart_addr = mqd_mem_obj->gpu_addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static void free_mqd(struct mqd_manager *mm, void *mqd, @@ -171,7 +170,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0); uint32_t wptr_mask = (uint32_t)((p->queue_size / 4) - 1); - return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id, + return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, (uint32_t __user *)p->write_ptr, wptr_shift, wptr_mask, mms); } @@ -180,14 +179,13 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd, + return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, (uint32_t __user *)p->write_ptr, mms); } static void __update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, struct mqd_update_info *minfo, - unsigned int atc_bit) + struct queue_properties *q, unsigned int atc_bit) { struct cik_mqd *m; @@ -216,17 +214,16 @@ static void __update_mqd(struct mqd_manager *mm, void *mqd, if (q->format == KFD_QUEUE_FORMAT_AQL) m->cp_hqd_pq_control |= NO_UPDATE_RPTR; - update_cu_mask(mm, mqd, minfo); + update_cu_mask(mm, mqd, q); set_priority(m, q); q->is_active = QUEUE_IS_ACTIVE(*q); } static void update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { - __update_mqd(mm, mqd, q, minfo, 1); + __update_mqd(mm, mqd, q, 1); } static uint32_t read_doorbell_id(void *mqd) @@ -237,15 +234,13 @@ static uint32_t read_doorbell_id(void *mqd) } static void update_mqd_hawaii(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { - __update_mqd(mm, mqd, q, minfo, 0); + __update_mqd(mm, mqd, q, 0); } static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct cik_sdma_rlc_registers *m; @@ -276,7 +271,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_destroy(mm->dev->adev, mqd, type, timeout, + return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, mqd, type, timeout, pipe_id, queue_id); } @@ -289,7 +284,7 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout); + return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); } static bool is_occupied(struct mqd_manager *mm, void *mqd, @@ -297,7 +292,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->adev, queue_address, + return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, pipe_id, queue_id); } @@ -306,7 +301,7 @@ static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd); + return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); } /* @@ -323,8 +318,7 @@ static void init_mqd_hiq(struct mqd_manager *mm, void **mqd, } static void update_mqd_hiq(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct cik_mqd *m; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c index d74d8a6ac2..c7fb59ca59 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c @@ -42,17 +42,16 @@ static inline struct v10_sdma_mqd *get_sdma_mqd(void *mqd) } static void update_cu_mask(struct mqd_manager *mm, void *mqd, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v10_compute_mqd *m; uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ - if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || - !minfo->cu_mask.ptr) + if (q->cu_mask_count == 0) return; mqd_symmetrically_map_cu_mask(mm, - minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); + q->cu_mask, q->cu_mask_count, se_mask); m = get_mqd(mqd); m->compute_static_thread_mgmt_se0 = se_mask[0]; @@ -137,7 +136,7 @@ static void init_mqd(struct mqd_manager *mm, void **mqd, *mqd = m; if (gart_addr) *gart_addr = addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd(struct mqd_manager *mm, void *mqd, @@ -148,7 +147,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0); - r = mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id, + r = mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, (uint32_t __user *)p->write_ptr, wptr_shift, 0, mms); return r; @@ -158,13 +157,12 @@ static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id, + return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, p->doorbell_off); } static void update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v10_compute_mqd *m; @@ -220,7 +218,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd, if (mm->dev->cwsr_enabled) m->cp_hqd_ctx_save_control = 0; - update_cu_mask(mm, mqd, minfo); + update_cu_mask(mm, mqd, q); set_priority(m, q); q->is_active = QUEUE_IS_ACTIVE(*q); @@ -239,7 +237,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_destroy - (mm->dev->adev, mqd, type, timeout, + (mm->dev->kgd, mqd, type, timeout, pipe_id, queue_id); } @@ -254,7 +252,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_is_occupied( - mm->dev->adev, queue_address, + mm->dev->kgd, queue_address, pipe_id, queue_id); } @@ -313,14 +311,14 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, if (gart_addr) *gart_addr = mqd_mem_obj->gpu_addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd, + return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, (uint32_t __user *)p->write_ptr, mms); } @@ -328,8 +326,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, #define SDMA_RLC_DUMMY_DEFAULT 0xf static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v10_sdma_mqd *m; @@ -363,14 +360,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout); + return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); } static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd); + return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); } #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 326eb22850..7f4e102ff4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -43,17 +43,16 @@ static inline struct v9_sdma_mqd *get_sdma_mqd(void *mqd) } static void update_cu_mask(struct mqd_manager *mm, void *mqd, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v9_mqd *m; uint32_t se_mask[KFD_MAX_NUM_SE] = {0}; - if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || - !minfo->cu_mask.ptr) + if (q->cu_mask_count == 0) return; mqd_symmetrically_map_cu_mask(mm, - minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); + q->cu_mask, q->cu_mask_count, se_mask); m = get_mqd(mqd); m->compute_static_thread_mgmt_se0 = se_mask[0]; @@ -108,7 +107,7 @@ static struct kfd_mem_obj *allocate_mqd(struct kfd_dev *kfd, mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); if (!mqd_mem_obj) return NULL; - retval = amdgpu_amdkfd_alloc_gtt_mem(kfd->adev, + retval = amdgpu_amdkfd_alloc_gtt_mem(kfd->kgd, ALIGN(q->ctl_stack_size, PAGE_SIZE) + ALIGN(sizeof(struct v9_mqd), PAGE_SIZE), &(mqd_mem_obj->gtt_mem), @@ -189,7 +188,7 @@ static void init_mqd(struct mqd_manager *mm, void **mqd, *mqd = m; if (gart_addr) *gart_addr = addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd(struct mqd_manager *mm, void *mqd, @@ -199,7 +198,7 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, /* AQL write pointer counts in 64B packets, PM4/CP counts in dwords. */ uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0); - return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id, + return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, (uint32_t __user *)p->write_ptr, wptr_shift, 0, mms); } @@ -208,13 +207,12 @@ static int hiq_load_mqd_kiq(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->adev, mqd, pipe_id, + return mm->dev->kfd2kgd->hiq_mqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, p->doorbell_off); } static void update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v9_mqd *m; @@ -271,7 +269,7 @@ static void update_mqd(struct mqd_manager *mm, void *mqd, if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) m->cp_hqd_ctx_save_control = 0; - update_cu_mask(mm, mqd, minfo); + update_cu_mask(mm, mqd, q); set_priority(m, q); q->is_active = QUEUE_IS_ACTIVE(*q); @@ -291,7 +289,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_destroy - (mm->dev->adev, mqd, type, timeout, + (mm->dev->kgd, mqd, type, timeout, pipe_id, queue_id); } @@ -301,7 +299,7 @@ static void free_mqd(struct mqd_manager *mm, void *mqd, struct kfd_dev *kfd = mm->dev; if (mqd_mem_obj->gtt_mem) { - amdgpu_amdkfd_free_gtt_mem(kfd->adev, mqd_mem_obj->gtt_mem); + amdgpu_amdkfd_free_gtt_mem(kfd->kgd, mqd_mem_obj->gtt_mem); kfree(mqd_mem_obj); } else { kfd_gtt_sa_free(mm->dev, mqd_mem_obj); @@ -313,7 +311,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_is_occupied( - mm->dev->adev, queue_address, + mm->dev->kgd, queue_address, pipe_id, queue_id); } @@ -368,14 +366,14 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, if (gart_addr) *gart_addr = mqd_mem_obj->gpu_addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd, + return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, (uint32_t __user *)p->write_ptr, mms); } @@ -383,8 +381,7 @@ static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, #define SDMA_RLC_DUMMY_DEFAULT 0xf static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct v9_sdma_mqd *m; @@ -418,14 +415,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout); + return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); } static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd); + return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); } #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index d456e950ce..33dbd22d29 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -45,17 +45,16 @@ static inline struct vi_sdma_mqd *get_sdma_mqd(void *mqd) } static void update_cu_mask(struct mqd_manager *mm, void *mqd, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct vi_mqd *m; uint32_t se_mask[4] = {0}; /* 4 is the max # of SEs */ - if (!minfo || (minfo->update_flag != UPDATE_FLAG_CU_MASK) || - !minfo->cu_mask.ptr) + if (q->cu_mask_count == 0) return; mqd_symmetrically_map_cu_mask(mm, - minfo->cu_mask.ptr, minfo->cu_mask.count, se_mask); + q->cu_mask, q->cu_mask_count, se_mask); m = get_mqd(mqd); m->compute_static_thread_mgmt_se0 = se_mask[0]; @@ -151,7 +150,7 @@ static void init_mqd(struct mqd_manager *mm, void **mqd, *mqd = m; if (gart_addr) *gart_addr = addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd(struct mqd_manager *mm, void *mqd, @@ -162,14 +161,14 @@ static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t wptr_shift = (p->format == KFD_QUEUE_FORMAT_AQL ? 4 : 0); uint32_t wptr_mask = (uint32_t)((p->queue_size / 4) - 1); - return mm->dev->kfd2kgd->hqd_load(mm->dev->adev, mqd, pipe_id, queue_id, + return mm->dev->kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, (uint32_t __user *)p->write_ptr, wptr_shift, wptr_mask, mms); } static void __update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, struct mqd_update_info *minfo, - unsigned int mtype, unsigned int atc_bit) + struct queue_properties *q, unsigned int mtype, + unsigned int atc_bit) { struct vi_mqd *m; @@ -231,7 +230,7 @@ static void __update_mqd(struct mqd_manager *mm, void *mqd, atc_bit << CP_HQD_CTX_SAVE_CONTROL__ATC__SHIFT | mtype << CP_HQD_CTX_SAVE_CONTROL__MTYPE__SHIFT; - update_cu_mask(mm, mqd, minfo); + update_cu_mask(mm, mqd, q); set_priority(m, q); q->is_active = QUEUE_IS_ACTIVE(*q); @@ -239,10 +238,9 @@ static void __update_mqd(struct mqd_manager *mm, void *mqd, static void update_mqd(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { - __update_mqd(mm, mqd, q, minfo, MTYPE_CC, 1); + __update_mqd(mm, mqd, q, MTYPE_CC, 1); } static uint32_t read_doorbell_id(void *mqd) @@ -253,10 +251,9 @@ static uint32_t read_doorbell_id(void *mqd) } static void update_mqd_tonga(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { - __update_mqd(mm, mqd, q, minfo, MTYPE_UC, 0); + __update_mqd(mm, mqd, q, MTYPE_UC, 0); } static int destroy_mqd(struct mqd_manager *mm, void *mqd, @@ -265,7 +262,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_destroy - (mm->dev->adev, mqd, type, timeout, + (mm->dev->kgd, mqd, type, timeout, pipe_id, queue_id); } @@ -280,7 +277,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, uint32_t queue_id) { return mm->dev->kfd2kgd->hqd_is_occupied( - mm->dev->adev, queue_address, + mm->dev->kgd, queue_address, pipe_id, queue_id); } @@ -320,10 +317,9 @@ static void init_mqd_hiq(struct mqd_manager *mm, void **mqd, } static void update_mqd_hiq(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { - __update_mqd(mm, mqd, q, minfo, MTYPE_UC, 0); + __update_mqd(mm, mqd, q, MTYPE_UC, 0); } static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, @@ -340,21 +336,20 @@ static void init_mqd_sdma(struct mqd_manager *mm, void **mqd, if (gart_addr) *gart_addr = mqd_mem_obj->gpu_addr; - mm->update_mqd(mm, m, q, NULL); + mm->update_mqd(mm, m, q); } static int load_mqd_sdma(struct mqd_manager *mm, void *mqd, uint32_t pipe_id, uint32_t queue_id, struct queue_properties *p, struct mm_struct *mms) { - return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->adev, mqd, + return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd, (uint32_t __user *)p->write_ptr, mms); } static void update_mqd_sdma(struct mqd_manager *mm, void *mqd, - struct queue_properties *q, - struct mqd_update_info *minfo) + struct queue_properties *q) { struct vi_sdma_mqd *m; @@ -389,14 +384,14 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd, unsigned int timeout, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->adev, mqd, timeout); + return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout); } static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id) { - return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->adev, mqd); + return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd); } #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c index 1439420925..e547f1f8c4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c @@ -223,7 +223,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm, int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) { - switch (dqm->dev->adev->asic_type) { + switch (dqm->dev->device_info->asic_family) { case CHIP_KAVERI: case CHIP_HAWAII: /* PM4 packet structures on CIK are the same as on VI */ @@ -236,16 +236,31 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) case CHIP_VEGAM: pm->pmf = &kfd_vi_pm_funcs; break; + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_RENOIR: + case CHIP_ARCTURUS: + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + pm->pmf = &kfd_v9_pm_funcs; + break; + case CHIP_ALDEBARAN: + pm->pmf = &kfd_aldebaran_pm_funcs; + break; default: - if (KFD_GC_VERSION(dqm->dev) == IP_VERSION(9, 4, 2)) - pm->pmf = &kfd_aldebaran_pm_funcs; - else if (KFD_GC_VERSION(dqm->dev) >= IP_VERSION(9, 0, 1)) - pm->pmf = &kfd_v9_pm_funcs; - else { - WARN(1, "Unexpected ASIC family %u", - dqm->dev->adev->asic_type); - return -EINVAL; - } + WARN(1, "Unexpected ASIC family %u", + dqm->dev->device_info->asic_family); + return -EINVAL; } pm->dqm = dqm; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c index 3c0658e32e..08442e7d99 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_vi.c @@ -110,8 +110,8 @@ static int pm_runlist_vi(struct packet_manager *pm, uint32_t *buffer, return 0; } -static int pm_set_resources_vi(struct packet_manager *pm, uint32_t *buffer, - struct scheduling_resources *res) +int pm_set_resources_vi(struct packet_manager *pm, uint32_t *buffer, + struct scheduling_resources *res) { struct pm4_mes_set_resources *packet; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index ea68f3b3a4..6d8f9bb2d9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -183,8 +183,7 @@ enum cache_policy { cache_policy_noncoherent }; -#define KFD_GC_VERSION(dev) ((dev)->adev->ip_versions[GC_HWIP][0]) -#define KFD_IS_SOC15(dev) ((KFD_GC_VERSION(dev)) >= (IP_VERSION(9, 0, 1))) +#define KFD_IS_SOC15(chip) ((chip) >= CHIP_VEGA10) struct kfd_event_interrupt_class { bool (*interrupt_isr)(struct kfd_dev *dev, @@ -195,6 +194,8 @@ struct kfd_event_interrupt_class { }; struct kfd_device_info { + enum amd_asic_type asic_family; + const char *asic_name; uint32_t gfx_target_version; const struct kfd_event_interrupt_class *event_interrupt_class; unsigned int max_pasid_bits; @@ -207,12 +208,11 @@ struct kfd_device_info { bool needs_iommu_device; bool needs_pci_atomics; uint32_t no_atomic_fw_version; + unsigned int num_sdma_engines; + unsigned int num_xgmi_sdma_engines; unsigned int num_sdma_queues_per_engine; }; -unsigned int kfd_get_num_sdma_engines(struct kfd_dev *kdev); -unsigned int kfd_get_num_xgmi_sdma_engines(struct kfd_dev *kdev); - struct kfd_mem_obj { uint32_t range_start; uint32_t range_end; @@ -228,9 +228,9 @@ struct kfd_vmid_info { }; struct kfd_dev { - struct amdgpu_device *adev; + struct kgd_dev *kgd; - struct kfd_device_info device_info; + const struct kfd_device_info *device_info; struct pci_dev *pdev; struct drm_device *ddev; @@ -472,6 +472,9 @@ struct queue_properties { uint32_t ctl_stack_size; uint64_t tba_addr; uint64_t tma_addr; + /* Relevant for CU */ + uint32_t cu_mask_count; /* Must be a multiple of 32 */ + uint32_t *cu_mask; }; #define QUEUE_IS_ACTIVE(q) ((q).queue_size > 0 && \ @@ -479,20 +482,6 @@ struct queue_properties { (q).queue_percent > 0 && \ !(q).is_evicted) -enum mqd_update_flag { - UPDATE_FLAG_CU_MASK = 0, -}; - -struct mqd_update_info { - union { - struct { - uint32_t count; /* Must be a multiple of 32 */ - uint32_t *ptr; - } cu_mask; - }; - enum mqd_update_flag update_flag; -}; - /** * struct queue * @@ -619,14 +608,12 @@ struct qcm_process_device { uint32_t sh_hidden_private_base; /* CWSR memory */ - struct kgd_mem *cwsr_mem; void *cwsr_kaddr; uint64_t cwsr_base; uint64_t tba_addr; uint64_t tma_addr; /* IB memory */ - struct kgd_mem *ib_mem; uint64_t ib_base; void *ib_kaddr; @@ -766,10 +753,8 @@ struct svm_range_list { struct list_head deferred_range_list; spinlock_t deferred_list_lock; atomic_t evicted_ranges; - atomic_t drain_pagefaults; struct delayed_work restore_work; DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE); - struct task_struct *faulting_task; }; /* Process data */ @@ -823,7 +808,6 @@ struct kfd_process { /* Event ID allocator and lookup */ struct idr event_idr; /* Event page */ - u64 signal_handle; struct kfd_signal_page *signal_page; size_t signal_mapped_size; size_t signal_event_count; @@ -856,8 +840,6 @@ struct kfd_process { struct svm_range_list svms; bool xnack_enabled; - - atomic_t poison; }; #define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */ @@ -893,7 +875,7 @@ struct kfd_process *kfd_lookup_process_by_pasid(u32 pasid); struct kfd_process *kfd_lookup_process_by_mm(const struct mm_struct *mm); int kfd_process_gpuidx_from_gpuid(struct kfd_process *p, uint32_t gpu_id); -int kfd_process_gpuid_from_adev(struct kfd_process *p, +int kfd_process_gpuid_from_kgd(struct kfd_process *p, struct amdgpu_device *adev, uint32_t *gpuid, uint32_t *gpuidx); static inline int kfd_process_gpuid_from_gpuidx(struct kfd_process *p, @@ -986,7 +968,7 @@ struct kfd_topology_device *kfd_topology_device_by_proximity_domain( struct kfd_topology_device *kfd_topology_device_by_id(uint32_t gpu_id); struct kfd_dev *kfd_device_by_id(uint32_t gpu_id); struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); -struct kfd_dev *kfd_device_by_adev(const struct amdgpu_device *adev); +struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd); int kfd_topology_enum_kfd_devices(uint8_t idx, struct kfd_dev **kdev); int kfd_numa_node_to_apic_id(int numa_node_id); void kfd_double_confirm_iommu_support(struct kfd_dev *gpu); @@ -1049,10 +1031,10 @@ int pqm_create_queue(struct process_queue_manager *pqm, unsigned int *qid, uint32_t *p_doorbell_offset_in_process); int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid); -int pqm_update_queue_properties(struct process_queue_manager *pqm, unsigned int qid, +int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, + struct queue_properties *p); +int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid, struct queue_properties *p); -int pqm_update_mqd(struct process_queue_manager *pqm, unsigned int qid, - struct mqd_update_info *minfo); int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid, void *gws); struct kernel_queue *pqm_get_kernel_queue(struct process_queue_manager *pqm, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index d1145da534..21ec8a18ca 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -72,8 +72,6 @@ static int kfd_process_init_cwsr_apu(struct kfd_process *p, struct file *filep); static void evict_process_worker(struct work_struct *work); static void restore_process_worker(struct work_struct *work); -static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd); - struct kfd_procfs_tree { struct kobject *kobj; }; @@ -251,13 +249,14 @@ static void kfd_sdma_activity_worker(struct work_struct *work) } /** - * kfd_get_cu_occupancy - Collect number of waves in-flight on this device + * @kfd_get_cu_occupancy - Collect number of waves in-flight on this device * by current process. Translates acquired wave count into number of compute units * that are occupied. * - * @attr: Handle of attribute that allows reporting of wave count. The attribute + * @atr: Handle of attribute that allows reporting of wave count. The attribute * handle encapsulates GPU device it is associated with, thereby allowing collection * of waves in flight, etc + * * @buffer: Handle of user provided buffer updated with wave count * * Return: Number of bytes written to user buffer or an error value @@ -287,7 +286,7 @@ static int kfd_get_cu_occupancy(struct attribute *attr, char *buffer) /* Collect wave count from device if it supports */ wave_cnt = 0; max_waves_per_cu = 0; - dev->kfd2kgd->get_cu_occupancy(dev->adev, proc->pasid, &wave_cnt, + dev->kfd2kgd->get_cu_occupancy(dev->kgd, proc->pasid, &wave_cnt, &max_waves_per_cu); /* Translate wave count to number of compute units */ @@ -461,7 +460,6 @@ static struct attribute *procfs_queue_attrs[] = { &attr_queue_gpuid, NULL }; -ATTRIBUTE_GROUPS(procfs_queue); static const struct sysfs_ops procfs_queue_ops = { .show = kfd_procfs_queue_show, @@ -469,7 +467,7 @@ static const struct sysfs_ops procfs_queue_ops = { static struct kobj_type procfs_queue_type = { .sysfs_ops = &procfs_queue_ops, - .default_groups = procfs_queue_groups, + .default_attrs = procfs_queue_attrs, }; static const struct sysfs_ops procfs_stats_ops = { @@ -687,17 +685,12 @@ void kfd_process_destroy_wq(void) } static void kfd_process_free_gpuvm(struct kgd_mem *mem, - struct kfd_process_device *pdd, void *kptr) + struct kfd_process_device *pdd) { struct kfd_dev *dev = pdd->dev; - if (kptr) { - amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(dev->adev, mem); - kptr = NULL; - } - - amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv); - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->adev, mem, pdd->drm_priv, + amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->kgd, mem, pdd->drm_priv); + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, mem, pdd->drm_priv, NULL); } @@ -709,46 +702,63 @@ static void kfd_process_free_gpuvm(struct kgd_mem *mem, */ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd, uint64_t gpu_va, uint32_t size, - uint32_t flags, struct kgd_mem **mem, void **kptr) + uint32_t flags, void **kptr) { struct kfd_dev *kdev = pdd->dev; + struct kgd_mem *mem = NULL; + int handle; int err; - err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->adev, gpu_va, size, - pdd->drm_priv, mem, NULL, flags); + err = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(kdev->kgd, gpu_va, size, + pdd->drm_priv, &mem, NULL, flags); if (err) goto err_alloc_mem; - err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->adev, *mem, + err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem, pdd->drm_priv, NULL); if (err) goto err_map_mem; - err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->adev, *mem, true); + err = amdgpu_amdkfd_gpuvm_sync_memory(kdev->kgd, mem, true); if (err) { pr_debug("Sync memory failed, wait interrupted by user signal\n"); goto sync_memory_failed; } + /* Create an obj handle so kfd_process_device_remove_obj_handle + * will take care of the bo removal when the process finishes. + * We do not need to take p->mutex, because the process is just + * created and the ioctls have not had the chance to run. + */ + handle = kfd_process_device_create_obj_handle(pdd, mem); + + if (handle < 0) { + err = handle; + goto free_gpuvm; + } + if (kptr) { - err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->adev, - (struct kgd_mem *)*mem, kptr, NULL); + err = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(kdev->kgd, + (struct kgd_mem *)mem, kptr, NULL); if (err) { pr_debug("Map GTT BO to kernel failed\n"); - goto sync_memory_failed; + goto free_obj_handle; } } return err; +free_obj_handle: + kfd_process_device_remove_obj_handle(pdd, handle); +free_gpuvm: sync_memory_failed: - amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(kdev->adev, *mem, pdd->drm_priv); + kfd_process_free_gpuvm(mem, pdd); + return err; err_map_mem: - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->adev, *mem, pdd->drm_priv, + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(kdev->kgd, mem, pdd->drm_priv, NULL); err_alloc_mem: - *mem = NULL; *kptr = NULL; return err; } @@ -766,7 +776,6 @@ static int kfd_process_device_reserve_ib_mem(struct kfd_process_device *pdd) KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE | KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE | KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; - struct kgd_mem *mem; void *kaddr; int ret; @@ -775,26 +784,15 @@ static int kfd_process_device_reserve_ib_mem(struct kfd_process_device *pdd) /* ib_base is only set for dGPU */ ret = kfd_process_alloc_gpuvm(pdd, qpd->ib_base, PAGE_SIZE, flags, - &mem, &kaddr); + &kaddr); if (ret) return ret; - qpd->ib_mem = mem; qpd->ib_kaddr = kaddr; return 0; } -static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd) -{ - struct qcm_process_device *qpd = &pdd->qpd; - - if (!qpd->ib_kaddr || !qpd->ib_base) - return; - - kfd_process_free_gpuvm(qpd->ib_mem, pdd, qpd->ib_kaddr); -} - struct kfd_process *kfd_create_process(struct file *filep) { struct kfd_process *process; @@ -940,46 +938,15 @@ static void kfd_process_device_free_bos(struct kfd_process_device *pdd) if (!peer_pdd->drm_priv) continue; amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( - peer_pdd->dev->adev, mem, peer_pdd->drm_priv); + peer_pdd->dev->kgd, mem, peer_pdd->drm_priv); } - amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->adev, mem, + amdgpu_amdkfd_gpuvm_free_memory_of_gpu(pdd->dev->kgd, mem, pdd->drm_priv, NULL); kfd_process_device_remove_obj_handle(pdd, id); } } -/* - * Just kunmap and unpin signal BO here. It will be freed in - * kfd_process_free_outstanding_kfd_bos() - */ -static void kfd_process_kunmap_signal_bo(struct kfd_process *p) -{ - struct kfd_process_device *pdd; - struct kfd_dev *kdev; - void *mem; - - kdev = kfd_device_by_id(GET_GPU_ID(p->signal_handle)); - if (!kdev) - return; - - mutex_lock(&p->mutex); - - pdd = kfd_get_process_device_data(kdev, p); - if (!pdd) - goto out; - - mem = kfd_process_device_translate_handle( - pdd, GET_IDR_HANDLE(p->signal_handle)); - if (!mem) - goto out; - - amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(kdev->adev, mem); - -out: - mutex_unlock(&p->mutex); -} - static void kfd_process_free_outstanding_kfd_bos(struct kfd_process *p) { int i; @@ -998,12 +965,9 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) pr_debug("Releasing pdd (topology id %d) for process (pasid 0x%x)\n", pdd->dev->id, p->pasid); - kfd_process_device_destroy_cwsr_dgpu(pdd); - kfd_process_device_destroy_ib_mem(pdd); - if (pdd->drm_file) { amdgpu_amdkfd_gpuvm_release_process_vm( - pdd->dev->adev, pdd->drm_priv); + pdd->dev->kgd, pdd->drm_priv); fput(pdd->drm_file); } @@ -1011,7 +975,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p) free_pages((unsigned long)pdd->qpd.cwsr_kaddr, get_order(KFD_CWSR_TBA_TMA_SIZE)); - bitmap_free(pdd->qpd.doorbell_bitmap); + kfree(pdd->qpd.doorbell_bitmap); idr_destroy(&pdd->alloc_idr); kfd_free_process_doorbells(pdd->dev, pdd->doorbell_index); @@ -1085,11 +1049,9 @@ static void kfd_process_wq_release(struct work_struct *work) { struct kfd_process *p = container_of(work, struct kfd_process, release_work); - kfd_process_remove_sysfs(p); kfd_iommu_unbind_process(p); - kfd_process_kunmap_signal_bo(p); kfd_process_free_outstanding_kfd_bos(p); svm_range_list_fini(p); @@ -1236,7 +1198,6 @@ static int kfd_process_device_init_cwsr_dgpu(struct kfd_process_device *pdd) uint32_t flags = KFD_IOC_ALLOC_MEM_FLAGS_GTT | KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE | KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; - struct kgd_mem *mem; void *kaddr; int ret; @@ -1245,11 +1206,10 @@ static int kfd_process_device_init_cwsr_dgpu(struct kfd_process_device *pdd) /* cwsr_base is only set for dGPU */ ret = kfd_process_alloc_gpuvm(pdd, qpd->cwsr_base, - KFD_CWSR_TBA_TMA_SIZE, flags, &mem, &kaddr); + KFD_CWSR_TBA_TMA_SIZE, flags, &kaddr); if (ret) return ret; - qpd->cwsr_mem = mem; qpd->cwsr_kaddr = kaddr; qpd->tba_addr = qpd->cwsr_base; @@ -1262,17 +1222,6 @@ static int kfd_process_device_init_cwsr_dgpu(struct kfd_process_device *pdd) return 0; } -static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd) -{ - struct kfd_dev *dev = pdd->dev; - struct qcm_process_device *qpd = &pdd->qpd; - - if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base) - return; - - kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, qpd->cwsr_kaddr); -} - void kfd_process_set_trap_handler(struct qcm_process_device *qpd, uint64_t tba_addr, uint64_t tma_addr) @@ -1317,13 +1266,14 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported) * support the SVM APIs and don't need to be considered * for the XNACK mode selection. */ - if (!KFD_IS_SOC15(dev)) + if (dev->device_info->asic_family < CHIP_VEGA10) continue; /* Aldebaran can always support XNACK because it can support * per-process XNACK mode selection. But let the dev->noretry * setting still influence the default XNACK mode. */ - if (supported && KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2)) + if (supported && + dev->device_info->asic_family == CHIP_ALDEBARAN) continue; /* GFXv10 and later GPUs do not support shader preemption @@ -1331,7 +1281,7 @@ bool kfd_process_xnack_mode(struct kfd_process *p, bool supported) * management and memory-manager-related preemptions or * even deadlocks. */ - if (KFD_GC_VERSION(dev) >= IP_VERSION(10, 1, 1)) + if (dev->device_info->asic_family >= CHIP_NAVI10) return false; if (dev->noretry) @@ -1430,11 +1380,12 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd, int range_start = dev->shared_resources.non_cp_doorbells_start; int range_end = dev->shared_resources.non_cp_doorbells_end; - if (!KFD_IS_SOC15(dev)) + if (!KFD_IS_SOC15(dev->device_info->asic_family)) return 0; - qpd->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, - GFP_KERNEL); + qpd->doorbell_bitmap = + kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, + BITS_PER_BYTE), GFP_KERNEL); if (!qpd->doorbell_bitmap) return -ENOMEM; @@ -1446,9 +1397,9 @@ static int init_doorbell_bitmap(struct qcm_process_device *qpd, for (i = 0; i < KFD_MAX_NUM_OF_QUEUES_PER_PROCESS / 2; i++) { if (i >= range_start && i <= range_end) { - __set_bit(i, qpd->doorbell_bitmap); - __set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET, - qpd->doorbell_bitmap); + set_bit(i, qpd->doorbell_bitmap); + set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET, + qpd->doorbell_bitmap); } } @@ -1545,7 +1496,7 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, dev = pdd->dev; ret = amdgpu_amdkfd_gpuvm_acquire_process_vm( - dev->adev, drm_file, p->pasid, + dev->kgd, drm_file, p->pasid, &p->kgd_process_info, &p->ef); if (ret) { pr_err("Failed to create process VM object\n"); @@ -1713,11 +1664,7 @@ int kfd_process_evict_queues(struct kfd_process *p) r = pdd->dev->dqm->ops.evict_process_queues(pdd->dev->dqm, &pdd->qpd); - /* evict return -EIO if HWS is hang or asic is resetting, in this case - * we would like to set all the queues to be in evicted state to prevent - * them been add back since they actually not be saved right now. - */ - if (r && r != -EIO) { + if (r) { pr_err("Failed to evict process queues\n"); goto fail; } @@ -1777,13 +1724,14 @@ int kfd_process_gpuidx_from_gpuid(struct kfd_process *p, uint32_t gpu_id) } int -kfd_process_gpuid_from_adev(struct kfd_process *p, struct amdgpu_device *adev, +kfd_process_gpuid_from_kgd(struct kfd_process *p, struct amdgpu_device *adev, uint32_t *gpuid, uint32_t *gpuidx) { + struct kgd_dev *kgd = (struct kgd_dev *)adev; int i; for (i = 0; i < p->n_pdds; i++) - if (p->pdds[i] && p->pdds[i]->dev->adev == adev) { + if (p->pdds[i] && p->pdds[i]->dev->kgd == kgd) { *gpuid = p->pdds[i]->dev->id; *gpuidx = i; return 0; @@ -1948,10 +1896,10 @@ void kfd_flush_tlb(struct kfd_process_device *pdd, enum TLB_FLUSH_TYPE type) * only happens when the first queue is created. */ if (pdd->qpd.vmid) - amdgpu_amdkfd_flush_gpu_tlb_vmid(dev->adev, + amdgpu_amdkfd_flush_gpu_tlb_vmid(dev->kgd, pdd->qpd.vmid); } else { - amdgpu_amdkfd_flush_gpu_tlb_pasid(dev->adev, + amdgpu_amdkfd_flush_gpu_tlb_pasid(dev->kgd, pdd->process->pasid, type); } } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 5e5c84a8e1..243dd1efcd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -118,10 +118,10 @@ int pqm_set_gws(struct process_queue_manager *pqm, unsigned int qid, return ret; pqn->q->gws = mem; - pdd->qpd.num_gws = gws ? dev->adev->gds.gws_size : 0; + pdd->qpd.num_gws = gws ? amdgpu_amdkfd_get_num_gws(dev->kgd) : 0; return pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, - pqn->q, NULL); + pqn->q); } void kfd_process_dequeue_from_all_devices(struct kfd_process *p) @@ -135,8 +135,9 @@ void kfd_process_dequeue_from_all_devices(struct kfd_process *p) int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) { INIT_LIST_HEAD(&pqm->queues); - pqm->queue_slot_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, - GFP_KERNEL); + pqm->queue_slot_bitmap = + kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, + BITS_PER_BYTE), GFP_KERNEL); if (!pqm->queue_slot_bitmap) return -ENOMEM; pqm->process = p; @@ -158,7 +159,7 @@ void pqm_uninit(struct process_queue_manager *pqm) kfree(pqn); } - bitmap_free(pqm->queue_slot_bitmap); + kfree(pqm->queue_slot_bitmap); pqm->queue_slot_bitmap = NULL; } @@ -219,7 +220,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, * Hence we also check the type as well */ if ((pdd->qpd.is_debug) || (type == KFD_QUEUE_TYPE_DIQ)) - max_queues = dev->device_info.max_no_of_hqd/2; + max_queues = dev->device_info->max_no_of_hqd/2; if (pdd->qpd.queue_count >= max_queues) return -ENOSPC; @@ -393,6 +394,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) pdd->qpd.num_gws = 0; } + kfree(pqn->q->properties.cu_mask); + pqn->q->properties.cu_mask = NULL; uninit_queue(pqn->q); } @@ -408,8 +411,8 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) return retval; } -int pqm_update_queue_properties(struct process_queue_manager *pqm, - unsigned int qid, struct queue_properties *p) +int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid, + struct queue_properties *p) { int retval; struct process_queue_node *pqn; @@ -426,15 +429,15 @@ int pqm_update_queue_properties(struct process_queue_manager *pqm, pqn->q->properties.priority = p->priority; retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, - pqn->q, NULL); + pqn->q); if (retval != 0) return retval; return 0; } -int pqm_update_mqd(struct process_queue_manager *pqm, - unsigned int qid, struct mqd_update_info *minfo) +int pqm_set_cu_mask(struct process_queue_manager *pqm, unsigned int qid, + struct queue_properties *p) { int retval; struct process_queue_node *pqn; @@ -445,8 +448,16 @@ int pqm_update_mqd(struct process_queue_manager *pqm, return -EFAULT; } + /* Free the old CU mask memory if it is already allocated, then + * allocate memory for the new CU mask. + */ + kfree(pqn->q->properties.cu_mask); + + pqn->q->properties.cu_mask_count = p->cu_mask_count; + pqn->q->properties.cu_mask = p->cu_mask; + retval = pqn->q->device->dqm->ops.update_queue(pqn->q->device->dqm, - pqn->q, minfo); + pqn->q); if (retval != 0) return retval; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c index deae12dc77..ed4bc5f844 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c @@ -207,6 +207,7 @@ void kfd_smi_event_update_gpu_reset(struct kfd_dev *dev, bool post_reset) void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev, uint64_t throttle_bitmask) { + struct amdgpu_device *adev = (struct amdgpu_device *)dev->kgd; /* * ThermalThrottle msg = throttle_bitmask(8): * thermal_interrupt_count(16): @@ -222,13 +223,14 @@ void kfd_smi_event_update_thermal_throttling(struct kfd_dev *dev, len = snprintf(fifo_in, sizeof(fifo_in), "%x %llx:%llx\n", KFD_SMI_EVENT_THERMAL_THROTTLE, throttle_bitmask, - atomic64_read(&dev->adev->smu.throttle_int_counter)); + atomic64_read(&adev->smu.throttle_int_counter)); add_event_to_kfifo(dev, KFD_SMI_EVENT_THERMAL_THROTTLE, fifo_in, len); } void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid) { + struct amdgpu_device *adev = (struct amdgpu_device *)dev->kgd; struct amdgpu_task_info task_info; /* VmFault msg = (hex)uint32_pid(8) + :(1) + task name(16) = 25 */ /* 1 byte event + 1 byte space + 25 bytes msg + 1 byte \n + @@ -241,7 +243,7 @@ void kfd_smi_event_update_vmfault(struct kfd_dev *dev, uint16_t pasid) return; memset(&task_info, 0, sizeof(struct amdgpu_task_info)); - amdgpu_vm_get_task_info(dev->adev, pasid, &task_info); + amdgpu_vm_get_task_info(adev, pasid, &task_info); /* Report VM faults from user applications, not retry from kernel */ if (!task_info.pid) return; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index f2805ba74c..830809b694 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -33,11 +33,6 @@ #include "kfd_svm.h" #include "kfd_migrate.h" -#ifdef dev_fmt -#undef dev_fmt -#endif -#define dev_fmt(fmt) "kfd_svm: %s: " fmt, __func__ - #define AMDGPU_SVM_RANGE_RESTORE_DELAY_MS 1 /* Long enough to ensure no retry fault comes after svm range is restored and @@ -50,9 +45,7 @@ static bool svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, const struct mmu_notifier_range *range, unsigned long cur_seq); -static int -svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last, - uint64_t *bo_s, uint64_t *bo_l); + static const struct mmu_interval_notifier_ops svm_range_mn_ops = { .invalidate = svm_range_cpu_invalidate_pagetables, }; @@ -107,7 +100,7 @@ static void svm_range_add_to_svms(struct svm_range *prange) pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms, prange, prange->start, prange->last); - list_move_tail(&prange->list, &prange->svms->list); + list_add_tail(&prange->list, &prange->svms->list); prange->it_node.start = prange->start; prange->it_node.last = prange->last; interval_tree_insert(&prange->it_node, &prange->svms->objects); @@ -165,17 +158,17 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, bo_adev->vm_manager.vram_base_offset - bo_adev->kfd.dev->pgmap.range.start; addr[i] |= SVM_RANGE_VRAM_DOMAIN; - pr_debug_ratelimited("vram address: 0x%llx\n", addr[i]); + pr_debug("vram address detected: 0x%llx\n", addr[i]); continue; } addr[i] = dma_map_page(dev, page, 0, PAGE_SIZE, dir); r = dma_mapping_error(dev, addr[i]); if (r) { - dev_err(dev, "failed %d dma_map_page\n", r); + pr_debug("failed %d dma_map_page\n", r); return r; } - pr_debug_ratelimited("dma mapping 0x%llx for page addr 0x%lx\n", - addr[i] >> PAGE_SHIFT, page_to_pfn(page)); + pr_debug("dma mapping 0x%llx for page addr 0x%lx\n", + addr[i] >> PAGE_SHIFT, page_to_pfn(page)); } return 0; } @@ -193,6 +186,7 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap, for_each_set_bit(gpuidx, bitmap, MAX_GPU_INSTANCE) { struct kfd_process_device *pdd; + struct amdgpu_device *adev; pr_debug("mapping to gpu idx 0x%x\n", gpuidx); pdd = kfd_process_device_from_gpuidx(p, gpuidx); @@ -200,8 +194,9 @@ svm_range_dma_map(struct svm_range *prange, unsigned long *bitmap, pr_debug("failed to find device idx %d\n", gpuidx); return -EINVAL; } + adev = (struct amdgpu_device *)pdd->dev->kgd; - r = svm_range_dma_map_dev(pdd->dev->adev, prange, offset, npages, + r = svm_range_dma_map_dev(adev, prange, offset, npages, hmm_pfns, gpuidx); if (r) break; @@ -222,7 +217,7 @@ void svm_range_dma_unmap(struct device *dev, dma_addr_t *dma_addr, for (i = offset; i < offset + npages; i++) { if (!svm_is_valid_dma_mapping_addr(dev, dma_addr[i])) continue; - pr_debug_ratelimited("unmap 0x%llx\n", dma_addr[i] >> PAGE_SHIFT); + pr_debug("dma unmapping 0x%llx\n", dma_addr[i] >> PAGE_SHIFT); dma_unmap_page(dev, dma_addr[i], PAGE_SIZE, dir); dma_addr[i] = 0; } @@ -295,6 +290,8 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start, prange->last = last; INIT_LIST_HEAD(&prange->list); INIT_LIST_HEAD(&prange->update_list); + INIT_LIST_HEAD(&prange->remove_list); + INIT_LIST_HEAD(&prange->insert_list); INIT_LIST_HEAD(&prange->svm_bo_list); INIT_LIST_HEAD(&prange->deferred_list); INIT_LIST_HEAD(&prange->child_list); @@ -330,8 +327,6 @@ static void svm_range_bo_release(struct kref *kref) struct svm_range_bo *svm_bo; svm_bo = container_of(kref, struct svm_range_bo, kref); - pr_debug("svm_bo 0x%p\n", svm_bo); - spin_lock(&svm_bo->list_lock); while (!list_empty(&svm_bo->range_list)) { struct svm_range *prange = @@ -365,33 +360,12 @@ static void svm_range_bo_release(struct kref *kref) kfree(svm_bo); } -static void svm_range_bo_wq_release(struct work_struct *work) +void svm_range_bo_unref(struct svm_range_bo *svm_bo) { - struct svm_range_bo *svm_bo; + if (!svm_bo) + return; - svm_bo = container_of(work, struct svm_range_bo, release_work); - svm_range_bo_release(&svm_bo->kref); -} - -static void svm_range_bo_release_async(struct kref *kref) -{ - struct svm_range_bo *svm_bo; - - svm_bo = container_of(kref, struct svm_range_bo, kref); - pr_debug("svm_bo 0x%p\n", svm_bo); - INIT_WORK(&svm_bo->release_work, svm_range_bo_wq_release); - schedule_work(&svm_bo->release_work); -} - -void svm_range_bo_unref_async(struct svm_range_bo *svm_bo) -{ - kref_put(&svm_bo->kref, svm_range_bo_release_async); -} - -static void svm_range_bo_unref(struct svm_range_bo *svm_bo) -{ - if (svm_bo) - kref_put(&svm_bo->kref, svm_range_bo_release); + kref_put(&svm_bo->kref, svm_range_bo_release); } static bool @@ -600,7 +574,7 @@ svm_range_get_adev_by_id(struct svm_range *prange, uint32_t gpu_id) return NULL; } - return pdd->dev->adev; + return (struct amdgpu_device *)pdd->dev->kgd; } struct kfd_process_device * @@ -612,7 +586,7 @@ svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev) p = container_of(prange->svms, struct kfd_process, svms); - r = kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpu_idx); + r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpu_idx); if (r) { pr_debug("failed to get device id by adev %p\n", adev); return NULL; @@ -725,61 +699,6 @@ svm_range_apply_attrs(struct kfd_process *p, struct svm_range *prange, } } -static bool -svm_range_is_same_attrs(struct kfd_process *p, struct svm_range *prange, - uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs) -{ - uint32_t i; - int gpuidx; - - for (i = 0; i < nattr; i++) { - switch (attrs[i].type) { - case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: - if (prange->preferred_loc != attrs[i].value) - return false; - break; - case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC: - /* Prefetch should always trigger a migration even - * if the value of the attribute didn't change. - */ - return false; - case KFD_IOCTL_SVM_ATTR_ACCESS: - case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE: - case KFD_IOCTL_SVM_ATTR_NO_ACCESS: - gpuidx = kfd_process_gpuidx_from_gpuid(p, - attrs[i].value); - if (attrs[i].type == KFD_IOCTL_SVM_ATTR_NO_ACCESS) { - if (test_bit(gpuidx, prange->bitmap_access) || - test_bit(gpuidx, prange->bitmap_aip)) - return false; - } else if (attrs[i].type == KFD_IOCTL_SVM_ATTR_ACCESS) { - if (!test_bit(gpuidx, prange->bitmap_access)) - return false; - } else { - if (!test_bit(gpuidx, prange->bitmap_aip)) - return false; - } - break; - case KFD_IOCTL_SVM_ATTR_SET_FLAGS: - if ((prange->flags & attrs[i].value) != attrs[i].value) - return false; - break; - case KFD_IOCTL_SVM_ATTR_CLR_FLAGS: - if ((prange->flags & attrs[i].value) != 0) - return false; - break; - case KFD_IOCTL_SVM_ATTR_GRANULARITY: - if (prange->granularity != attrs[i].value) - return false; - break; - default: - WARN_ONCE(1, "svm_range_check_attrs wasn't called?"); - } - } - - return true; -} - /** * svm_range_debug_dump - print all range information from svms * @svms: svm range list header @@ -817,6 +736,14 @@ static void svm_range_debug_dump(struct svm_range_list *svms) } } +static bool +svm_range_is_same_attrs(struct svm_range *old, struct svm_range *new) +{ + return (old->prefetch_loc == new->prefetch_loc && + old->flags == new->flags && + old->granularity == new->granularity); +} + static int svm_range_split_array(void *ppnew, void *ppold, size_t size, uint64_t old_start, uint64_t old_n, @@ -1016,7 +943,7 @@ svm_range_split_tail(struct svm_range *prange, int r = svm_range_split(prange, prange->start, new_last, &tail); if (!r) - list_add(&tail->list, insert_list); + list_add(&tail->insert_list, insert_list); return r; } @@ -1028,7 +955,7 @@ svm_range_split_head(struct svm_range *prange, int r = svm_range_split(prange, new_start, prange->last, &head); if (!r) - list_add(&head->list, insert_list); + list_add(&head->insert_list, insert_list); return r; } @@ -1119,8 +1046,8 @@ svm_range_get_pte_flags(struct amdgpu_device *adev, struct svm_range *prange, if (domain == SVM_RANGE_VRAM_DOMAIN) bo_adev = amdgpu_ttm_adev(prange->svm_bo->bo->tbo.bdev); - switch (KFD_GC_VERSION(adev->kfd.dev)) { - case IP_VERSION(9, 4, 1): + switch (adev->asic_type) { + case CHIP_ARCTURUS: if (domain == SVM_RANGE_VRAM_DOMAIN) { if (bo_adev == adev) { mapping_flags |= coherent ? @@ -1136,7 +1063,7 @@ svm_range_get_pte_flags(struct amdgpu_device *adev, struct svm_range *prange, AMDGPU_VM_MTYPE_UC : AMDGPU_VM_MTYPE_NC; } break; - case IP_VERSION(9, 4, 2): + case CHIP_ALDEBARAN: if (domain == SVM_RANGE_VRAM_DOMAIN) { if (bo_adev == adev) { mapping_flags |= coherent ? @@ -1195,6 +1122,7 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, DECLARE_BITMAP(bitmap, MAX_GPU_INSTANCE); struct kfd_process_device *pdd; struct dma_fence *fence = NULL; + struct amdgpu_device *adev; struct kfd_process *p; uint32_t gpuidx; int r = 0; @@ -1210,9 +1138,9 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, pr_debug("failed to find device idx %d\n", gpuidx); return -EINVAL; } + adev = (struct amdgpu_device *)pdd->dev->kgd; - r = svm_range_unmap_from_gpu(pdd->dev->adev, - drm_priv_to_vm(pdd->drm_priv), + r = svm_range_unmap_from_gpu(adev, drm_priv_to_vm(pdd->drm_priv), start, last, &fence); if (r) break; @@ -1224,7 +1152,7 @@ svm_range_unmap_from_gpus(struct svm_range *prange, unsigned long start, if (r) break; } - amdgpu_amdkfd_flush_gpu_tlb_pasid(pdd->dev->adev, + amdgpu_amdkfd_flush_gpu_tlb_pasid((struct kgd_dev *)adev, p->pasid, TLB_FLUSH_HEAVYWEIGHT); } @@ -1237,6 +1165,7 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned long npages, bool readonly, dma_addr_t *dma_addr, struct amdgpu_device *bo_adev, struct dma_fence **fence) { + struct amdgpu_bo_va bo_va; bool table_freed = false; uint64_t pte_flags; unsigned long last_start; @@ -1249,6 +1178,9 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, pr_debug("svms 0x%p [0x%lx 0x%lx] readonly %d\n", prange->svms, last_start, last_start + npages - 1, readonly); + if (prange->svm_bo && prange->ttm_res) + bo_va.is_xgmi = amdgpu_xgmi_same_hive(adev, bo_adev); + for (i = offset; i < offset + npages; i++) { last_domain = dma_addr[i] & SVM_RANGE_VRAM_DOMAIN; dma_addr[i] &= ~SVM_RANGE_VRAM_DOMAIN; @@ -1304,7 +1236,8 @@ svm_range_map_to_gpu(struct amdgpu_device *adev, struct amdgpu_vm *vm, struct kfd_process *p; p = container_of(prange->svms, struct kfd_process, svms); - amdgpu_amdkfd_flush_gpu_tlb_pasid(adev, p->pasid, TLB_FLUSH_LEGACY); + amdgpu_amdkfd_flush_gpu_tlb_pasid((struct kgd_dev *)adev, + p->pasid, TLB_FLUSH_LEGACY); } out: return r; @@ -1317,6 +1250,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset, { struct kfd_process_device *pdd; struct amdgpu_device *bo_adev; + struct amdgpu_device *adev; struct kfd_process *p; struct dma_fence *fence = NULL; uint32_t gpuidx; @@ -1335,18 +1269,19 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset, pr_debug("failed to find device idx %d\n", gpuidx); return -EINVAL; } + adev = (struct amdgpu_device *)pdd->dev->kgd; pdd = kfd_bind_process_to_device(pdd->dev, p); if (IS_ERR(pdd)) return -EINVAL; - if (bo_adev && pdd->dev->adev != bo_adev && - !amdgpu_xgmi_same_hive(pdd->dev->adev, bo_adev)) { + if (bo_adev && adev != bo_adev && + !amdgpu_xgmi_same_hive(adev, bo_adev)) { pr_debug("cannot map to device idx %d\n", gpuidx); continue; } - r = svm_range_map_to_gpu(pdd->dev->adev, drm_priv_to_vm(pdd->drm_priv), + r = svm_range_map_to_gpu(adev, drm_priv_to_vm(pdd->drm_priv), prange, offset, npages, readonly, prange->dma_addr[gpuidx], bo_adev, wait ? &fence : NULL); @@ -1380,6 +1315,7 @@ struct svm_validate_context { static int svm_range_reserve_bos(struct svm_validate_context *ctx) { struct kfd_process_device *pdd; + struct amdgpu_device *adev; struct amdgpu_vm *vm; uint32_t gpuidx; int r; @@ -1391,6 +1327,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx) pr_debug("failed to find device idx %d\n", gpuidx); return -EINVAL; } + adev = (struct amdgpu_device *)pdd->dev->kgd; vm = drm_priv_to_vm(pdd->drm_priv); ctx->tv[gpuidx].bo = &vm->root.bo->tbo; @@ -1412,9 +1349,9 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx) r = -EINVAL; goto unreserve_out; } + adev = (struct amdgpu_device *)pdd->dev->kgd; - r = amdgpu_vm_validate_pt_bos(pdd->dev->adev, - drm_priv_to_vm(pdd->drm_priv), + r = amdgpu_vm_validate_pt_bos(adev, drm_priv_to_vm(pdd->drm_priv), svm_range_bo_validate, NULL); if (r) { pr_debug("failed %d validate pt bos\n", r); @@ -1437,10 +1374,12 @@ static void svm_range_unreserve_bos(struct svm_validate_context *ctx) static void *kfd_svm_page_owner(struct kfd_process *p, int32_t gpuidx) { struct kfd_process_device *pdd; + struct amdgpu_device *adev; pdd = kfd_process_device_from_gpuidx(p, gpuidx); + adev = (struct amdgpu_device *)pdd->dev->kgd; - return SVM_ADEV_PGMAP_OWNER(pdd->dev->adev); + return SVM_ADEV_PGMAP_OWNER(adev); } /* @@ -1515,7 +1454,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, /* This should never happen. actual_loc gets set by * svm_migrate_ram_to_vram after allocating a BO. */ - WARN_ONCE(1, "VRAM BO missing during validation\n"); + WARN(1, "VRAM BO missing during validation\n"); return -EINVAL; } @@ -1550,11 +1489,9 @@ static int svm_range_validate_and_map(struct mm_struct *mm, next = min(vma->vm_end, end); npages = (next - addr) >> PAGE_SHIFT; - WRITE_ONCE(p->svms.faulting_task, current); r = amdgpu_hmm_range_get_pages(&prange->notifier, mm, NULL, addr, npages, &hmm_range, readonly, true, owner); - WRITE_ONCE(p->svms.faulting_task, NULL); if (r) { pr_debug("failed %d to get svm range pages\n", r); goto unreserve_out; @@ -1610,7 +1547,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, * Context: Returns with mmap write lock held, pending deferred work flushed * */ -void +static void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm) { @@ -1714,10 +1651,6 @@ static void svm_range_restore_work(struct work_struct *work) /** * svm_range_evict - evict svm range - * @prange: svm range structure - * @mm: current process mm_struct - * @start: starting process queue number - * @last: last process queue number * * Stop all queues of the process to ensure GPU doesn't access the memory, then * return to let CPU evict the buffer and proceed CPU pagetable update. @@ -1859,6 +1792,7 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, unsigned long last = start + size - 1UL; struct svm_range_list *svms = &p->svms; struct interval_tree_node *node; + struct svm_range new = {0}; struct svm_range *prange; struct svm_range *tmp; int r = 0; @@ -1868,37 +1802,31 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, INIT_LIST_HEAD(update_list); INIT_LIST_HEAD(insert_list); INIT_LIST_HEAD(remove_list); + svm_range_apply_attrs(p, &new, nattr, attrs); node = interval_tree_iter_first(&svms->objects, start, last); while (node) { struct interval_tree_node *next; + struct svm_range *old; unsigned long next_start; pr_debug("found overlap node [0x%lx 0x%lx]\n", node->start, node->last); - prange = container_of(node, struct svm_range, it_node); + old = container_of(node, struct svm_range, it_node); next = interval_tree_iter_next(node, start, last); next_start = min(node->last, last) + 1; - if (svm_range_is_same_attrs(p, prange, nattr, attrs)) { - /* nothing to do */ - } else if (node->start < start || node->last > last) { - /* node intersects the update range and its attributes - * will change. Clone and split it, apply updates only - * to the overlapping part - */ - struct svm_range *old = prange; - + if (node->start < start || node->last > last) { + /* node intersects the updated range, clone+split it */ prange = svm_range_clone(old); if (!prange) { r = -ENOMEM; goto out; } - list_add(&old->update_list, remove_list); - list_add(&prange->list, insert_list); - list_add(&prange->update_list, update_list); + list_add(&old->remove_list, remove_list); + list_add(&prange->insert_list, insert_list); if (node->start < start) { pr_debug("change old range start\n"); @@ -1918,18 +1846,22 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, /* The node is contained within start..last, * just update it */ - list_add(&prange->update_list, update_list); + prange = old; } + if (!svm_range_is_same_attrs(prange, &new)) + list_add(&prange->update_list, update_list); + /* insert a new node if needed */ if (node->start > start) { - prange = svm_range_new(svms, start, node->start - 1); + prange = svm_range_new(prange->svms, start, + node->start - 1); if (!prange) { r = -ENOMEM; goto out; } - list_add(&prange->list, insert_list); + list_add(&prange->insert_list, insert_list); list_add(&prange->update_list, update_list); } @@ -1944,13 +1876,13 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, r = -ENOMEM; goto out; } - list_add(&prange->list, insert_list); + list_add(&prange->insert_list, insert_list); list_add(&prange->update_list, update_list); } out: if (r) - list_for_each_entry_safe(prange, tmp, insert_list, list) + list_for_each_entry_safe(prange, tmp, insert_list, insert_list) svm_range_free(prange); return r; @@ -2034,30 +1966,23 @@ svm_range_handle_list_op(struct svm_range_list *svms, struct svm_range *prange) static void svm_range_drain_retry_fault(struct svm_range_list *svms) { struct kfd_process_device *pdd; + struct amdgpu_device *adev; struct kfd_process *p; - int drain; uint32_t i; p = container_of(svms, struct kfd_process, svms); -restart: - drain = atomic_read(&svms->drain_pagefaults); - if (!drain) - return; - for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) { pdd = p->pdds[i]; if (!pdd) continue; pr_debug("drain retry fault gpu %d svms %p\n", i, svms); + adev = (struct amdgpu_device *)pdd->dev->kgd; - amdgpu_ih_wait_on_checkpoint_process_ts(pdd->dev->adev, - &pdd->dev->adev->irq.ih1); + amdgpu_ih_wait_on_checkpoint_process(adev, &adev->irq.ih1); pr_debug("drain retry fault gpu %d svms 0x%p done\n", i, svms); } - if (atomic_cmpxchg(&svms->drain_pagefaults, drain, 0) != drain) - goto restart; } static void svm_range_deferred_list_work(struct work_struct *work) @@ -2065,41 +1990,35 @@ static void svm_range_deferred_list_work(struct work_struct *work) struct svm_range_list *svms; struct svm_range *prange; struct mm_struct *mm; - struct kfd_process *p; svms = container_of(work, struct svm_range_list, deferred_list_work); pr_debug("enter svms 0x%p\n", svms); - p = container_of(svms, struct kfd_process, svms); - /* Avoid mm is gone when inserting mmu notifier */ - mm = get_task_mm(p->lead_thread); - if (!mm) { - pr_debug("svms 0x%p process mm gone\n", svms); - return; - } -retry: - mmap_write_lock(mm); - - /* Checking for the need to drain retry faults must be inside - * mmap write lock to serialize with munmap notifiers. - */ - if (unlikely(atomic_read(&svms->drain_pagefaults))) { - mmap_write_unlock(mm); - svm_range_drain_retry_fault(svms); - goto retry; - } - spin_lock(&svms->deferred_list_lock); while (!list_empty(&svms->deferred_range_list)) { prange = list_first_entry(&svms->deferred_range_list, struct svm_range, deferred_list); - list_del_init(&prange->deferred_list); spin_unlock(&svms->deferred_list_lock); - pr_debug("prange 0x%p [0x%lx 0x%lx] op %d\n", prange, prange->start, prange->last, prange->work_item.op); + /* Make sure no stale retry fault coming after range is freed */ + if (prange->work_item.op == SVM_OP_UNMAP_RANGE) + svm_range_drain_retry_fault(prange->svms); + + mm = prange->work_item.mm; + mmap_write_lock(mm); mutex_lock(&svms->lock); + + /* Remove from deferred_list must be inside mmap write lock, + * otherwise, svm_range_list_lock_and_flush_work may hold mmap + * write lock, and continue because deferred_list is empty, then + * deferred_list handle is blocked by mmap write lock. + */ + spin_lock(&svms->deferred_list_lock); + list_del_init(&prange->deferred_list); + spin_unlock(&svms->deferred_list_lock); + mutex_lock(&prange->migrate_mutex); while (!list_empty(&prange->child_list)) { struct svm_range *pchild; @@ -2115,13 +2034,12 @@ static void svm_range_deferred_list_work(struct work_struct *work) svm_range_handle_list_op(svms, prange); mutex_unlock(&svms->lock); + mmap_write_unlock(mm); spin_lock(&svms->deferred_list_lock); } spin_unlock(&svms->deferred_list_lock); - mmap_write_unlock(mm); - mmput(mm); pr_debug("exit svms 0x%p\n", svms); } @@ -2208,12 +2126,6 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange, pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx 0x%lx]\n", svms, prange, prange->start, prange->last, start, last); - /* Make sure pending page faults are drained in the deferred worker - * before the range is freed to avoid straggler interrupts on - * unmapped memory causing "phantom faults". - */ - atomic_inc(&svms->drain_pagefaults); - unmap_parent = start <= prange->start && last >= prange->last; list_for_each_entry(pchild, &prange->child_list, child_list) { @@ -2243,9 +2155,6 @@ svm_range_unmap_from_cpu(struct mm_struct *mm, struct svm_range *prange, /** * svm_range_cpu_invalidate_pagetables - interval notifier callback - * @mni: mmu_interval_notifier struct - * @range: mmu_notifier_range struct - * @cur_seq: value to pass to mmu_interval_set_seq() * * If event is MMU_NOTIFY_UNMAP, this is from CPU unmap range, otherwise, it * is from migration, or CPU page invalidation callback. @@ -2275,8 +2184,8 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, start = mni->interval_tree.start; last = mni->interval_tree.last; - start = max(start, range->start) >> PAGE_SHIFT; - last = min(last, range->end - 1) >> PAGE_SHIFT; + start = (start > range->start ? start : range->start) >> PAGE_SHIFT; + last = (last < (range->end - 1) ? last : range->end - 1) >> PAGE_SHIFT; pr_debug("[0x%lx 0x%lx] range[0x%lx 0x%lx] notifier[0x%lx 0x%lx] %d\n", start, last, range->start >> PAGE_SHIFT, (range->end - 1) >> PAGE_SHIFT, @@ -2354,7 +2263,7 @@ svm_range_from_addr(struct svm_range_list *svms, unsigned long addr, * migration if actual loc is not best location, then update GPU page table * mapping to the best location. * - * If the preferred loc is accessible by faulting GPU, use preferred loc. + * If vm fault gpu is range preferred loc, the best_loc is preferred loc. * If vm fault gpu idx is on range ACCESSIBLE bitmap, best_loc is vm fault gpu * If vm fault gpu idx is on range ACCESSIBLE_IN_PLACE bitmap, then * if range actual loc is cpu, best_loc is cpu @@ -2371,29 +2280,21 @@ svm_range_best_restore_location(struct svm_range *prange, struct amdgpu_device *adev, int32_t *gpuidx) { - struct amdgpu_device *bo_adev, *preferred_adev; + struct amdgpu_device *bo_adev; struct kfd_process *p; uint32_t gpuid; int r; p = container_of(prange->svms, struct kfd_process, svms); - r = kfd_process_gpuid_from_adev(p, adev, &gpuid, gpuidx); + r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, gpuidx); if (r < 0) { pr_debug("failed to get gpuid from kgd\n"); return -1; } - if (prange->preferred_loc == gpuid || - prange->preferred_loc == KFD_IOCTL_SVM_LOCATION_SYSMEM) { + if (prange->preferred_loc == gpuid) return prange->preferred_loc; - } else if (prange->preferred_loc != KFD_IOCTL_SVM_LOCATION_UNDEFINED) { - preferred_adev = svm_range_get_adev_by_id(prange, - prange->preferred_loc); - if (amdgpu_xgmi_same_hive(adev, preferred_adev)) - return prange->preferred_loc; - /* fall through */ - } if (test_bit(*gpuidx, prange->bitmap_access)) return gpuid; @@ -2411,11 +2312,9 @@ svm_range_best_restore_location(struct svm_range *prange, return -1; } - static int svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr, - unsigned long *start, unsigned long *last, - bool *is_heap_stack) + unsigned long *start, unsigned long *last) { struct vm_area_struct *vma; struct interval_tree_node *node; @@ -2426,12 +2325,6 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr, pr_debug("VMA does not exist in address [0x%llx]\n", addr); return -EFAULT; } - - *is_heap_stack = (vma->vm_start <= vma->vm_mm->brk && - vma->vm_end >= vma->vm_mm->start_brk) || - (vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack); - start_limit = max(vma->vm_start >> PAGE_SHIFT, (unsigned long)ALIGN_DOWN(addr, 2UL << 8)); end_limit = min(vma->vm_end >> PAGE_SHIFT, @@ -2461,64 +2354,13 @@ svm_range_get_range_boundaries(struct kfd_process *p, int64_t addr, *start = start_limit; *last = end_limit - 1; - pr_debug("vma [0x%lx 0x%lx] range [0x%lx 0x%lx] is_heap_stack %d\n", - vma->vm_start >> PAGE_SHIFT, vma->vm_end >> PAGE_SHIFT, - *start, *last, *is_heap_stack); + pr_debug("vma start: 0x%lx start: 0x%lx vma end: 0x%lx last: 0x%lx\n", + vma->vm_start >> PAGE_SHIFT, *start, + vma->vm_end >> PAGE_SHIFT, *last); return 0; + } - -static int -svm_range_check_vm_userptr(struct kfd_process *p, uint64_t start, uint64_t last, - uint64_t *bo_s, uint64_t *bo_l) -{ - struct amdgpu_bo_va_mapping *mapping; - struct interval_tree_node *node; - struct amdgpu_bo *bo = NULL; - unsigned long userptr; - uint32_t i; - int r; - - for (i = 0; i < p->n_pdds; i++) { - struct amdgpu_vm *vm; - - if (!p->pdds[i]->drm_priv) - continue; - - vm = drm_priv_to_vm(p->pdds[i]->drm_priv); - r = amdgpu_bo_reserve(vm->root.bo, false); - if (r) - return r; - - /* Check userptr by searching entire vm->va interval tree */ - node = interval_tree_iter_first(&vm->va, 0, ~0ULL); - while (node) { - mapping = container_of((struct rb_node *)node, - struct amdgpu_bo_va_mapping, rb); - bo = mapping->bo_va->base.bo; - - if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, - start << PAGE_SHIFT, - last << PAGE_SHIFT, - &userptr)) { - node = interval_tree_iter_next(node, 0, ~0ULL); - continue; - } - - pr_debug("[0x%llx 0x%llx] already userptr mapped\n", - start, last); - if (bo_s && bo_l) { - *bo_s = userptr >> PAGE_SHIFT; - *bo_l = *bo_s + bo->tbo.ttm->num_pages - 1; - } - amdgpu_bo_unreserve(vm->root.bo); - return -EADDRINUSE; - } - amdgpu_bo_unreserve(vm->root.bo); - } - return 0; -} - static struct svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev, struct kfd_process *p, @@ -2528,42 +2370,21 @@ svm_range *svm_range_create_unregistered_range(struct amdgpu_device *adev, struct svm_range *prange = NULL; unsigned long start, last; uint32_t gpuid, gpuidx; - bool is_heap_stack; - uint64_t bo_s = 0; - uint64_t bo_l = 0; - int r; - if (svm_range_get_range_boundaries(p, addr, &start, &last, - &is_heap_stack)) + if (svm_range_get_range_boundaries(p, addr, &start, &last)) return NULL; - r = svm_range_check_vm(p, start, last, &bo_s, &bo_l); - if (r != -EADDRINUSE) - r = svm_range_check_vm_userptr(p, start, last, &bo_s, &bo_l); - - if (r == -EADDRINUSE) { - if (addr >= bo_s && addr <= bo_l) - return NULL; - - /* Create one page svm range if 2MB range overlapping */ - start = addr; - last = addr; - } - prange = svm_range_new(&p->svms, start, last); if (!prange) { pr_debug("Failed to create prange in address [0x%llx]\n", addr); return NULL; } - if (kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpuidx)) { + if (kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpuidx)) { pr_debug("failed to get gpuid from kgd\n"); svm_range_free(prange); return NULL; } - if (is_heap_stack) - prange->preferred_loc = KFD_IOCTL_SVM_LOCATION_SYSMEM; - svm_range_add_to_svms(prange); svm_range_add_notifier_locked(mm, prange); @@ -2622,7 +2443,7 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p, uint32_t gpuid; int r; - r = kfd_process_gpuid_from_adev(p, adev, &gpuid, &gpuidx); + r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpuidx); if (r < 0) return; } @@ -2636,13 +2457,20 @@ svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p, } static bool -svm_fault_allowed(struct vm_area_struct *vma, bool write_fault) +svm_fault_allowed(struct mm_struct *mm, uint64_t addr, bool write_fault) { unsigned long requested = VM_READ; + struct vm_area_struct *vma; if (write_fault) requested |= VM_WRITE; + vma = find_vma(mm, addr << PAGE_SHIFT); + if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) { + pr_debug("address 0x%llx VMA is removed\n", addr); + return true; + } + pr_debug("requested 0x%lx, vma permission flags 0x%lx\n", requested, vma->vm_flags); return (vma->vm_flags & requested) == requested; @@ -2660,7 +2488,6 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, int32_t best_loc; int32_t gpuidx = MAX_GPU_INSTANCE; bool write_locked = false; - struct vm_area_struct *vma; int r = 0; if (!KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) { @@ -2671,7 +2498,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, p = kfd_lookup_process_by_pasid(pasid); if (!p) { pr_debug("kfd process not founded pasid 0x%x\n", pasid); - return 0; + return -ESRCH; } if (!p->xnack_enabled) { pr_debug("XNACK not enabled for pasid 0x%x\n", pasid); @@ -2682,19 +2509,10 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, pr_debug("restoring svms 0x%p fault address 0x%llx\n", svms, addr); - if (atomic_read(&svms->drain_pagefaults)) { - pr_debug("draining retry fault, drop fault 0x%llx\n", addr); - r = 0; - goto out; - } - - /* p->lead_thread is available as kfd_process_wq_release flush the work - * before releasing task ref. - */ mm = get_task_mm(p->lead_thread); if (!mm) { pr_debug("svms 0x%p failed to get mm\n", svms); - r = 0; + r = -ESRCH; goto out; } @@ -2732,7 +2550,6 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, if (svm_range_skip_recover(prange)) { amdgpu_gmc_filter_faults_remove(adev, addr, pasid); - r = 0; goto out_unlock_range; } @@ -2741,21 +2558,10 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, if (timestamp < AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING) { pr_debug("svms 0x%p [0x%lx %lx] already restored\n", svms, prange->start, prange->last); - r = 0; goto out_unlock_range; } - /* __do_munmap removed VMA, return success as we are handling stale - * retry fault. - */ - vma = find_vma(mm, addr << PAGE_SHIFT); - if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) { - pr_debug("address 0x%llx VMA is removed\n", addr); - r = 0; - goto out_unlock_range; - } - - if (!svm_fault_allowed(vma, write_fault)) { + if (!svm_fault_allowed(mm, addr, write_fault)) { pr_debug("fault addr 0x%llx no %s permission\n", addr, write_fault ? "write" : "read"); r = -EPERM; @@ -2833,14 +2639,6 @@ void svm_range_list_fini(struct kfd_process *p) /* Ensure list work is finished before process is destroyed */ flush_work(&p->svms.deferred_list_work); - /* - * Ensure no retry fault comes in afterwards, as page fault handler will - * not find kfd process and take mm lock to recover fault. - */ - atomic_inc(&p->svms.drain_pagefaults); - svm_range_drain_retry_fault(&p->svms); - - list_for_each_entry_safe(prange, next, &p->svms.list, list) { svm_range_unlink(prange); svm_range_remove_notifier(prange); @@ -2861,7 +2659,6 @@ int svm_range_list_init(struct kfd_process *p) mutex_init(&svms->lock); INIT_LIST_HEAD(&svms->list); atomic_set(&svms->evicted_ranges, 0); - atomic_set(&svms->drain_pagefaults, 0); INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work); INIT_WORK(&svms->deferred_list_work, svm_range_deferred_list_work); INIT_LIST_HEAD(&svms->deferred_range_list); @@ -2874,68 +2671,9 @@ int svm_range_list_init(struct kfd_process *p) return 0; } -/** - * svm_range_check_vm - check if virtual address range mapped already - * @p: current kfd_process - * @start: range start address, in pages - * @last: range last address, in pages - * @bo_s: mapping start address in pages if address range already mapped - * @bo_l: mapping last address in pages if address range already mapped - * - * The purpose is to avoid virtual address ranges already allocated by - * kfd_ioctl_alloc_memory_of_gpu ioctl. - * It looks for each pdd in the kfd_process. - * - * Context: Process context - * - * Return 0 - OK, if the range is not mapped. - * Otherwise error code: - * -EADDRINUSE - if address is mapped already by kfd_ioctl_alloc_memory_of_gpu - * -ERESTARTSYS - A wait for the buffer to become unreserved was interrupted by - * a signal. Release all buffer reservations and return to user-space. - */ -static int -svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last, - uint64_t *bo_s, uint64_t *bo_l) -{ - struct amdgpu_bo_va_mapping *mapping; - struct interval_tree_node *node; - uint32_t i; - int r; - - for (i = 0; i < p->n_pdds; i++) { - struct amdgpu_vm *vm; - - if (!p->pdds[i]->drm_priv) - continue; - - vm = drm_priv_to_vm(p->pdds[i]->drm_priv); - r = amdgpu_bo_reserve(vm->root.bo, false); - if (r) - return r; - - node = interval_tree_iter_first(&vm->va, start, last); - if (node) { - pr_debug("range [0x%llx 0x%llx] already TTM mapped\n", - start, last); - mapping = container_of((struct rb_node *)node, - struct amdgpu_bo_va_mapping, rb); - if (bo_s && bo_l) { - *bo_s = mapping->start; - *bo_l = mapping->last; - } - amdgpu_bo_unreserve(vm->root.bo); - return -EADDRINUSE; - } - amdgpu_bo_unreserve(vm->root.bo); - } - - return 0; -} - /** * svm_range_is_valid - check if virtual address range is valid - * @p: current kfd_process + * @mm: current process mm_struct * @start: range start address, in pages * @size: range size, in pages * @@ -2944,28 +2682,28 @@ svm_range_check_vm(struct kfd_process *p, uint64_t start, uint64_t last, * Context: Process context * * Return: - * 0 - OK, otherwise error code + * true - valid svm range + * false - invalid svm range */ -static int -svm_range_is_valid(struct kfd_process *p, uint64_t start, uint64_t size) +static bool +svm_range_is_valid(struct mm_struct *mm, uint64_t start, uint64_t size) { const unsigned long device_vma = VM_IO | VM_PFNMAP | VM_MIXEDMAP; struct vm_area_struct *vma; unsigned long end; - unsigned long start_unchg = start; start <<= PAGE_SHIFT; end = start + (size << PAGE_SHIFT); + do { - vma = find_vma(p->mm, start); + vma = find_vma(mm, start); if (!vma || start < vma->vm_start || (vma->vm_flags & device_vma)) - return -EFAULT; + return false; start = min(end, vma->vm_end); } while (start < end); - return svm_range_check_vm(p, start_unchg, (end - 1) >> PAGE_SHIFT, NULL, - NULL); + return true; } /** @@ -3001,6 +2739,7 @@ svm_range_best_prefetch_location(struct svm_range *prange) uint32_t best_loc = prange->prefetch_loc; struct kfd_process_device *pdd; struct amdgpu_device *bo_adev; + struct amdgpu_device *adev; struct kfd_process *p; uint32_t gpuidx; @@ -3028,11 +2767,12 @@ svm_range_best_prefetch_location(struct svm_range *prange) pr_debug("failed to get device by idx 0x%x\n", gpuidx); continue; } + adev = (struct amdgpu_device *)pdd->dev->kgd; - if (pdd->dev->adev == bo_adev) + if (adev == bo_adev) continue; - if (!amdgpu_xgmi_same_hive(pdd->dev->adev, bo_adev)) { + if (!amdgpu_xgmi_same_hive(adev, bo_adev)) { best_loc = 0; break; } @@ -3158,8 +2898,6 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) struct svm_range *prange = list_first_entry(&svm_bo->range_list, struct svm_range, svm_bo_list); - int retries = 3; - list_del_init(&prange->svm_bo_list); spin_unlock(&svm_bo->list_lock); @@ -3167,11 +2905,7 @@ static void svm_range_evict_svm_bo_worker(struct work_struct *work) prange->start, prange->last); mutex_lock(&prange->migrate_mutex); - do { - svm_migrate_vram_to_ram(prange, - svm_bo->eviction_fence->mm); - } while (prange->actual_loc && --retries); - WARN(prange->actual_loc, "Migration failed during eviction"); + svm_migrate_vram_to_ram(prange, svm_bo->eviction_fence->mm); mutex_lock(&prange->lock); prange->svm_bo = NULL; @@ -3216,9 +2950,9 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, svm_range_list_lock_and_flush_work(svms, mm); - r = svm_range_is_valid(p, start, size); - if (r) { - pr_debug("invalid range r=%d\n", r); + if (!svm_range_is_valid(mm, start, size)) { + pr_debug("invalid range\n"); + r = -EFAULT; mmap_write_unlock(mm); goto out; } @@ -3234,7 +2968,7 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, goto out; } /* Apply changes as a transaction */ - list_for_each_entry_safe(prange, next, &insert_list, list) { + list_for_each_entry_safe(prange, next, &insert_list, insert_list) { svm_range_add_to_svms(prange); svm_range_add_notifier_locked(mm, prange); } @@ -3242,7 +2976,8 @@ svm_range_set_attr(struct kfd_process *p, uint64_t start, uint64_t size, svm_range_apply_attrs(p, prange, nattr, attrs); /* TODO: unmap ranges from GPU that lost access */ } - list_for_each_entry_safe(prange, next, &remove_list, update_list) { + list_for_each_entry_safe(prange, next, &remove_list, + remove_list) { pr_debug("unlink old 0x%p prange 0x%p [0x%lx 0x%lx]\n", prange->svms, prange, prange->start, prange->last); @@ -3317,7 +3052,6 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size, uint32_t flags_or = 0; int gpuidx; uint32_t i; - int r = 0; pr_debug("svms 0x%p [0x%llx 0x%llx] nattr 0x%x\n", &p->svms, start, start + size - 1, nattr); @@ -3331,12 +3065,12 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size, flush_work(&p->svms.deferred_list_work); mmap_read_lock(mm); - r = svm_range_is_valid(p, start, size); - mmap_read_unlock(mm); - if (r) { - pr_debug("invalid range r=%d\n", r); - return r; + if (!svm_range_is_valid(mm, start, size)) { + pr_debug("invalid range\n"); + mmap_read_unlock(mm); + return -EINVAL; } + mmap_read_unlock(mm); for (i = 0; i < nattr; i++) { switch (attrs[i].type) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h index 949b477e2f..c6ec55354c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -48,7 +48,6 @@ struct svm_range_bo { struct work_struct eviction_work; struct svm_range_list *svms; uint32_t evicting; - struct work_struct release_work; }; enum svm_work_list_ops { @@ -76,6 +75,8 @@ struct svm_work_list_item { * aligned, page size is (last - start + 1) * @list: link list node, used to scan all ranges of svms * @update_list:link list node used to add to update_list + * @remove_list:link list node used to add to remove list + * @insert_list:link list node used to add to insert list * @mapping: bo_va mapping structure to create and update GPU page table * @npages: number of pages * @dma_addr: dma mapping address on each GPU for system memory physical page @@ -111,6 +112,8 @@ struct svm_range { struct interval_tree_node it_node; struct list_head list; struct list_head update_list; + struct list_head remove_list; + struct list_head insert_list; uint64_t npages; dma_addr_t *dma_addr[MAX_GPU_INSTANCE]; struct ttm_resource *ttm_res; @@ -185,14 +188,13 @@ void svm_range_prefault(struct svm_range *prange, struct mm_struct *mm, void *owner); struct kfd_process_device * svm_range_get_pdd_by_adev(struct svm_range *prange, struct amdgpu_device *adev); -void svm_range_list_lock_and_flush_work(struct svm_range_list *svms, struct mm_struct *mm); /* SVM API and HMM page migration work together, device memory type * is initialized to not 0 when page migration register device memory. */ #define KFD_IS_SVM_API_SUPPORTED(dev) ((dev)->pgmap.type != 0) -void svm_range_bo_unref_async(struct svm_range_bo *svm_bo); +void svm_range_bo_unref(struct svm_range_bo *svm_bo); #else struct kfd_process; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 948fbb3933..98cca5f2b2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -113,7 +113,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev) return device; } -struct kfd_dev *kfd_device_by_adev(const struct amdgpu_device *adev) +struct kfd_dev *kfd_device_by_kgd(const struct kgd_dev *kgd) { struct kfd_topology_device *top_dev; struct kfd_dev *device = NULL; @@ -121,7 +121,7 @@ struct kfd_dev *kfd_device_by_adev(const struct amdgpu_device *adev) down_read(&topology_lock); list_for_each_entry(top_dev, &topology_device_list, list) - if (top_dev->gpu && top_dev->gpu->adev == adev) { + if (top_dev->gpu && top_dev->gpu->kgd == kgd) { device = top_dev->gpu; break; } @@ -503,7 +503,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, if (dev->gpu) { log_max_watch_addr = - __ilog2_u32(dev->gpu->device_info.num_of_watch_points); + __ilog2_u32(dev->gpu->device_info->num_of_watch_points); if (log_max_watch_addr) { dev->node_props.capability |= @@ -515,7 +515,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, HSA_CAP_WATCH_POINTS_TOTALBITS_MASK); } - if (dev->gpu->adev->asic_type == CHIP_TONGA) + if (dev->gpu->device_info->asic_family == CHIP_TONGA) dev->node_props.capability |= HSA_CAP_AQL_QUEUE_DOUBLE_MAP; @@ -531,7 +531,7 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, sysfs_show_32bit_prop(buffer, offs, "sdma_fw_version", dev->gpu->sdma_fw_version); sysfs_show_64bit_prop(buffer, offs, "unique_id", - dev->gpu->adev->unique_id); + amdgpu_amdkfd_get_unique_id(dev->gpu->kgd)); } @@ -1106,7 +1106,7 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) if (!gpu) return 0; - amdgpu_amdkfd_get_local_mem_info(gpu->adev, &local_mem_info); + amdgpu_amdkfd_get_local_mem_info(gpu->kgd, &local_mem_info); local_mem_size = local_mem_info.local_mem_size_private + local_mem_info.local_mem_size_public; @@ -1189,7 +1189,7 @@ static void kfd_fill_mem_clk_max_info(struct kfd_topology_device *dev) * for APUs - If CRAT from ACPI reports more than one bank, then * all the banks will report the same mem_clk_max information */ - amdgpu_amdkfd_get_local_mem_info(dev->gpu->adev, &local_mem_info); + amdgpu_amdkfd_get_local_mem_info(dev->gpu->kgd, &local_mem_info); list_for_each_entry(mem, &dev->mem_props, list) mem->mem_clk_max = local_mem_info.mem_clk_max; @@ -1217,7 +1217,8 @@ static void kfd_set_iolink_no_atomics(struct kfd_topology_device *dev, /* set gpu (dev) flags. */ } else { if (!dev->gpu->pci_atomic_requested || - dev->gpu->adev->asic_type == CHIP_HAWAII) + dev->gpu->device_info->asic_family == + CHIP_HAWAII) link->flags |= CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT | CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT; } @@ -1238,7 +1239,7 @@ static void kfd_set_iolink_non_coherent(struct kfd_topology_device *to_dev, */ if (inbound_link->iolink_type == CRAT_IOLINK_TYPE_PCIEXPRESS || (inbound_link->iolink_type == CRAT_IOLINK_TYPE_XGMI && - KFD_GC_VERSION(to_dev->gpu) == IP_VERSION(9, 4, 0))) { + to_dev->gpu->device_info->asic_family == CHIP_VEGA20)) { outbound_link->flags |= CRAT_IOLINK_FLAGS_NON_COHERENT; inbound_link->flags |= CRAT_IOLINK_FLAGS_NON_COHERENT; } @@ -1285,8 +1286,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) void *crat_image = NULL; size_t image_size = 0; int proximity_domain; - int i; - const char *asic_name = amdgpu_asic_name[gpu->adev->asic_type]; + struct amdgpu_device *adev; INIT_LIST_HEAD(&temp_topology_device_list); @@ -1296,22 +1296,6 @@ int kfd_topology_add_device(struct kfd_dev *gpu) proximity_domain = atomic_inc_return(&topology_crat_proximity_domain); - /* Include the CPU in xGMI hive if xGMI connected by assigning it the hive ID. */ - if (gpu->hive_id && gpu->adev->gmc.xgmi.connected_to_cpu) { - struct kfd_topology_device *top_dev; - - down_read(&topology_lock); - - list_for_each_entry(top_dev, &topology_device_list, list) { - if (top_dev->gpu) - break; - - top_dev->node_props.hive_id = gpu->hive_id; - } - - up_read(&topology_lock); - } - /* Check to see if this gpu device exists in the topology_device_list. * If so, assign the gpu to that device, * else create a Virtual CRAT for this gpu device and then parse that @@ -1370,48 +1354,45 @@ int kfd_topology_add_device(struct kfd_dev *gpu) * needed for the topology */ - amdgpu_amdkfd_get_cu_info(dev->gpu->adev, &cu_info); + amdgpu_amdkfd_get_cu_info(dev->gpu->kgd, &cu_info); - for (i = 0; i < KFD_TOPOLOGY_PUBLIC_NAME_SIZE-1; i++) { - dev->node_props.name[i] = __tolower(asic_name[i]); - if (asic_name[i] == '\0') - break; - } - dev->node_props.name[i] = '\0'; + strncpy(dev->node_props.name, gpu->device_info->asic_name, + KFD_TOPOLOGY_PUBLIC_NAME_SIZE); dev->node_props.simd_arrays_per_engine = cu_info.num_shader_arrays_per_engine; - dev->node_props.gfx_target_version = gpu->device_info.gfx_target_version; + dev->node_props.gfx_target_version = gpu->device_info->gfx_target_version; dev->node_props.vendor_id = gpu->pdev->vendor; dev->node_props.device_id = gpu->pdev->device; dev->node_props.capability |= - ((dev->gpu->adev->rev_id << HSA_CAP_ASIC_REVISION_SHIFT) & + ((amdgpu_amdkfd_get_asic_rev_id(dev->gpu->kgd) << + HSA_CAP_ASIC_REVISION_SHIFT) & HSA_CAP_ASIC_REVISION_MASK); dev->node_props.location_id = pci_dev_id(gpu->pdev); dev->node_props.domain = pci_domain_nr(gpu->pdev->bus); dev->node_props.max_engine_clk_fcompute = - amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->adev); + amdgpu_amdkfd_get_max_engine_clock_in_mhz(dev->gpu->kgd); dev->node_props.max_engine_clk_ccompute = cpufreq_quick_get_max(0) / 1000; dev->node_props.drm_render_minor = gpu->shared_resources.drm_render_minor; dev->node_props.hive_id = gpu->hive_id; - dev->node_props.num_sdma_engines = kfd_get_num_sdma_engines(gpu); + dev->node_props.num_sdma_engines = gpu->device_info->num_sdma_engines; dev->node_props.num_sdma_xgmi_engines = - kfd_get_num_xgmi_sdma_engines(gpu); + gpu->device_info->num_xgmi_sdma_engines; dev->node_props.num_sdma_queues_per_engine = - gpu->device_info.num_sdma_queues_per_engine; + gpu->device_info->num_sdma_queues_per_engine; dev->node_props.num_gws = (dev->gpu->gws && dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ? - dev->gpu->adev->gds.gws_size : 0; + amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm); kfd_fill_mem_clk_max_info(dev); kfd_fill_iolink_non_crat_info(dev); - switch (dev->gpu->adev->asic_type) { + switch (dev->gpu->device_info->asic_family) { case CHIP_KAVERI: case CHIP_HAWAII: case CHIP_TONGA: @@ -1430,14 +1411,30 @@ int kfd_topology_add_device(struct kfd_dev *gpu) HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); break; + case CHIP_VEGA10: + case CHIP_VEGA12: + case CHIP_VEGA20: + case CHIP_RAVEN: + case CHIP_RENOIR: + case CHIP_ARCTURUS: + case CHIP_ALDEBARAN: + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_NAVI14: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_VANGOGH: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_YELLOW_CARP: + case CHIP_CYAN_SKILLFISH: + dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 << + HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & + HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); + break; default: - if (KFD_GC_VERSION(dev->gpu) >= IP_VERSION(9, 0, 1)) - dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 << - HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & - HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); - else - WARN(1, "Unexpected ASIC family %u", - dev->gpu->adev->asic_type); + WARN(1, "Unexpected ASIC family %u", + dev->gpu->device_info->asic_family); } /* @@ -1454,25 +1451,25 @@ int kfd_topology_add_device(struct kfd_dev *gpu) * because it doesn't consider masked out CUs * max_waves_per_simd: Carrizo reports wrong max_waves_per_simd */ - if (dev->gpu->adev->asic_type == CHIP_CARRIZO) { + if (dev->gpu->device_info->asic_family == CHIP_CARRIZO) { dev->node_props.simd_count = cu_info.simd_per_cu * cu_info.cu_active_number; dev->node_props.max_waves_per_simd = 10; } + adev = (struct amdgpu_device *)(dev->gpu->kgd); /* kfd only concerns sram ecc on GFX and HBM ecc on UMC */ dev->node_props.capability |= - ((dev->gpu->adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ? + ((adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__GFX)) != 0) ? HSA_CAP_SRAM_EDCSUPPORTED : 0; - dev->node_props.capability |= - ((dev->gpu->adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ? + dev->node_props.capability |= ((adev->ras_enabled & BIT(AMDGPU_RAS_BLOCK__UMC)) != 0) ? HSA_CAP_MEM_EDCSUPPORTED : 0; - if (KFD_GC_VERSION(dev->gpu) != IP_VERSION(9, 0, 1)) - dev->node_props.capability |= (dev->gpu->adev->ras_enabled != 0) ? + if (adev->asic_type != CHIP_VEGA10) + dev->node_props.capability |= (adev->ras_enabled != 0) ? HSA_CAP_RASEVENTNOTIFY : 0; - if (KFD_IS_SVM_API_SUPPORTED(dev->gpu->adev->kfd.dev)) + if (KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) dev->node_props.capability |= HSA_CAP_SVMAPI_SUPPORTED; kfd_debug_print_topology(); @@ -1578,7 +1575,7 @@ void kfd_double_confirm_iommu_support(struct kfd_dev *gpu) gpu->use_iommu_v2 = false; - if (!gpu->device_info.needs_iommu_device) + if (!gpu->device_info->needs_iommu_device) return; down_read(&topology_lock); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h index f0cc59d2fd..a8db017c9b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h @@ -25,11 +25,38 @@ #include #include -#include #include "kfd_crat.h" #define KFD_TOPOLOGY_PUBLIC_NAME_SIZE 32 +#define HSA_CAP_HOT_PLUGGABLE 0x00000001 +#define HSA_CAP_ATS_PRESENT 0x00000002 +#define HSA_CAP_SHARED_WITH_GRAPHICS 0x00000004 +#define HSA_CAP_QUEUE_SIZE_POW2 0x00000008 +#define HSA_CAP_QUEUE_SIZE_32BIT 0x00000010 +#define HSA_CAP_QUEUE_IDLE_EVENT 0x00000020 +#define HSA_CAP_VA_LIMIT 0x00000040 +#define HSA_CAP_WATCH_POINTS_SUPPORTED 0x00000080 +#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK 0x00000f00 +#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8 +#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK 0x00003000 +#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT 12 + +#define HSA_CAP_DOORBELL_TYPE_PRE_1_0 0x0 +#define HSA_CAP_DOORBELL_TYPE_1_0 0x1 +#define HSA_CAP_DOORBELL_TYPE_2_0 0x2 +#define HSA_CAP_AQL_QUEUE_DOUBLE_MAP 0x00004000 + +#define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000 /* Old buggy user mode depends on this being 0 */ +#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000 +#define HSA_CAP_RASEVENTNOTIFY 0x00200000 +#define HSA_CAP_ASIC_REVISION_MASK 0x03c00000 +#define HSA_CAP_ASIC_REVISION_SHIFT 22 +#define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000 +#define HSA_CAP_SVMAPI_SUPPORTED 0x08000000 +#define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000 +#define HSA_CAP_RESERVED 0xe00f8000 + struct kfd_node_properties { uint64_t hive_id; uint32_t cpu_cores_count; @@ -66,6 +93,17 @@ struct kfd_node_properties { char name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE]; }; +#define HSA_MEM_HEAP_TYPE_SYSTEM 0 +#define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1 +#define HSA_MEM_HEAP_TYPE_FB_PRIVATE 2 +#define HSA_MEM_HEAP_TYPE_GPU_GDS 3 +#define HSA_MEM_HEAP_TYPE_GPU_LDS 4 +#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH 5 + +#define HSA_MEM_FLAGS_HOT_PLUGGABLE 0x00000001 +#define HSA_MEM_FLAGS_NON_VOLATILE 0x00000002 +#define HSA_MEM_FLAGS_RESERVED 0xfffffffc + struct kfd_mem_properties { struct list_head list; uint32_t heap_type; @@ -78,6 +116,12 @@ struct kfd_mem_properties { struct attribute attr; }; +#define HSA_CACHE_TYPE_DATA 0x00000001 +#define HSA_CACHE_TYPE_INSTRUCTION 0x00000002 +#define HSA_CACHE_TYPE_CPU 0x00000004 +#define HSA_CACHE_TYPE_HSACU 0x00000008 +#define HSA_CACHE_TYPE_RESERVED 0xfffffff0 + struct kfd_cache_properties { struct list_head list; uint32_t processor_id_low; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 075429bea4..cd611444ad 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -29,7 +29,6 @@ #include "dm_services_types.h" #include "dc.h" #include "dc_link_dp.h" -#include "link_enc_cfg.h" #include "dc/inc/core_types.h" #include "dal_asic_id.h" #include "dmub/dmub_srv.h" @@ -51,7 +50,6 @@ #include #endif #include "amdgpu_pm.h" -#include "amdgpu_atombios.h" #include "amd_shared.h" #include "amdgpu_dm_irq.h" @@ -217,9 +215,6 @@ static void handle_cursor_update(struct drm_plane *plane, static const struct drm_format_info * amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd); -static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector); -static void handle_hpd_rx_irq(void *param); - static bool is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state, struct drm_crtc_state *new_crtc_state); @@ -621,127 +616,7 @@ static void dm_dcn_vertical_interrupt0_high_irq(void *interrupt_params) amdgpu_dm_crtc_handle_crc_window_irq(&acrtc->base); } -#endif /* CONFIG_DRM_AMD_SECURE_DISPLAY */ - -/** - * dmub_aux_setconfig_callback - Callback for AUX or SET_CONFIG command. - * @adev: amdgpu_device pointer - * @notify: dmub notification structure - * - * Dmub AUX or SET_CONFIG command completion processing callback - * Copies dmub notification to DM which is to be read by AUX command. - * issuing thread and also signals the event to wake up the thread. - */ -static void dmub_aux_setconfig_callback(struct amdgpu_device *adev, - struct dmub_notification *notify) -{ - if (adev->dm.dmub_notify) - memcpy(adev->dm.dmub_notify, notify, sizeof(struct dmub_notification)); - if (notify->type == DMUB_NOTIFICATION_AUX_REPLY) - complete(&adev->dm.dmub_aux_transfer_done); -} - -/** - * dmub_hpd_callback - DMUB HPD interrupt processing callback. - * @adev: amdgpu_device pointer - * @notify: dmub notification structure - * - * Dmub Hpd interrupt processing callback. Gets displayindex through the - * ink index and calls helper to do the processing. - */ -static void dmub_hpd_callback(struct amdgpu_device *adev, - struct dmub_notification *notify) -{ - struct amdgpu_dm_connector *aconnector; - struct amdgpu_dm_connector *hpd_aconnector = NULL; - struct drm_connector *connector; - struct drm_connector_list_iter iter; - struct dc_link *link; - uint8_t link_index = 0; - struct drm_device *dev; - - if (adev == NULL) - return; - - if (notify == NULL) { - DRM_ERROR("DMUB HPD callback notification was NULL"); - return; - } - - if (notify->link_index > adev->dm.dc->link_count) { - DRM_ERROR("DMUB HPD index (%u)is abnormal", notify->link_index); - return; - } - - link_index = notify->link_index; - link = adev->dm.dc->links[link_index]; - dev = adev->dm.ddev; - - drm_connector_list_iter_begin(dev, &iter); - drm_for_each_connector_iter(connector, &iter) { - aconnector = to_amdgpu_dm_connector(connector); - if (link && aconnector->dc_link == link) { - DRM_INFO("DMUB HPD callback: link_index=%u\n", link_index); - hpd_aconnector = aconnector; - break; - } - } - drm_connector_list_iter_end(&iter); - - if (hpd_aconnector) { - if (notify->type == DMUB_NOTIFICATION_HPD) - handle_hpd_irq_helper(hpd_aconnector); - else if (notify->type == DMUB_NOTIFICATION_HPD_IRQ) - handle_hpd_rx_irq(hpd_aconnector); - } -} - -/** - * register_dmub_notify_callback - Sets callback for DMUB notify - * @adev: amdgpu_device pointer - * @type: Type of dmub notification - * @callback: Dmub interrupt callback function - * @dmub_int_thread_offload: offload indicator - * - * API to register a dmub callback handler for a dmub notification - * Also sets indicator whether callback processing to be offloaded. - * to dmub interrupt handling thread - * Return: true if successfully registered, false if there is existing registration - */ -static bool register_dmub_notify_callback(struct amdgpu_device *adev, - enum dmub_notification_type type, - dmub_notify_interrupt_callback_t callback, - bool dmub_int_thread_offload) -{ - if (callback != NULL && type < ARRAY_SIZE(adev->dm.dmub_thread_offload)) { - adev->dm.dmub_callback[type] = callback; - adev->dm.dmub_thread_offload[type] = dmub_int_thread_offload; - } else - return false; - - return true; -} - -static void dm_handle_hpd_work(struct work_struct *work) -{ - struct dmub_hpd_work *dmub_hpd_wrk; - - dmub_hpd_wrk = container_of(work, struct dmub_hpd_work, handle_hpd_work); - - if (!dmub_hpd_wrk->dmub_notify) { - DRM_ERROR("dmub_hpd_wrk dmub_notify is NULL"); - return; - } - - if (dmub_hpd_wrk->dmub_notify->type < ARRAY_SIZE(dmub_hpd_wrk->adev->dm.dmub_callback)) { - dmub_hpd_wrk->adev->dm.dmub_callback[dmub_hpd_wrk->dmub_notify->type](dmub_hpd_wrk->adev, - dmub_hpd_wrk->dmub_notify); - } - - kfree(dmub_hpd_wrk->dmub_notify); - kfree(dmub_hpd_wrk); - -} +#endif #define DMUB_TRACE_MAX_READ 64 /** @@ -759,50 +634,22 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) struct amdgpu_display_manager *dm = &adev->dm; struct dmcub_trace_buf_entry entry = { 0 }; uint32_t count = 0; - struct dmub_hpd_work *dmub_hpd_wrk; - struct dc_link *plink = NULL; - if (dc_enable_dmub_notifications(adev->dm.dc) && - irq_params->irq_src == DC_IRQ_SOURCE_DMCUB_OUTBOX) { + if (dc_enable_dmub_notifications(adev->dm.dc)) { + if (irq_params->irq_src == DC_IRQ_SOURCE_DMCUB_OUTBOX) { + do { + dc_stat_get_dmub_notification(adev->dm.dc, ¬ify); + } while (notify.pending_notification); - do { - dc_stat_get_dmub_notification(adev->dm.dc, ¬ify); - if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) { - DRM_ERROR("DM: notify type %d invalid!", notify.type); - continue; - } - if (!dm->dmub_callback[notify.type]) { - DRM_DEBUG_DRIVER("DMUB notification skipped, no handler: type=%d\n", notify.type); - continue; - } - if (dm->dmub_thread_offload[notify.type] == true) { - dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC); - if (!dmub_hpd_wrk) { - DRM_ERROR("Failed to allocate dmub_hpd_wrk"); - return; - } - dmub_hpd_wrk->dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_ATOMIC); - if (!dmub_hpd_wrk->dmub_notify) { - kfree(dmub_hpd_wrk); - DRM_ERROR("Failed to allocate dmub_hpd_wrk->dmub_notify"); - return; - } - INIT_WORK(&dmub_hpd_wrk->handle_hpd_work, dm_handle_hpd_work); - if (dmub_hpd_wrk->dmub_notify) - memcpy(dmub_hpd_wrk->dmub_notify, ¬ify, sizeof(struct dmub_notification)); - dmub_hpd_wrk->adev = adev; - if (notify.type == DMUB_NOTIFICATION_HPD) { - plink = adev->dm.dc->links[notify.link_index]; - if (plink) { - plink->hpd_status = - notify.hpd_status == DP_HPD_PLUG; - } - } - queue_work(adev->dm.delayed_hpd_wq, &dmub_hpd_wrk->handle_hpd_work); - } else { - dm->dmub_callback[notify.type](adev, ¬ify); - } - } while (notify.pending_notification); + if (adev->dm.dmub_notify) + memcpy(adev->dm.dmub_notify, ¬ify, sizeof(struct dmub_notification)); + if (notify.type == DMUB_NOTIFICATION_AUX_REPLY) + complete(&adev->dm.dmub_aux_transfer_done); + // TODO : HPD Implementation + + } else { + DRM_ERROR("DM: Failed to receive correct outbox IRQ !"); + } } @@ -820,10 +667,9 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) } while (count <= DMUB_TRACE_MAX_READ); - if (count > DMUB_TRACE_MAX_READ) - DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ"); + ASSERT(count <= DMUB_TRACE_MAX_READ); } -#endif /* CONFIG_DRM_AMD_DC_DCN */ +#endif static int dm_set_clockgating_state(void *handle, enum amd_clockgating_state state) @@ -1027,7 +873,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) const unsigned char *fw_inst_const, *fw_bss_data; uint32_t i, fw_inst_const_size, fw_bss_data_size; bool has_hw_support; - struct dc *dc = adev->dm.dc; if (!dmub_srv) /* DMUB isn't supported on the ASIC. */ @@ -1055,11 +900,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) return 0; } - /* Reset DMCUB if it was previously running - before we overwrite its memory. */ - status = dmub_srv_hw_reset(dmub_srv); - if (status != DMUB_STATUS_OK) - DRM_WARN("Error resetting DMUB HW: %d\n", status); - hdr = (const struct dmcub_firmware_header_v1_0 *)dmub_fw->data; fw_inst_const = dmub_fw->data + @@ -1119,19 +959,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) for (i = 0; i < fb_info->num_fb; ++i) hw_params.fb[i] = &fb_info->fb[i]; - switch (adev->asic_type) { - case CHIP_YELLOW_CARP: - if (dc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_A0) { - hw_params.dpia_supported = true; -#if defined(CONFIG_DRM_AMD_DC_DCN) - hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia; -#endif - } - break; - default: - break; - } - status = dmub_srv_hw_init(dmub_srv, &hw_params); if (status != DMUB_STATUS_OK) { DRM_ERROR("Error initializing DMUB HW: %d\n", status); @@ -1162,32 +989,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) return 0; } -static void dm_dmub_hw_resume(struct amdgpu_device *adev) -{ - struct dmub_srv *dmub_srv = adev->dm.dmub_srv; - enum dmub_status status; - bool init; - - if (!dmub_srv) { - /* DMUB isn't supported on the ASIC. */ - return; - } - - status = dmub_srv_is_hw_init(dmub_srv, &init); - if (status != DMUB_STATUS_OK) - DRM_WARN("DMUB hardware init check failed: %d\n", status); - - if (status == DMUB_STATUS_OK && init) { - /* Wait for firmware load to finish. */ - status = dmub_srv_wait_for_auto_load(dmub_srv, 100000); - if (status != DMUB_STATUS_OK) - DRM_WARN("Wait for DMUB auto-load failed: %d\n", status); - } else { - /* Perform the full hardware initialization. */ - dm_dmub_hw_init(adev); - } -} - #if defined(CONFIG_DRM_AMD_DC_DCN) static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config) { @@ -1282,114 +1083,6 @@ static void vblank_control_worker(struct work_struct *work) } #endif - -static void dm_handle_hpd_rx_offload_work(struct work_struct *work) -{ - struct hpd_rx_irq_offload_work *offload_work; - struct amdgpu_dm_connector *aconnector; - struct dc_link *dc_link; - struct amdgpu_device *adev; - enum dc_connection_type new_connection_type = dc_connection_none; - unsigned long flags; - - offload_work = container_of(work, struct hpd_rx_irq_offload_work, work); - aconnector = offload_work->offload_wq->aconnector; - - if (!aconnector) { - DRM_ERROR("Can't retrieve aconnector in hpd_rx_irq_offload_work"); - goto skip; - } - - adev = drm_to_adev(aconnector->base.dev); - dc_link = aconnector->dc_link; - - mutex_lock(&aconnector->hpd_lock); - if (!dc_link_detect_sink(dc_link, &new_connection_type)) - DRM_ERROR("KMS: Failed to detect connector\n"); - mutex_unlock(&aconnector->hpd_lock); - - if (new_connection_type == dc_connection_none) - goto skip; - - if (amdgpu_in_reset(adev)) - goto skip; - - mutex_lock(&adev->dm.dc_lock); - if (offload_work->data.bytes.device_service_irq.bits.AUTOMATED_TEST) - dc_link_dp_handle_automated_test(dc_link); - else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && - hpd_rx_irq_check_link_loss_status(dc_link, &offload_work->data) && - dc_link_dp_allow_hpd_rx_irq(dc_link)) { - dc_link_dp_handle_link_loss(dc_link); - spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags); - offload_work->offload_wq->is_handling_link_loss = false; - spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags); - } - mutex_unlock(&adev->dm.dc_lock); - -skip: - kfree(offload_work); - -} - -static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(struct dc *dc) -{ - int max_caps = dc->caps.max_links; - int i = 0; - struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq = NULL; - - hpd_rx_offload_wq = kcalloc(max_caps, sizeof(*hpd_rx_offload_wq), GFP_KERNEL); - - if (!hpd_rx_offload_wq) - return NULL; - - - for (i = 0; i < max_caps; i++) { - hpd_rx_offload_wq[i].wq = - create_singlethread_workqueue("amdgpu_dm_hpd_rx_offload_wq"); - - if (hpd_rx_offload_wq[i].wq == NULL) { - DRM_ERROR("create amdgpu_dm_hpd_rx_offload_wq fail!"); - return NULL; - } - - spin_lock_init(&hpd_rx_offload_wq[i].offload_lock); - } - - return hpd_rx_offload_wq; -} - -struct amdgpu_stutter_quirk { - u16 chip_vendor; - u16 chip_device; - u16 subsys_vendor; - u16 subsys_device; - u8 revision; -}; - -static const struct amdgpu_stutter_quirk amdgpu_stutter_quirk_list[] = { - /* https://bugzilla.kernel.org/show_bug.cgi?id=214417 */ - { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 }, - { 0, 0, 0, 0, 0 }, -}; - -static bool dm_should_disable_stutter(struct pci_dev *pdev) -{ - const struct amdgpu_stutter_quirk *p = amdgpu_stutter_quirk_list; - - while (p && p->chip_device != 0) { - if (pdev->vendor == p->chip_vendor && - pdev->device == p->chip_device && - pdev->subsystem_vendor == p->subsys_vendor && - pdev->subsystem_device == p->subsys_device && - pdev->revision == p->revision) { - return true; - } - ++p; - } - return false; -} - static int amdgpu_dm_init(struct amdgpu_device *adev) { struct dc_init_data init_data; @@ -1445,35 +1138,24 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) switch (adev->asic_type) { case CHIP_CARRIZO: case CHIP_STONEY: + case CHIP_RAVEN: + case CHIP_RENOIR: + init_data.flags.gpu_vm_support = true; + switch (adev->dm.dmcub_fw_version) { + case 0: /* development */ + case 0x1: /* linux-firmware.git hash 6d9f399 */ + case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */ + init_data.flags.disable_dmcu = false; + break; + default: + init_data.flags.disable_dmcu = true; + } + break; + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: init_data.flags.gpu_vm_support = true; break; default: - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(2, 1, 0): - init_data.flags.gpu_vm_support = true; - switch (adev->dm.dmcub_fw_version) { - case 0: /* development */ - case 0x1: /* linux-firmware.git hash 6d9f399 */ - case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */ - init_data.flags.disable_dmcu = false; - break; - default: - init_data.flags.disable_dmcu = true; - } - break; - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - case IP_VERSION(3, 0, 1): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - init_data.flags.gpu_vm_support = true; - break; - case IP_VERSION(2, 0, 3): - init_data.flags.disable_dmcu = true; - break; - default: - break; - } break; } @@ -1489,21 +1171,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_dc_feature_mask & DC_EDP_NO_POWER_SEQUENCING) init_data.flags.edp_no_power_sequencing = true; -#ifdef CONFIG_DRM_AMD_DC_DCN - if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP1_4A) - init_data.flags.allow_lttpr_non_transparent_mode.bits.DP1_4A = true; - if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP2_0) - init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true; -#endif - init_data.flags.power_down_display_on_boot = true; - if (check_seamless_boot_capability(adev)) { - init_data.flags.power_down_display_on_boot = false; - init_data.flags.allow_seamless_boot_optimization = true; - DRM_INFO("Seamless boot condition check passed\n"); - } - INIT_LIST_HEAD(&adev->dm.da_list); /* Display Core create. */ adev->dm.dc = dc_create(&init_data); @@ -1522,16 +1191,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (adev->asic_type != CHIP_CARRIZO && adev->asic_type != CHIP_STONEY) adev->dm.dc->debug.disable_stutter = amdgpu_pp_feature_mask & PP_STUTTER_MODE ? false : true; - if (dm_should_disable_stutter(adev->pdev)) - adev->dm.dc->debug.disable_stutter = true; if (amdgpu_dc_debug_mask & DC_DISABLE_STUTTER) adev->dm.dc->debug.disable_stutter = true; - if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) { + if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) adev->dm.dc->debug.disable_dsc = true; - adev->dm.dc->debug.disable_dsc_edp = true; - } if (amdgpu_dc_debug_mask & DC_DISABLE_CLOCK_GATING) adev->dm.dc->debug.disable_clock_gate = true; @@ -1544,12 +1209,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) dc_hardware_init(adev->dm.dc); - adev->dm.hpd_rx_offload_wq = hpd_rx_irq_create_workqueue(adev->dm.dc); - if (!adev->dm.hpd_rx_offload_wq) { - DRM_ERROR("amdgpu: failed to create hpd rx offload workqueue.\n"); - goto error; - } - #if defined(CONFIG_DRM_AMD_DC_DCN) if ((adev->flags & AMD_IS_APU) && (adev->asic_type >= CHIP_CARRIZO)) { struct dc_phy_addr_space_config pa_config; @@ -1581,7 +1240,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) #endif #ifdef CONFIG_DRM_AMD_DC_HDCP - if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) { + if (adev->dm.dc->caps.max_links > 0 && adev->asic_type >= CHIP_RAVEN) { adev->dm.hdcp_workqueue = hdcp_create_workqueue(adev, &init_params.cp_psp, adev->dm.dc); if (!adev->dm.hdcp_workqueue) @@ -1602,29 +1261,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) DRM_INFO("amdgpu: fail to allocate adev->dm.dmub_notify"); goto error; } - - adev->dm.delayed_hpd_wq = create_singlethread_workqueue("amdgpu_dm_hpd_wq"); - if (!adev->dm.delayed_hpd_wq) { - DRM_ERROR("amdgpu: failed to create hpd offload workqueue.\n"); - goto error; - } - amdgpu_dm_outbox_init(adev); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_AUX_REPLY, - dmub_aux_setconfig_callback, false)) { - DRM_ERROR("amdgpu: fail to register dmub aux callback"); - goto error; - } - if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD, dmub_hpd_callback, true)) { - DRM_ERROR("amdgpu: fail to register dmub hpd callback"); - goto error; - } - if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_HPD_IRQ, dmub_hpd_callback, true)) { - DRM_ERROR("amdgpu: fail to register dmub hpd callback"); - goto error; - } -#endif /* CONFIG_DRM_AMD_DC_DCN */ } if (amdgpu_dm_initialize_drm_device(adev)) { @@ -1706,8 +1343,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) if (dc_enable_dmub_notifications(adev->dm.dc)) { kfree(adev->dm.dmub_notify); adev->dm.dmub_notify = NULL; - destroy_workqueue(adev->dm.delayed_hpd_wq); - adev->dm.delayed_hpd_wq = NULL; } if (adev->dm.dmub_bo) @@ -1715,18 +1350,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) &adev->dm.dmub_bo_gpu_addr, &adev->dm.dmub_bo_cpu_addr); - if (adev->dm.hpd_rx_offload_wq) { - for (i = 0; i < adev->dm.dc->caps.max_links; i++) { - if (adev->dm.hpd_rx_offload_wq[i].wq) { - destroy_workqueue(adev->dm.hpd_rx_offload_wq[i].wq); - adev->dm.hpd_rx_offload_wq[i].wq = NULL; - } - } - - kfree(adev->dm.hpd_rx_offload_wq); - adev->dm.hpd_rx_offload_wq = NULL; - } - /* DC Destroy TODO: Replace destroy DAL */ if (adev->dm.dc) dc_destroy(&adev->dm.dc); @@ -1780,6 +1403,15 @@ static int load_dmcu_fw(struct amdgpu_device *adev) case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_VEGA20: + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_RENOIR: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: return 0; case CHIP_NAVI12: fw_name_dmcu = FIRMWARE_NAVI12_DMCU; @@ -1793,21 +1425,6 @@ static int load_dmcu_fw(struct amdgpu_device *adev) return 0; break; default: - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 0, 3): - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 1, 0): - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 2): - case IP_VERSION(3, 0, 3): - case IP_VERSION(3, 0, 1): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - return 0; - default: - break; - } DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); return -EINVAL; } @@ -1886,37 +1503,35 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) enum dmub_status status; int r; - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(2, 1, 0): + switch (adev->asic_type) { + case CHIP_RENOIR: dmub_asic = DMUB_ASIC_DCN21; fw_name_dmub = FIRMWARE_RENOIR_DMUB; if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) fw_name_dmub = FIRMWARE_GREEN_SARDINE_DMUB; break; - case IP_VERSION(3, 0, 0): - if (adev->ip_versions[GC_HWIP][0] == IP_VERSION(10, 3, 0)) { - dmub_asic = DMUB_ASIC_DCN30; - fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; - } else { - dmub_asic = DMUB_ASIC_DCN30; - fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; - } + case CHIP_SIENNA_CICHLID: + dmub_asic = DMUB_ASIC_DCN30; + fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; break; - case IP_VERSION(3, 0, 1): + case CHIP_NAVY_FLOUNDER: + dmub_asic = DMUB_ASIC_DCN30; + fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; + break; + case CHIP_VANGOGH: dmub_asic = DMUB_ASIC_DCN301; fw_name_dmub = FIRMWARE_VANGOGH_DMUB; break; - case IP_VERSION(3, 0, 2): + case CHIP_DIMGREY_CAVEFISH: dmub_asic = DMUB_ASIC_DCN302; fw_name_dmub = FIRMWARE_DIMGREY_CAVEFISH_DMUB; break; - case IP_VERSION(3, 0, 3): + case CHIP_BEIGE_GOBY: dmub_asic = DMUB_ASIC_DCN303; fw_name_dmub = FIRMWARE_BEIGE_GOBY_DMUB; break; - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31; + case CHIP_YELLOW_CARP: + dmub_asic = DMUB_ASIC_DCN31; fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB; break; @@ -2215,9 +1830,10 @@ static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) * therefore, this function apply to navi10/12/14 but not Renoir * * */ - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 0, 0): + switch(adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: break; default: return 0; @@ -2354,6 +1970,14 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) goto fail; } + + res = dc_validate_global_state(dc, context, false); + + if (res != DC_OK) { + DRM_ERROR("%s:resource validation failed, dc_status:%d\n", __func__, res); + goto fail; + } + res = dc_commit_state(dc, context); fail: @@ -2363,16 +1987,6 @@ static enum dc_status amdgpu_dm_commit_zero_streams(struct dc *dc) return res; } -static void hpd_rx_irq_work_suspend(struct amdgpu_display_manager *dm) -{ - int i; - - if (dm->hpd_rx_offload_wq) { - for (i = 0; i < dm->dc->caps.max_links; i++) - flush_workqueue(dm->hpd_rx_offload_wq[i].wq); - } -} - static int dm_suspend(void *handle) { struct amdgpu_device *adev = handle; @@ -2394,8 +2008,6 @@ static int dm_suspend(void *handle) amdgpu_dm_irq_suspend(adev); - hpd_rx_irq_work_suspend(dm); - return ret; } @@ -2406,8 +2018,6 @@ static int dm_suspend(void *handle) amdgpu_dm_irq_suspend(adev); - hpd_rx_irq_work_suspend(dm); - dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); return 0; @@ -2554,7 +2164,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, return; } -static void dm_set_dpms_off(struct dc_link *link, struct dm_crtc_state *acrtc_state) +static void dm_set_dpms_off(struct dc_link *link) { struct dc_stream_state *stream_state; struct amdgpu_dm_connector *aconnector = link->priv; @@ -2575,7 +2185,6 @@ static void dm_set_dpms_off(struct dc_link *link, struct dm_crtc_state *acrtc_st } stream_update.stream = stream_state; - acrtc_state->force_dpms_off = true; dc_commit_updates_for_stream(stream_state->ctx->dc, NULL, 0, stream_state, &stream_update, stream_state->ctx->dc->current_state); @@ -2604,20 +2213,6 @@ static int dm_resume(void *handle) if (amdgpu_in_reset(adev)) { dc_state = dm->cached_dc_state; - /* - * The dc->current_state is backed up into dm->cached_dc_state - * before we commit 0 streams. - * - * DC will clear link encoder assignments on the real state - * but the changes won't propagate over to the copy we made - * before the 0 streams commit. - * - * DC expects that link encoder assignments are *not* valid - * when committing a state, so as a workaround it needs to be - * cleared here. - */ - link_enc_cfg_init(dm->dc, dc_state); - if (dc_enable_dmub_notifications(adev->dm.dc)) amdgpu_dm_outbox_init(adev); @@ -2637,6 +2232,15 @@ static int dm_resume(void *handle) = 0xffffffff; } } +#if defined(CONFIG_DRM_AMD_DC_DCN) + /* + * Resource allocation happens for link encoders for newer ASIC in + * dc_validate_global_state, so we need to revalidate it. + * + * This shouldn't fail (it passed once before), so warn if it does. + */ + WARN_ON(dc_validate_global_state(dm->dc, dc_state, false) != DC_OK); +#endif WARN_ON(!dc_commit_state(dm->dc, dc_state)); @@ -2664,7 +2268,9 @@ static int dm_resume(void *handle) amdgpu_dm_outbox_init(adev); /* Before powering on DC we need to re-initialize DMUB. */ - dm_dmub_hw_resume(adev); + r = dm_dmub_hw_init(adev); + if (r) + DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); /* power on hardware */ dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); @@ -2991,12 +2597,13 @@ void amdgpu_dm_update_connector_after_detect( aconnector->edid = (struct edid *)sink->dc_edid.raw_edid; + drm_connector_update_edid_property(connector, + aconnector->edid); if (aconnector->dc_link->aux_mode) drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, aconnector->edid); } - drm_connector_update_edid_property(connector, aconnector->edid); amdgpu_dm_update_freesync_caps(connector, aconnector->edid); update_connector_ext_caps(aconnector); } else { @@ -3022,22 +2629,20 @@ void amdgpu_dm_update_connector_after_detect( dc_sink_release(sink); } -static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) +static void handle_hpd_irq(void *param) { + struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; struct drm_connector *connector = &aconnector->base; struct drm_device *dev = connector->dev; enum dc_connection_type new_connection_type = dc_connection_none; struct amdgpu_device *adev = drm_to_adev(dev); +#ifdef CONFIG_DRM_AMD_DC_HDCP struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state); - struct dm_crtc_state *dm_crtc_state = NULL; +#endif if (adev->dm.disable_hpd_irq) return; - if (dm_con_state->base.state && dm_con_state->base.crtc) - dm_crtc_state = to_dm_crtc_state(drm_atomic_get_crtc_state( - dm_con_state->base.state, - dm_con_state->base.crtc)); /* * In case of failure or MST no need to update connector status or notify the OS * since (for MST case) MST does this in its own context. @@ -3059,18 +2664,18 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) if (aconnector->base.force && new_connection_type == dc_connection_none) { emulated_link_detect(aconnector->dc_link); + drm_modeset_lock_all(dev); dm_restore_drm_connector_state(dev, connector); drm_modeset_unlock_all(dev); if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) { if (new_connection_type == dc_connection_none && - aconnector->dc_link->type == dc_connection_none && - dm_crtc_state) - dm_set_dpms_off(aconnector->dc_link, dm_crtc_state); + aconnector->dc_link->type == dc_connection_none) + dm_set_dpms_off(aconnector->dc_link); amdgpu_dm_update_connector_after_detect(aconnector); @@ -3079,21 +2684,13 @@ static void handle_hpd_irq_helper(struct amdgpu_dm_connector *aconnector) drm_modeset_unlock_all(dev); if (aconnector->base.force == DRM_FORCE_UNSPECIFIED) - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } mutex_unlock(&aconnector->hpd_lock); } -static void handle_hpd_irq(void *param) -{ - struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; - - handle_hpd_irq_helper(aconnector); - -} - -static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) +static void dm_handle_hpd_rx_irq(struct amdgpu_dm_connector *aconnector) { uint8_t esi[DP_PSR_ERROR_STATUS - DP_SINK_COUNT_ESI] = { 0 }; uint8_t dret; @@ -3171,25 +2768,6 @@ static void dm_handle_mst_sideband_msg(struct amdgpu_dm_connector *aconnector) DRM_DEBUG_DRIVER("Loop exceeded max iterations\n"); } -static void schedule_hpd_rx_offload_work(struct hpd_rx_irq_offload_work_queue *offload_wq, - union hpd_irq_data hpd_irq_data) -{ - struct hpd_rx_irq_offload_work *offload_work = - kzalloc(sizeof(*offload_work), GFP_KERNEL); - - if (!offload_work) { - DRM_ERROR("Failed to allocate hpd_rx_irq_offload_work.\n"); - return; - } - - INIT_WORK(&offload_work->work, dm_handle_hpd_rx_offload_work); - offload_work->data = hpd_irq_data; - offload_work->offload_wq = offload_wq; - - queue_work(offload_wq->wq, &offload_work->work); - DRM_DEBUG_KMS("queue work to handle hpd_rx offload work"); -} - static void handle_hpd_rx_irq(void *param) { struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; @@ -3201,16 +2779,14 @@ static void handle_hpd_rx_irq(void *param) enum dc_connection_type new_connection_type = dc_connection_none; struct amdgpu_device *adev = drm_to_adev(dev); union hpd_irq_data hpd_irq_data; - bool link_loss = false; - bool has_left_work = false; - int idx = aconnector->base.index; - struct hpd_rx_irq_offload_work_queue *offload_wq = &adev->dm.hpd_rx_offload_wq[idx]; + bool lock_flag = 0; memset(&hpd_irq_data, 0, sizeof(hpd_irq_data)); if (adev->dm.disable_hpd_irq) return; + /* * TODO:Temporary add mutex to protect hpd interrupt not have a gpio * conflict, after implement i2c helper, this mutex should be @@ -3218,42 +2794,44 @@ static void handle_hpd_rx_irq(void *param) */ mutex_lock(&aconnector->hpd_lock); - result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, - &link_loss, true, &has_left_work); + read_hpd_rx_irq_data(dc_link, &hpd_irq_data); - if (!has_left_work) - goto out; - - if (hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST) { - schedule_hpd_rx_offload_work(offload_wq, hpd_irq_data); - goto out; - } - - if (dc_link_dp_allow_hpd_rx_irq(dc_link)) { - if (hpd_irq_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY || - hpd_irq_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { - dm_handle_mst_sideband_msg(aconnector); + if ((dc_link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) || + (dc_link->type == dc_connection_mst_branch)) { + if (hpd_irq_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) { + result = true; + dm_handle_hpd_rx_irq(aconnector); goto out; - } - - if (link_loss) { - bool skip = false; - - spin_lock(&offload_wq->offload_lock); - skip = offload_wq->is_handling_link_loss; - - if (!skip) - offload_wq->is_handling_link_loss = true; - - spin_unlock(&offload_wq->offload_lock); - - if (!skip) - schedule_hpd_rx_offload_work(offload_wq, hpd_irq_data); - + } else if (hpd_irq_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { + result = false; + dm_handle_hpd_rx_irq(aconnector); goto out; } } + /* + * TODO: We need the lock to avoid touching DC state while it's being + * modified during automated compliance testing, or when link loss + * happens. While this should be split into subhandlers and proper + * interfaces to avoid having to conditionally lock like this in the + * outer layer, we need this workaround temporarily to allow MST + * lightup in some scenarios to avoid timeout. + */ + if (!amdgpu_in_reset(adev) && + (hpd_rx_irq_check_link_loss_status(dc_link, &hpd_irq_data) || + hpd_irq_data.bytes.device_service_irq.bits.AUTOMATED_TEST)) { + mutex_lock(&adev->dm.dc_lock); + lock_flag = 1; + } + +#ifdef CONFIG_DRM_AMD_DC_HDCP + result = dc_link_handle_hpd_rx_irq(dc_link, &hpd_irq_data, NULL); +#else + result = dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL); +#endif + if (!amdgpu_in_reset(adev) && lock_flag) + mutex_unlock(&adev->dm.dc_lock); + out: if (result && !is_mst_root_connector) { /* Downstream Port status changed. */ @@ -3273,7 +2851,7 @@ static void handle_hpd_rx_irq(void *param) dm_restore_drm_connector_state(dev, connector); drm_modeset_unlock_all(dev); - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } else if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) { if (aconnector->fake_enable) @@ -3286,7 +2864,7 @@ static void handle_hpd_rx_irq(void *param) dm_restore_drm_connector_state(dev, connector); drm_modeset_unlock_all(dev); - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } } #ifdef CONFIG_DRM_AMD_DC_HDCP @@ -3337,10 +2915,6 @@ static void register_hpd_handlers(struct amdgpu_device *adev) amdgpu_dm_irq_register_interrupt(adev, &int_params, handle_hpd_rx_irq, (void *) aconnector); - - if (adev->dm.hpd_rx_offload_wq) - adev->dm.hpd_rx_offload_wq[connector->index].aconnector = - aconnector; } } } @@ -3438,7 +3012,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) int i; unsigned client_id = AMDGPU_IRQ_CLIENTID_LEGACY; - if (adev->family >= AMDGPU_FAMILY_AI) + if (adev->asic_type >= CHIP_VEGA10) client_id = SOC15_IH_CLIENTID_DCE; int_params.requested_polarity = INTERRUPT_POLARITY_DEFAULT; @@ -3961,9 +3535,6 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm, caps = dm->backlight_caps[bl_idx]; dm->brightness[bl_idx] = user_brightness; - /* update scratch register */ - if (bl_idx == 0) - amdgpu_atombios_scratch_regs_set_backlight_level(dm->adev, dm->brightness[bl_idx]); brightness = convert_brightness_from_user(&caps, dm->brightness[bl_idx]); link = (struct dc_link *)dm->backlight_link[bl_idx]; @@ -4158,7 +3729,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) int32_t primary_planes; enum dc_connection_type new_connection_type = dc_connection_none; const struct dc_plane_cap *plane; - bool psr_feature_enabled = false; dm->display_indexes_num = dm->dc->caps.max_streams; /* Update the actual used number of crtc */ @@ -4227,32 +3797,18 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) #if defined(CONFIG_DRM_AMD_DC_DCN) /* Use Outbox interrupt */ - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - case IP_VERSION(2, 1, 0): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_YELLOW_CARP: + case CHIP_RENOIR: if (register_outbox_irq_handlers(dm->adev)) { DRM_ERROR("DM: Failed to initialize IRQ\n"); goto fail; } break; default: - DRM_DEBUG_KMS("Unsupported DCN IP version for outbox: 0x%X\n", - adev->ip_versions[DCE_HWIP][0]); - } - - /* Determine whether to enable PSR support by default. */ - if (!(amdgpu_dc_debug_mask & DC_DISABLE_PSR)) { - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - psr_feature_enabled = true; - break; - default: - psr_feature_enabled = amdgpu_dc_feature_mask & DC_PSR_MASK; - break; - } + DRM_DEBUG_KMS("Unsupported ASIC type for outbox: 0x%X\n", adev->asic_type); } #endif @@ -4300,9 +3856,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) } else if (dc_link_detect(link, DETECT_REASON_BOOT)) { amdgpu_dm_update_connector_after_detect(aconnector); register_backlight_device(dm, link); + if (dm->num_of_edps) update_connector_ext_caps(aconnector); - if (psr_feature_enabled) + if (amdgpu_dc_feature_mask & DC_PSR_MASK) amdgpu_dm_set_psr_caps(link); /* TODO: Fix vblank control helpers to delay PSR entry to allow this when @@ -4349,33 +3906,27 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) goto fail; } break; - default: #if defined(CONFIG_DRM_AMD_DC_DCN) - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - case IP_VERSION(2, 0, 2): - case IP_VERSION(2, 0, 3): - case IP_VERSION(2, 0, 0): - case IP_VERSION(2, 1, 0): - case IP_VERSION(3, 0, 0): - case IP_VERSION(3, 0, 2): - case IP_VERSION(3, 0, 3): - case IP_VERSION(3, 0, 1): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - if (dcn10_register_irq_handlers(dm->adev)) { - DRM_ERROR("DM: Failed to initialize IRQ\n"); - goto fail; - } - break; - default: - DRM_ERROR("Unsupported DCE IP versions: 0x%X\n", - adev->ip_versions[DCE_HWIP][0]); + case CHIP_RAVEN: + case CHIP_NAVI12: + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_RENOIR: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_VANGOGH: + case CHIP_YELLOW_CARP: + if (dcn10_register_irq_handlers(dm->adev)) { + DRM_ERROR("DM: Failed to initialize IRQ\n"); goto fail; } -#endif break; +#endif + default: + DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); + goto fail; } return 0; @@ -4522,44 +4073,42 @@ static int dm_early_init(void *handle) adev->mode_info.num_hpd = 6; adev->mode_info.num_dig = 6; break; - default: #if defined(CONFIG_DRM_AMD_DC_DCN) - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(2, 0, 2): - case IP_VERSION(3, 0, 0): - adev->mode_info.num_crtc = 6; - adev->mode_info.num_hpd = 6; - adev->mode_info.num_dig = 6; - break; - case IP_VERSION(2, 0, 0): - case IP_VERSION(3, 0, 2): - adev->mode_info.num_crtc = 5; - adev->mode_info.num_hpd = 5; - adev->mode_info.num_dig = 5; - break; - case IP_VERSION(2, 0, 3): - case IP_VERSION(3, 0, 3): - adev->mode_info.num_crtc = 2; - adev->mode_info.num_hpd = 2; - adev->mode_info.num_dig = 2; - break; - case IP_VERSION(1, 0, 0): - case IP_VERSION(1, 0, 1): - case IP_VERSION(3, 0, 1): - case IP_VERSION(2, 1, 0): - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - adev->mode_info.num_crtc = 4; - adev->mode_info.num_hpd = 4; - adev->mode_info.num_dig = 4; - break; - default: - DRM_ERROR("Unsupported DCE IP versions: 0x%x\n", - adev->ip_versions[DCE_HWIP][0]); - return -EINVAL; - } -#endif + case CHIP_RAVEN: + case CHIP_RENOIR: + case CHIP_VANGOGH: + adev->mode_info.num_crtc = 4; + adev->mode_info.num_hpd = 4; + adev->mode_info.num_dig = 4; break; + case CHIP_NAVI10: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + adev->mode_info.num_crtc = 6; + adev->mode_info.num_hpd = 6; + adev->mode_info.num_dig = 6; + break; + case CHIP_YELLOW_CARP: + adev->mode_info.num_crtc = 4; + adev->mode_info.num_hpd = 4; + adev->mode_info.num_dig = 4; + break; + case CHIP_NAVI14: + case CHIP_DIMGREY_CAVEFISH: + adev->mode_info.num_crtc = 5; + adev->mode_info.num_hpd = 5; + adev->mode_info.num_dig = 5; + break; + case CHIP_BEIGE_GOBY: + adev->mode_info.num_crtc = 2; + adev->mode_info.num_hpd = 2; + adev->mode_info.num_dig = 2; + break; +#endif + default: + DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); + return -EINVAL; } amdgpu_dm_set_irq_funcs(adev); @@ -4647,8 +4196,7 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, } -static int fill_dc_scaling_info(struct amdgpu_device *adev, - const struct drm_plane_state *state, +static int fill_dc_scaling_info(const struct drm_plane_state *state, struct dc_scaling_info *scaling_info) { int scale_w, scale_h, min_downscale, max_upscale; @@ -4662,8 +4210,7 @@ static int fill_dc_scaling_info(struct amdgpu_device *adev, /* * For reasons we don't (yet) fully understand a non-zero * src_y coordinate into an NV12 buffer can cause a - * system hang on DCN1x. - * To avoid hangs (and maybe be overly cautious) + * system hang. To avoid hangs (and maybe be overly cautious) * let's reject both non-zero src_x and src_y. * * We currently know of only one use-case to reproduce a @@ -4671,10 +4218,10 @@ static int fill_dc_scaling_info(struct amdgpu_device *adev, * is to gesture the YouTube Android app into full screen * on ChromeOS. */ - if (((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) || - (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) && - (state->fb && state->fb->format->format == DRM_FORMAT_NV12 && - (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0))) + if (state->fb && + state->fb->format->format == DRM_FORMAT_NV12 && + (scaling_info->src_rect.x != 0 || + scaling_info->src_rect.y != 0)) return -EINVAL; scaling_info->src_rect.width = state->src_w >> 16; @@ -4780,7 +4327,12 @@ fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev, tiling_info->gfx9.num_rb_per_se = adev->gfx.config.gb_addr_config_fields.num_rb_per_se; tiling_info->gfx9.shaderEnable = 1; - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) + if (adev->asic_type == CHIP_SIENNA_CICHLID || + adev->asic_type == CHIP_NAVY_FLOUNDER || + adev->asic_type == CHIP_DIMGREY_CAVEFISH || + adev->asic_type == CHIP_BEIGE_GOBY || + adev->asic_type == CHIP_YELLOW_CARP || + adev->asic_type == CHIP_VANGOGH) tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; } @@ -5140,16 +4692,6 @@ add_gfx10_3_modifiers(const struct amdgpu_device *adev, AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); - add_modifier(mods, size, capacity, AMD_FMT_MOD | - AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | - AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | - AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | - AMD_FMT_MOD_SET(PACKERS, pkrs) | - AMD_FMT_MOD_SET(DCC, 1) | - AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | - AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | - AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); - add_modifier(mods, size, capacity, AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | @@ -5162,17 +4704,6 @@ add_gfx10_3_modifiers(const struct amdgpu_device *adev, AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); - add_modifier(mods, size, capacity, AMD_FMT_MOD | - AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | - AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | - AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | - AMD_FMT_MOD_SET(PACKERS, pkrs) | - AMD_FMT_MOD_SET(DCC, 1) | - AMD_FMT_MOD_SET(DCC_RETILE, 1) | - AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | - AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | - AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); - add_modifier(mods, size, capacity, AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | @@ -5221,7 +4752,7 @@ get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, u case AMDGPU_FAMILY_NV: case AMDGPU_FAMILY_VGH: case AMDGPU_FAMILY_YC: - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0)) + if (adev->asic_type >= CHIP_SIENNA_CICHLID) add_gfx10_3_modifiers(adev, mods, &size, &capacity); else add_gfx10_1_modifiers(adev, mods, &size, &capacity); @@ -5258,27 +4789,10 @@ fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev, if (modifier_has_dcc(modifier) && !force_disable_dcc) { uint64_t dcc_address = afb->address + afb->base.offsets[1]; - bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier); - bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier); dcc->enable = 1; dcc->meta_pitch = afb->base.pitches[1]; - dcc->independent_64b_blks = independent_64b_blks; - if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) { - if (independent_64b_blks && independent_128b_blks) - dcc->dcc_ind_blk = hubp_ind_block_64b_no_128bcl; - else if (independent_128b_blks) - dcc->dcc_ind_blk = hubp_ind_block_128b; - else if (independent_64b_blks && !independent_128b_blks) - dcc->dcc_ind_blk = hubp_ind_block_64b; - else - dcc->dcc_ind_blk = hubp_ind_block_unconstrained; - } else { - if (independent_64b_blks) - dcc->dcc_ind_blk = hubp_ind_block_64b; - else - dcc->dcc_ind_blk = hubp_ind_block_unconstrained; - } + dcc->independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier); address->grph.meta_addr.low_part = lower_32_bits(dcc_address); address->grph.meta_addr.high_part = upper_32_bits(dcc_address); @@ -5580,7 +5094,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, int ret; bool force_disable_dcc = false; - ret = fill_dc_scaling_info(adev, plane_state, &scaling_info); + ret = fill_dc_scaling_info(plane_state, &scaling_info); if (ret) return ret; @@ -6101,72 +5615,11 @@ static void update_dsc_caps(struct amdgpu_dm_connector *aconnector, stream->timing.flags.DSC = 0; dsc_caps->is_dsc_supported = false; - if (aconnector->dc_link && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT || - sink->sink_signal == SIGNAL_TYPE_EDP)) { - if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE || - sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) - dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc, - aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw, - aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw, - dsc_caps); - } -} - -static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector, - struct dc_sink *sink, struct dc_stream_state *stream, - struct dsc_dec_dpcd_caps *dsc_caps, - uint32_t max_dsc_target_bpp_limit_override) -{ - const struct dc_link_settings *verified_link_cap = NULL; - uint32_t link_bw_in_kbps; - uint32_t edp_min_bpp_x16, edp_max_bpp_x16; - struct dc *dc = sink->ctx->dc; - struct dc_dsc_bw_range bw_range = {0}; - struct dc_dsc_config dsc_cfg = {0}; - - verified_link_cap = dc_link_get_link_cap(stream->link); - link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap); - edp_min_bpp_x16 = 8 * 16; - edp_max_bpp_x16 = 8 * 16; - - if (edp_max_bpp_x16 > dsc_caps->edp_max_bits_per_pixel) - edp_max_bpp_x16 = dsc_caps->edp_max_bits_per_pixel; - - if (edp_max_bpp_x16 < edp_min_bpp_x16) - edp_min_bpp_x16 = edp_max_bpp_x16; - - if (dc_dsc_compute_bandwidth_range(dc->res_pool->dscs[0], - dc->debug.dsc_min_slice_height_override, - edp_min_bpp_x16, edp_max_bpp_x16, - dsc_caps, - &stream->timing, - &bw_range)) { - - if (bw_range.max_kbps < link_bw_in_kbps) { - if (dc_dsc_compute_config(dc->res_pool->dscs[0], - dsc_caps, - dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, - 0, - &stream->timing, - &dsc_cfg)) { - stream->timing.dsc_cfg = dsc_cfg; - stream->timing.flags.DSC = 1; - stream->timing.dsc_cfg.bits_per_pixel = edp_max_bpp_x16; - } - return; - } - } - - if (dc_dsc_compute_config(dc->res_pool->dscs[0], - dsc_caps, - dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, - link_bw_in_kbps, - &stream->timing, - &dsc_cfg)) { - stream->timing.dsc_cfg = dsc_cfg; - stream->timing.flags.DSC = 1; + if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) { + dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc, + aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.raw, + aconnector->dc_link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw, + dsc_caps); } } @@ -6176,59 +5629,24 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, { struct drm_connector *drm_connector = &aconnector->base; uint32_t link_bandwidth_kbps; - uint32_t max_dsc_target_bpp_limit_override = 0; - struct dc *dc = sink->ctx->dc; - uint32_t max_supported_bw_in_kbps, timing_bw_in_kbps; - uint32_t dsc_max_supported_bw_in_kbps; link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, dc_link_get_link_cap(aconnector->dc_link)); - - if (stream->link && stream->link->local_sink) - max_dsc_target_bpp_limit_override = - stream->link->local_sink->edid_caps.panel_patch.max_dsc_target_bpp_limit; - /* Set DSC policy according to dsc_clock_en */ dc_dsc_policy_set_enable_dsc_when_not_needed( aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE); - if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_EDP && !dc->debug.disable_dsc_edp && - dc->caps.edp_dsc_support && aconnector->dsc_settings.dsc_force_enable != DSC_CLK_FORCE_DISABLE) { + if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) { - apply_dsc_policy_for_edp(aconnector, sink, stream, dsc_caps, max_dsc_target_bpp_limit_override); - - } else if (aconnector->dc_link && sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT) { - if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) { - if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], + if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], dsc_caps, aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, + 0, link_bandwidth_kbps, &stream->timing, &stream->timing.dsc_cfg)) { - stream->timing.flags.DSC = 1; - DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", - __func__, drm_connector->name); - } - } else if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) { - timing_bw_in_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing); - max_supported_bw_in_kbps = link_bandwidth_kbps; - dsc_max_supported_bw_in_kbps = link_bandwidth_kbps; - - if (timing_bw_in_kbps > max_supported_bw_in_kbps && - max_supported_bw_in_kbps > 0 && - dsc_max_supported_bw_in_kbps > 0) - if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], - dsc_caps, - aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, - max_dsc_target_bpp_limit_override, - dsc_max_supported_bw_in_kbps, - &stream->timing, - &stream->timing.dsc_cfg)) { - stream->timing.flags.DSC = 1; - DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from DP-HDMI PCON\n", - __func__, drm_connector->name); - } + stream->timing.flags.DSC = 1; + DRM_DEBUG_DRIVER("%s: [%s] DSC is selected from SST RX\n", __func__, drm_connector->name); } } @@ -6245,7 +5663,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, if (stream->timing.flags.DSC && aconnector->dsc_settings.dsc_bits_per_pixel) stream->timing.dsc_cfg.bits_per_pixel = aconnector->dsc_settings.dsc_bits_per_pixel; } -#endif /* CONFIG_DRM_AMD_DC_DCN */ +#endif /** * DOC: FreeSync Video @@ -6263,7 +5681,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector, * - Cinema HFR (48 FPS) * - TV/PAL (50 FPS) * - Commonly used (60 FPS) - * - Multiples of 24 (48,72,96,120 FPS) + * - Multiples of 24 (48,72,96 FPS) * * The list of standards video format is not huge and can be added to the * connector modeset list beforehand. With that, userspace can leverage @@ -6574,7 +5992,6 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) state->freesync_config = cur->freesync_config; state->cm_has_degamma = cur->cm_has_degamma; state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; - state->force_dpms_off = cur->force_dpms_off; /* TODO Duplicate dc_stream after objects are stream object is flattened */ return &state->base; @@ -7416,8 +6833,8 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, struct drm_connector_state *new_con_state; struct amdgpu_dm_connector *aconnector; struct dm_connector_state *dm_conn_state; - int i, j; - int vcpi, pbn_div, pbn, slot_num = 0; + int i, j, clock; + int vcpi, pbn_div, pbn = 0; for_each_new_connector_in_state(state, connector, new_con_state, i) { @@ -7445,24 +6862,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, if (!stream) continue; - pbn_div = dm_mst_get_pbn_divider(stream->link); - /* pbn is calculated by compute_mst_dsc_configs_for_state*/ - for (j = 0; j < dc_state->stream_count; j++) { - if (vars[j].aconnector == aconnector) { - pbn = vars[j].pbn; - break; - } - } - - if (j == dc_state->stream_count) - continue; - - slot_num = DIV_ROUND_UP(pbn, pbn_div); - if (stream->timing.flags.DSC != 1) { - dm_conn_state->pbn = pbn; - dm_conn_state->vcpi_slots = slot_num; - drm_dp_mst_atomic_enable_dsc(state, aconnector->port, dm_conn_state->pbn, @@ -7471,6 +6871,16 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, continue; } + pbn_div = dm_mst_get_pbn_divider(stream->link); + clock = stream->timing.pix_clk_100hz / 10; + /* pbn is calculated by compute_mst_dsc_configs_for_state*/ + for (j = 0; j < dc_state->stream_count; j++) { + if (vars[j].aconnector == aconnector) { + pbn = vars[j].pbn; + break; + } + } + vcpi = drm_dp_mst_atomic_enable_dsc(state, aconnector->port, pbn, pbn_div, @@ -7734,7 +7144,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; - ret = fill_dc_scaling_info(adev, new_plane_state, &scaling_info); + ret = fill_dc_scaling_info(new_plane_state, &scaling_info); if (ret) return ret; @@ -8232,19 +7642,19 @@ static uint add_fs_modes(struct amdgpu_dm_connector *aconnector) /* Standard FPS values * - * 23.976 - TV/NTSC - * 24 - Cinema - * 25 - TV/PAL - * 29.97 - TV/NTSC - * 30 - TV/NTSC - * 48 - Cinema HFR - * 50 - TV/PAL - * 60 - Commonly used - * 48,72,96,120 - Multiples of 24 + * 23.976 - TV/NTSC + * 24 - Cinema + * 25 - TV/PAL + * 29.97 - TV/NTSC + * 30 - TV/NTSC + * 48 - Cinema HFR + * 50 - TV/PAL + * 60 - Commonly used + * 48,72,96 - Multiples of 24 */ static const uint32_t common_rates[] = { 23976, 24000, 25000, 29970, 30000, - 48000, 50000, 60000, 72000, 96000, 120000 + 48000, 50000, 60000, 72000, 96000 }; /* @@ -8372,10 +7782,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, break; case DRM_MODE_CONNECTOR_DisplayPort: aconnector->base.polled = DRM_CONNECTOR_POLL_HPD; - link->link_enc = dp_get_link_enc(link); - ASSERT(link->link_enc); - if (link->link_enc) - aconnector->base.ycbcr_420_allowed = + aconnector->base.ycbcr_420_allowed = link->link_enc->features.dp_ycbcr420_supported ? true : false; break; case DRM_MODE_CONNECTOR_DVID: @@ -8490,8 +7897,7 @@ create_i2c(struct ddc_service *ddc_service, snprintf(i2c->base.name, sizeof(i2c->base.name), "AMDGPU DM i2c hw bus %d", link_index); i2c_set_adapdata(&i2c->base, i2c); i2c->ddc_service = ddc_service; - if (i2c->ddc_service->ddc_pin) - i2c->ddc_service->ddc_pin->hw_info.ddc_channel = link_index; + i2c->ddc_service->ddc_pin->hw_info.ddc_channel = link_index; return i2c; } @@ -9175,7 +8581,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; } - fill_dc_scaling_info(dm->adev, new_plane_state, + fill_dc_scaling_info(new_plane_state, &bundle->scaling_infos[planes_count]); bundle->surface_updates[planes_count].scaling_info = @@ -9302,8 +8708,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * and rely on sending it from software. */ if (acrtc_attach->base.state->event && - acrtc_state->active_planes > 0 && - !acrtc_state->force_dpms_off) { + acrtc_state->active_planes > 0) { drm_crtc_vblank_get(pcrtc); spin_lock_irqsave(&pcrtc->dev->event_lock, flags); @@ -10764,8 +10169,6 @@ static int dm_update_plane_state(struct dc *dc, dm_new_plane_state->dc_state = dc_new_plane_state; - dm_new_crtc_state->mpo_requested |= (plane->type == DRM_PLANE_TYPE_OVERLAY); - /* Tell DC to do a full surface update every time there * is a plane change. Inefficient, but works for now. */ @@ -10778,77 +10181,39 @@ static int dm_update_plane_state(struct dc *dc, return ret; } -static void dm_get_oriented_plane_size(struct drm_plane_state *plane_state, - int *src_w, int *src_h) -{ - switch (plane_state->rotation & DRM_MODE_ROTATE_MASK) { - case DRM_MODE_ROTATE_90: - case DRM_MODE_ROTATE_270: - *src_w = plane_state->src_h >> 16; - *src_h = plane_state->src_w >> 16; - break; - case DRM_MODE_ROTATE_0: - case DRM_MODE_ROTATE_180: - default: - *src_w = plane_state->src_w >> 16; - *src_h = plane_state->src_h >> 16; - break; - } -} - static int dm_check_crtc_cursor(struct drm_atomic_state *state, struct drm_crtc *crtc, struct drm_crtc_state *new_crtc_state) { - struct drm_plane *cursor = crtc->cursor, *underlying; - struct drm_plane_state *new_cursor_state, *new_underlying_state; - int i; - int cursor_scale_w, cursor_scale_h, underlying_scale_w, underlying_scale_h; - int cursor_src_w, cursor_src_h; - int underlying_src_w, underlying_src_h; + struct drm_plane_state *new_cursor_state, *new_primary_state; + int cursor_scale_w, cursor_scale_h, primary_scale_w, primary_scale_h; /* On DCE and DCN there is no dedicated hardware cursor plane. We get a * cursor per pipe but it's going to inherit the scaling and * positioning from the underlying pipe. Check the cursor plane's - * blending properties match the underlying planes'. */ + * blending properties match the primary plane's. */ - new_cursor_state = drm_atomic_get_new_plane_state(state, cursor); - if (!new_cursor_state || !new_cursor_state->fb) { + new_cursor_state = drm_atomic_get_new_plane_state(state, crtc->cursor); + new_primary_state = drm_atomic_get_new_plane_state(state, crtc->primary); + if (!new_cursor_state || !new_primary_state || + !new_cursor_state->fb || !new_primary_state->fb) { return 0; } - dm_get_oriented_plane_size(new_cursor_state, &cursor_src_w, &cursor_src_h); - cursor_scale_w = new_cursor_state->crtc_w * 1000 / cursor_src_w; - cursor_scale_h = new_cursor_state->crtc_h * 1000 / cursor_src_h; + cursor_scale_w = new_cursor_state->crtc_w * 1000 / + (new_cursor_state->src_w >> 16); + cursor_scale_h = new_cursor_state->crtc_h * 1000 / + (new_cursor_state->src_h >> 16); - for_each_new_plane_in_state_reverse(state, underlying, new_underlying_state, i) { - /* Narrow down to non-cursor planes on the same CRTC as the cursor */ - if (new_underlying_state->crtc != crtc || underlying == crtc->cursor) - continue; + primary_scale_w = new_primary_state->crtc_w * 1000 / + (new_primary_state->src_w >> 16); + primary_scale_h = new_primary_state->crtc_h * 1000 / + (new_primary_state->src_h >> 16); - /* Ignore disabled planes */ - if (!new_underlying_state->fb) - continue; - - dm_get_oriented_plane_size(new_underlying_state, - &underlying_src_w, &underlying_src_h); - underlying_scale_w = new_underlying_state->crtc_w * 1000 / underlying_src_w; - underlying_scale_h = new_underlying_state->crtc_h * 1000 / underlying_src_h; - - if (cursor_scale_w != underlying_scale_w || - cursor_scale_h != underlying_scale_h) { - drm_dbg_atomic(crtc->dev, - "Cursor [PLANE:%d:%s] scaling doesn't match underlying [PLANE:%d:%s]\n", - cursor->base.id, cursor->name, underlying->base.id, underlying->name); - return -EINVAL; - } - - /* If this plane covers the whole CRTC, no need to check planes underneath */ - if (new_underlying_state->crtc_x <= 0 && - new_underlying_state->crtc_y <= 0 && - new_underlying_state->crtc_x + new_underlying_state->crtc_w >= new_crtc_state->mode.hdisplay && - new_underlying_state->crtc_y + new_underlying_state->crtc_h >= new_crtc_state->mode.vdisplay) - break; + if (cursor_scale_w != primary_scale_w || + cursor_scale_h != primary_scale_h) { + drm_dbg_atomic(crtc->dev, "Cursor plane scaling doesn't match primary plane\n"); + return -EINVAL; } return 0; @@ -10879,6 +10244,53 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm } #endif +static int validate_overlay(struct drm_atomic_state *state) +{ + int i; + struct drm_plane *plane; + struct drm_plane_state *new_plane_state; + struct drm_plane_state *primary_state, *overlay_state = NULL; + + /* Check if primary plane is contained inside overlay */ + for_each_new_plane_in_state_reverse(state, plane, new_plane_state, i) { + if (plane->type == DRM_PLANE_TYPE_OVERLAY) { + if (drm_atomic_plane_disabling(plane->state, new_plane_state)) + return 0; + + overlay_state = new_plane_state; + continue; + } + } + + /* check if we're making changes to the overlay plane */ + if (!overlay_state) + return 0; + + /* check if overlay plane is enabled */ + if (!overlay_state->crtc) + return 0; + + /* find the primary plane for the CRTC that the overlay is enabled on */ + primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary); + if (IS_ERR(primary_state)) + return PTR_ERR(primary_state); + + /* check if primary plane is enabled */ + if (!primary_state->crtc) + return 0; + + /* Perform the bounds check to ensure the overlay plane covers the primary */ + if (primary_state->crtc_x < overlay_state->crtc_x || + primary_state->crtc_y < overlay_state->crtc_y || + primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w || + primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) { + DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n"); + return -EINVAL; + } + + return 0; +} + /** * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. * @dev: The DRM device @@ -10918,20 +10330,16 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, enum dc_status status; int ret, i; bool lock_and_validation_needed = false; - struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; + struct dm_crtc_state *dm_old_crtc_state; #if defined(CONFIG_DRM_AMD_DC_DCN) struct dsc_mst_fairness_vars vars[MAX_PIPES]; - struct drm_dp_mst_topology_state *mst_state; - struct drm_dp_mst_topology_mgr *mgr; #endif trace_amdgpu_dm_atomic_check_begin(state); ret = drm_atomic_helper_check_modeset(dev, state); - if (ret) { - DRM_DEBUG_DRIVER("drm_atomic_helper_check_modeset() failed\n"); + if (ret) goto fail; - } /* Check connector changes */ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { @@ -10947,7 +10355,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc); if (IS_ERR(new_crtc_state)) { - DRM_DEBUG_DRIVER("drm_atomic_get_crtc_state() failed\n"); ret = PTR_ERR(new_crtc_state); goto fail; } @@ -10962,10 +10369,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = add_affected_mst_dsc_crtcs(state, crtc); - if (ret) { - DRM_DEBUG_DRIVER("add_affected_mst_dsc_crtcs() failed\n"); + if (ret) goto fail; - } } } } @@ -10980,25 +10385,19 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, continue; ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); - if (ret) { - DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n"); + if (ret) goto fail; - } if (!new_crtc_state->enable) continue; ret = drm_atomic_add_affected_connectors(state, crtc); - if (ret) { - DRM_DEBUG_DRIVER("drm_atomic_add_affected_connectors() failed\n"); - goto fail; - } + if (ret) + return ret; ret = drm_atomic_add_affected_planes(state, crtc); - if (ret) { - DRM_DEBUG_DRIVER("drm_atomic_add_affected_planes() failed\n"); + if (ret) goto fail; - } if (dm_old_crtc_state->dsc_force_changed) new_crtc_state->mode_changed = true; @@ -11035,7 +10434,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (IS_ERR(new_plane_state)) { ret = PTR_ERR(new_plane_state); - DRM_DEBUG_DRIVER("new_plane_state is BAD\n"); goto fail; } } @@ -11048,10 +10446,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_plane_state, false, &lock_and_validation_needed); - if (ret) { - DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n"); + if (ret) goto fail; - } } /* Disable all crtcs which require disable */ @@ -11061,10 +10457,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state, false, &lock_and_validation_needed); - if (ret) { - DRM_DEBUG_DRIVER("DISABLE: dm_update_crtc_state() failed\n"); + if (ret) goto fail; - } } /* Enable all crtcs which require enable */ @@ -11074,12 +10468,14 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state, true, &lock_and_validation_needed); - if (ret) { - DRM_DEBUG_DRIVER("ENABLE: dm_update_crtc_state() failed\n"); + if (ret) goto fail; - } } + ret = validate_overlay(state); + if (ret) + goto fail; + /* Add new/modified planes */ for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { ret = dm_update_plane_state(dc, state, plane, @@ -11087,32 +10483,20 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_plane_state, true, &lock_and_validation_needed); - if (ret) { - DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n"); + if (ret) goto fail; - } } /* Run this here since we want to validate the streams we created */ ret = drm_atomic_helper_check_planes(dev, state); - if (ret) { - DRM_DEBUG_DRIVER("drm_atomic_helper_check_planes() failed\n"); + if (ret) goto fail; - } - - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - if (dm_new_crtc_state->mpo_requested) - DRM_DEBUG_DRIVER("MPO enablement requested on crtc:[%p]\n", crtc); - } /* Check cursor planes scaling */ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { ret = dm_check_crtc_cursor(state, crtc, new_crtc_state); - if (ret) { - DRM_DEBUG_DRIVER("dm_check_crtc_cursor() failed\n"); + if (ret) goto fail; - } } if (state->legacy_cursor_update) { @@ -11157,33 +10541,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, lock_and_validation_needed = true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* set the slot info for each mst_state based on the link encoding format */ - for_each_new_mst_mgr_in_state(state, mgr, mst_state, i) { - struct amdgpu_dm_connector *aconnector; - struct drm_connector *connector; - struct drm_connector_list_iter iter; - u8 link_coding_cap; - - if (!mgr->mst_state ) - continue; - - drm_connector_list_iter_begin(dev, &iter); - drm_for_each_connector_iter(connector, &iter) { - int id = connector->index; - - if (id == mst_state->mgr->conn_base_id) { - aconnector = to_amdgpu_dm_connector(connector); - link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link); - drm_dp_mst_update_slots(mst_state, link_coding_cap); - - break; - } - } - drm_connector_list_iter_end(&iter); - - } -#endif /** * Streams and planes are reset when there are changes that affect * bandwidth. Anything that affects bandwidth needs to go through @@ -11199,28 +10556,20 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, */ if (lock_and_validation_needed) { ret = dm_atomic_get_state(state, &dm_state); - if (ret) { - DRM_DEBUG_DRIVER("dm_atomic_get_state() failed\n"); + if (ret) goto fail; - } ret = do_aquire_global_lock(dev, state); - if (ret) { - DRM_DEBUG_DRIVER("do_aquire_global_lock() failed\n"); + if (ret) goto fail; - } #if defined(CONFIG_DRM_AMD_DC_DCN) - if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) { - DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); + if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) goto fail; - } ret = dm_update_mst_vcpi_slots_for_dsc(state, dm_state->context, vars); - if (ret) { - DRM_DEBUG_DRIVER("dm_update_mst_vcpi_slots_for_dsc() failed\n"); + if (ret) goto fail; - } #endif /* @@ -11230,13 +10579,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, * to get stuck in an infinite loop and hang eventually. */ ret = drm_dp_mst_atomic_check(state); - if (ret) { - DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n"); + if (ret) goto fail; - } - status = dc_validate_global_state(dc, dm_state->context, true); + status = dc_validate_global_state(dc, dm_state->context, false); if (status != DC_OK) { - DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)", + drm_dbg_atomic(dev, + "DC global validation failure: %s (%d)", dc_status_to_str(status), status); ret = -EINVAL; goto fail; @@ -11358,7 +10706,7 @@ static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm, sizeof(cmd.edid_cea) - sizeof(cmd.edid_cea.header); input->offset = offset; input->length = length; - input->cea_total_length = total_length; + input->total_length = total_length; memcpy(input->payload, data, length); res = dc_dmub_srv_cmd_with_reply_data(dm->dc->ctx->dmub_srv, &cmd); @@ -11500,7 +10848,6 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); struct dm_connector_state *dm_con_state = NULL; - struct dc_sink *sink; struct drm_device *dev = connector->dev; struct amdgpu_device *adev = drm_to_adev(dev); @@ -11512,31 +10859,28 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, goto update; } - sink = amdgpu_dm_connector->dc_sink ? - amdgpu_dm_connector->dc_sink : - amdgpu_dm_connector->dc_em_sink; - - if (!edid || !sink) { + if (!edid) { dm_con_state = to_dm_connector_state(connector->state); amdgpu_dm_connector->min_vfreq = 0; amdgpu_dm_connector->max_vfreq = 0; amdgpu_dm_connector->pixel_clock_mhz = 0; - connector->display_info.monitor_range.min_vfreq = 0; - connector->display_info.monitor_range.max_vfreq = 0; - freesync_capable = false; goto update; } dm_con_state = to_dm_connector_state(connector->state); + if (!amdgpu_dm_connector->dc_sink) { + DRM_ERROR("dc_sink NULL, could not add free_sync module.\n"); + goto update; + } if (!adev->dm.freesync_module) goto update; - if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT - || sink->sink_signal == SIGNAL_TYPE_EDP) { + if (amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT + || amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_EDP) { bool edid_check_required = false; if (edid) { @@ -11583,7 +10927,7 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, freesync_capable = true; } } - } else if (edid && sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) { + } else if (edid && amdgpu_dm_connector->dc_sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) { i = parse_hdmi_amd_vsdb(amdgpu_dm_connector, edid, &vsdb_info); if (i >= 0 && vsdb_info.freesync_supported) { timing = &edid->detailed_timings[i]; @@ -11665,98 +11009,29 @@ uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address, return value; } -static int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, - struct dc_context *ctx, - uint8_t status_type, - uint32_t *operation_result) -{ - struct amdgpu_device *adev = ctx->driver_context; - int return_status = -1; - struct dmub_notification *p_notify = adev->dm.dmub_notify; - - if (is_cmd_aux) { - if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) { - return_status = p_notify->aux_reply.length; - *operation_result = p_notify->result; - } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT) { - *operation_result = AUX_RET_ERROR_TIMEOUT; - } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) { - *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE; - } else { - *operation_result = AUX_RET_ERROR_UNKNOWN; - } - } else { - if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS) { - return_status = 0; - *operation_result = p_notify->sc_status; - } else { - *operation_result = SET_CONFIG_UNKNOWN_ERROR; - } - } - - return return_status; -} - -int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context *ctx, - unsigned int link_index, void *cmd_payload, void *operation_result) +int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex, + struct aux_payload *payload, enum aux_return_code_type *operation_result) { struct amdgpu_device *adev = ctx->driver_context; int ret = 0; - if (is_cmd_aux) { - dc_process_dmub_aux_transfer_async(ctx->dc, - link_index, (struct aux_payload *)cmd_payload); - } else if (dc_process_dmub_set_config_async(ctx->dc, link_index, - (struct set_config_cmd_payload *)cmd_payload, - adev->dm.dmub_notify)) { - return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, - ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS, - (uint32_t *)operation_result); - } - - ret = wait_for_completion_timeout(&adev->dm.dmub_aux_transfer_done, 10 * HZ); + dc_process_dmub_aux_transfer_async(ctx->dc, linkIndex, payload); + ret = wait_for_completion_interruptible_timeout(&adev->dm.dmub_aux_transfer_done, 10*HZ); if (ret == 0) { - DRM_ERROR("wait_for_completion_timeout timeout!"); - return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, - ctx, DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT, - (uint32_t *)operation_result); + *operation_result = AUX_RET_ERROR_TIMEOUT; + return -1; + } + *operation_result = (enum aux_return_code_type)adev->dm.dmub_notify->result; + + if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) { + (*payload->reply) = adev->dm.dmub_notify->aux_reply.command; + + // For read case, Copy data to payload + if (!payload->write && adev->dm.dmub_notify->aux_reply.length && + (*payload->reply == AUX_TRANSACTION_REPLY_AUX_ACK)) + memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data, + adev->dm.dmub_notify->aux_reply.length); } - if (is_cmd_aux) { - if (adev->dm.dmub_notify->result == AUX_RET_SUCCESS) { - struct aux_payload *payload = (struct aux_payload *)cmd_payload; - - payload->reply[0] = adev->dm.dmub_notify->aux_reply.command; - if (!payload->write && adev->dm.dmub_notify->aux_reply.length && - payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) { - memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data, - adev->dm.dmub_notify->aux_reply.length); - } - } - } - - return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, - ctx, DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS, - (uint32_t *)operation_result); -} - -/* - * Check whether seamless boot is supported. - * - * So far we only support seamless boot on CHIP_VANGOGH. - * If everything goes well, we may consider expanding - * seamless boot to other ASICs. - */ -bool check_seamless_boot_capability(struct amdgpu_device *adev) -{ - switch (adev->asic_type) { - case CHIP_VANGOGH: - if (!adev->mman.keep_stolen_vga_memory) - return true; - break; - default: - break; - } - - return false; + return adev->dm.dmub_notify->aux_reply.length; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index b9a69b0cef..d1d353a7c7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -47,15 +47,6 @@ #define AMDGPU_DM_MAX_CRTC 6 #define AMDGPU_DM_MAX_NUM_EDP 2 - -#define AMDGPU_DMUB_NOTIFICATION_MAX 5 - -/* - * DMUB Async to Sync Mechanism Status - */ -#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1 -#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2 -#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3 /* #include "include/amdgpu_dal_power_if.h" #include "amdgpu_dm_irq.h" @@ -95,21 +86,6 @@ struct dm_compressor_info { uint64_t gpu_addr; }; -typedef void (*dmub_notify_interrupt_callback_t)(struct amdgpu_device *adev, struct dmub_notification *notify); - -/** - * struct dmub_hpd_work - Handle time consuming work in low priority outbox IRQ - * - * @handle_hpd_work: Work to be executed in a separate thread to handle hpd_low_irq - * @dmub_notify: notification for callback function - * @adev: amdgpu_device pointer - */ -struct dmub_hpd_work { - struct work_struct handle_hpd_work; - struct dmub_notification *dmub_notify; - struct amdgpu_device *adev; -}; - /** * struct vblank_control_work - Work data for vblank control * @work: Kernel work data for the work event @@ -178,48 +154,6 @@ struct dal_allocation { u64 gpu_addr; }; -/** - * struct hpd_rx_irq_offload_work_queue - Work queue to handle hpd_rx_irq - * offload work - */ -struct hpd_rx_irq_offload_work_queue { - /** - * @wq: workqueue structure to queue offload work. - */ - struct workqueue_struct *wq; - /** - * @offload_lock: To protect fields of offload work queue. - */ - spinlock_t offload_lock; - /** - * @is_handling_link_loss: Used to prevent inserting link loss event when - * we're handling link loss - */ - bool is_handling_link_loss; - /** - * @aconnector: The aconnector that this work queue is attached to - */ - struct amdgpu_dm_connector *aconnector; -}; - -/** - * struct hpd_rx_irq_offload_work - hpd_rx_irq offload work structure - */ -struct hpd_rx_irq_offload_work { - /** - * @work: offload work - */ - struct work_struct work; - /** - * @data: reference irq data which is used while handling offload work - */ - union hpd_irq_data data; - /** - * @offload_wq: offload work queue that this work is queued to - */ - struct hpd_rx_irq_offload_work_queue *offload_wq; -}; - /** * struct amdgpu_display_manager - Central amdgpu display manager device * @@ -256,30 +190,8 @@ struct amdgpu_display_manager { */ struct dmub_srv *dmub_srv; - /** - * @dmub_notify: - * - * Notification from DMUB. - */ - struct dmub_notification *dmub_notify; - /** - * @dmub_callback: - * - * Callback functions to handle notification from DMUB. - */ - - dmub_notify_interrupt_callback_t dmub_callback[AMDGPU_DMUB_NOTIFICATION_MAX]; - - /** - * @dmub_thread_offload: - * - * Flag to indicate if callback is offload. - */ - - bool dmub_thread_offload[AMDGPU_DMUB_NOTIFICATION_MAX]; - /** * @dmub_fb_info: * @@ -510,12 +422,7 @@ struct amdgpu_display_manager { */ struct crc_rd_work *crc_rd_wrk; #endif - /** - * @hpd_rx_offload_wq: - * - * Work queue to offload works of hpd_rx_irq - */ - struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq; + /** * @mst_encoders: * @@ -532,7 +439,6 @@ struct amdgpu_display_manager { */ struct list_head da_list; struct completion dmub_aux_transfer_done; - struct workqueue_struct *delayed_hpd_wq; /** * @brightness: @@ -626,8 +532,6 @@ struct dm_crtc_state { bool cm_has_degamma; bool cm_is_degamma_srgb; - bool mpo_requested; - int update_type; int active_planes; @@ -638,8 +542,6 @@ struct dm_crtc_state { bool dsc_force_changed; bool vrr_supported; - - bool force_dpms_off; struct mod_freesync_config freesync_config; struct dc_info_packet vrr_infopacket; @@ -730,10 +632,6 @@ void amdgpu_dm_update_connector_after_detect( extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs; -int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, - struct dc_context *ctx, unsigned int link_index, - void *payload, void *operation_result); - -bool check_seamless_boot_capability(struct amdgpu_device *adev); - +int amdgpu_dm_process_dmub_aux_transfer_sync(struct dc_context *ctx, unsigned int linkIndex, + struct aux_payload *payload, enum aux_return_code_type *operation_result); #endif /* __AMDGPU_DM_H__ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index a71177305b..a022e5bb30 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -285,12 +285,8 @@ static int __set_input_tf(struct dc_transfer_func *func, } /** - * amdgpu_dm_verify_lut_sizes - * @crtc_state: the DRM CRTC state - * * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of * the expected size. - * * Returns 0 on success. */ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 26719efa53..e94ddd5e7b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -78,10 +78,12 @@ static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size, wr_buf_ptr = wr_buf; - /* r is bytes not be copied */ - if (copy_from_user(wr_buf_ptr, buf, wr_buf_size)) { - DRM_DEBUG_DRIVER("user data could not be read successfully\n"); - return -EFAULT; + r = copy_from_user(wr_buf_ptr, buf, wr_buf_size); + + /* r is bytes not be copied */ + if (r >= wr_buf_size) { + DRM_DEBUG_DRIVER("user data not be read\n"); + return -EINVAL; } /* check number of parameters. isspace could not differ space and \n */ @@ -292,9 +294,6 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, case LINK_RATE_RBR2: case LINK_RATE_HIGH2: case LINK_RATE_HIGH3: -#if defined(CONFIG_DRM_AMD_DC_DCN) - case LINK_RATE_UHBR10: -#endif break; default: valid_input = false; @@ -380,9 +379,9 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf, return -EINVAL; snprintf(rd_buf, rd_buf_size, " %d %d %d\n", - link->cur_lane_setting[0].VOLTAGE_SWING, - link->cur_lane_setting[0].PRE_EMPHASIS, - link->cur_lane_setting[0].POST_CURSOR2); + link->cur_lane_setting.VOLTAGE_SWING, + link->cur_lane_setting.PRE_EMPHASIS, + link->cur_lane_setting.POST_CURSOR2); while (size) { if (*pos >= rd_buf_size) @@ -734,7 +733,7 @@ static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __us } for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++) - link_training_settings.lane_settings[i] = link->cur_lane_setting[i]; + link_training_settings.lane_settings[i] = link->cur_lane_setting; dc_link_set_test_pattern( link, @@ -824,48 +823,6 @@ static int dmub_fw_state_show(struct seq_file *m, void *data) return seq_write(m, state_base, state_size); } -/* psr_capability_show() - show eDP panel PSR capability - * - * The read function: sink_psr_capability_show - * Shows if sink has PSR capability or not. - * If yes - the PSR version is appended - * - * cat /sys/kernel/debug/dri/0/eDP-X/psr_capability - * - * Expected output: - * "Sink support: no\n" - if panel doesn't support PSR - * "Sink support: yes [0x01]\n" - if panel supports PSR1 - * "Driver support: no\n" - if driver doesn't support PSR - * "Driver support: yes [0x01]\n" - if driver supports PSR1 - */ -static int psr_capability_show(struct seq_file *m, void *data) -{ - struct drm_connector *connector = m->private; - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); - struct dc_link *link = aconnector->dc_link; - - if (!link) - return -ENODEV; - - if (link->type == dc_connection_none) - return -ENODEV; - - if (!(link->connector_signal & SIGNAL_TYPE_EDP)) - return -ENODEV; - - seq_printf(m, "Sink support: %s", yesno(link->dpcd_caps.psr_caps.psr_version != 0)); - if (link->dpcd_caps.psr_caps.psr_version) - seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_caps.psr_version); - seq_puts(m, "\n"); - - seq_printf(m, "Driver support: %s", yesno(link->psr_settings.psr_feature_enabled)); - if (link->psr_settings.psr_version) - seq_printf(m, " [0x%02x]", link->psr_settings.psr_version); - seq_puts(m, "\n"); - - return 0; -} - /* * Returns the current and maximum output bpc for the connector. * Example usage: cat /sys/kernel/debug/dri/0/DP-1/output_bpc @@ -1285,7 +1242,7 @@ static ssize_t trigger_hotplug(struct file *f, const char __user *buf, dm_restore_drm_connector_state(dev, connector); drm_modeset_unlock_all(dev); - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } else if (param[0] == 0) { if (!aconnector->dc_link) goto unlock; @@ -1307,7 +1264,7 @@ static ssize_t trigger_hotplug(struct file *f, const char __user *buf, dm_restore_drm_connector_state(dev, connector); drm_modeset_unlock_all(dev); - drm_kms_helper_connector_hotplug_event(connector); + drm_kms_helper_hotplug_event(dev); } unlock: @@ -2509,7 +2466,6 @@ DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status); DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability); #endif DEFINE_SHOW_ATTRIBUTE(internal_display); -DEFINE_SHOW_ATTRIBUTE(psr_capability); static const struct file_operations dp_dsc_clock_en_debugfs_fops = { .owner = THIS_MODULE, @@ -2755,138 +2711,6 @@ static const struct { {"internal_display", &internal_display_fops} }; -/* - * Returns supported customized link rates by this eDP panel. - * Example usage: cat /sys/kernel/debug/dri/0/eDP-x/ilr_setting - */ -static int edp_ilr_show(struct seq_file *m, void *unused) -{ - struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private); - struct dc_link *link = aconnector->dc_link; - uint8_t supported_link_rates[16]; - uint32_t link_rate_in_khz; - uint32_t entry = 0; - uint8_t dpcd_rev; - - memset(supported_link_rates, 0, sizeof(supported_link_rates)); - dm_helpers_dp_read_dpcd(link->ctx, link, DP_SUPPORTED_LINK_RATES, - supported_link_rates, sizeof(supported_link_rates)); - - dpcd_rev = link->dpcd_caps.dpcd_rev.raw; - - if (dpcd_rev >= DP_DPCD_REV_13 && - (supported_link_rates[entry+1] != 0 || supported_link_rates[entry] != 0)) { - - for (entry = 0; entry < 16; entry += 2) { - link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 + - supported_link_rates[entry]) * 200; - seq_printf(m, "[%d] %d kHz\n", entry/2, link_rate_in_khz); - } - } else { - seq_printf(m, "ILR is not supported by this eDP panel.\n"); - } - - return 0; -} - -/* - * Set supported customized link rate to eDP panel. - * - * echo > ilr_setting - * - * for example, supported ILR : [0] 1620000 kHz [1] 2160000 kHz [2] 2430000 kHz ... - * echo 4 1 > /sys/kernel/debug/dri/0/eDP-x/ilr_setting - * to set 4 lanes and 2.16 GHz - */ -static ssize_t edp_ilr_write(struct file *f, const char __user *buf, - size_t size, loff_t *pos) -{ - struct amdgpu_dm_connector *connector = file_inode(f)->i_private; - struct dc_link *link = connector->dc_link; - struct amdgpu_device *adev = drm_to_adev(connector->base.dev); - struct dc *dc = (struct dc *)link->dc; - struct dc_link_settings prefer_link_settings; - char *wr_buf = NULL; - const uint32_t wr_buf_size = 40; - /* 0: lane_count; 1: link_rate */ - int max_param_num = 2; - uint8_t param_nums = 0; - long param[2]; - bool valid_input = true; - - if (size == 0) - return -EINVAL; - - wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); - if (!wr_buf) - return -ENOMEM; - - if (parse_write_buffer_into_params(wr_buf, wr_buf_size, - (long *)param, buf, - max_param_num, - ¶m_nums)) { - kfree(wr_buf); - return -EINVAL; - } - - if (param_nums <= 0) { - kfree(wr_buf); - return -EINVAL; - } - - switch (param[0]) { - case LANE_COUNT_ONE: - case LANE_COUNT_TWO: - case LANE_COUNT_FOUR: - break; - default: - valid_input = false; - break; - } - - if (param[1] >= link->dpcd_caps.edp_supported_link_rates_count) - valid_input = false; - - if (!valid_input) { - kfree(wr_buf); - DRM_DEBUG_DRIVER("Invalid Input value. No HW will be programmed\n"); - prefer_link_settings.use_link_rate_set = false; - dc_link_set_preferred_training_settings(dc, NULL, NULL, link, true); - return size; - } - - /* save user force lane_count, link_rate to preferred settings - * spread spectrum will not be changed - */ - prefer_link_settings.link_spread = link->cur_link_settings.link_spread; - prefer_link_settings.lane_count = param[0]; - prefer_link_settings.use_link_rate_set = true; - prefer_link_settings.link_rate_set = param[1]; - prefer_link_settings.link_rate = link->dpcd_caps.edp_supported_link_rates[param[1]]; - - mutex_lock(&adev->dm.dc_lock); - dc_link_set_preferred_training_settings(dc, &prefer_link_settings, - NULL, link, false); - mutex_unlock(&adev->dm.dc_lock); - - kfree(wr_buf); - return size; -} - -static int edp_ilr_open(struct inode *inode, struct file *file) -{ - return single_open(file, edp_ilr_show, inode->i_private); -} - -static const struct file_operations edp_ilr_debugfs_fops = { - .owner = THIS_MODULE, - .open = edp_ilr_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = edp_ilr_write -}; - void connector_debugfs_init(struct amdgpu_dm_connector *connector) { int i; @@ -2901,14 +2725,11 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) } } if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { - debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops); debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops); debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector, ¤t_backlight_fops); debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector, &target_backlight_fops); - debugfs_create_file("ilr_setting", 0644, dir, connector, - &edp_ilr_debugfs_fops); } for (i = 0; i < ARRAY_SIZE(connector_debugfs_entries); i++) { @@ -3371,32 +3192,6 @@ static int disable_hpd_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(disable_hpd_ops, disable_hpd_get, disable_hpd_set, "%llu\n"); -#if defined(CONFIG_DRM_AMD_DC_DCN) -/* - * Temporary w/a to force sst sequence in M42D DP2 mst receiver - * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_set_mst_en_for_sst - */ -static int dp_force_sst_set(void *data, u64 val) -{ - struct amdgpu_device *adev = data; - - adev->dm.dc->debug.set_mst_en_for_sst = val; - - return 0; -} - -static int dp_force_sst_get(void *data, u64 *val) -{ - struct amdgpu_device *adev = data; - - *val = adev->dm.dc->debug.set_mst_en_for_sst; - - return 0; -} -DEFINE_DEBUGFS_ATTRIBUTE(dp_set_mst_en_for_sst_ops, dp_force_sst_get, - dp_force_sst_set, "%llu\n"); -#endif - /* * Sets the DC visual confirm debug option from the given string. * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm @@ -3506,10 +3301,6 @@ void dtn_debugfs_init(struct amdgpu_device *adev) adev, &mst_topo_fops); debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev, &dtn_log_fops); -#if defined(CONFIG_DRM_AMD_DC_DCN) - debugfs_create_file("amdgpu_dm_dp_set_mst_en_for_sst", 0644, root, adev, - &dp_set_mst_en_for_sst_ops); -#endif debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev, &visual_confirm_fops); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 5bfdc66b58..c5f1dc3b59 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -448,8 +448,6 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) struct mod_hdcp_display *display = &hdcp_work[link_index].display; struct mod_hdcp_link *link = &hdcp_work[link_index].link; struct drm_connector_state *conn_state; - struct dc_sink *sink = NULL; - bool link_is_hdcp14 = false; if (config->dpms_off) { hdcp_remove_display(hdcp_work, link_index, aconnector); @@ -462,13 +460,8 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) display->index = aconnector->base.index; display->state = MOD_HDCP_DISPLAY_ACTIVE; - if (aconnector->dc_sink) - sink = aconnector->dc_sink; - else if (aconnector->dc_em_sink) - sink = aconnector->dc_em_sink; - - if (sink != NULL) - link->mode = mod_hdcp_signal_type_to_operation_mode(sink->sink_signal); + if (aconnector->dc_sink != NULL) + link->mode = mod_hdcp_signal_type_to_operation_mode(aconnector->dc_sink->sink_signal); display->controller = CONTROLLER_ID_D0 + config->otg_inst; display->dig_fe = config->dig_fe; @@ -477,9 +470,8 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) display->stream_enc_idx = config->stream_enc_idx; link->link_enc_idx = config->link_enc_idx; link->phy_idx = config->phy_idx; - if (sink) - link_is_hdcp14 = dc_link_is_hdcp14(aconnector->dc_link, sink->sink_signal); - link->hdcp_supported_informational = link_is_hdcp14; + link->hdcp_supported_informational = dc_link_is_hdcp14(aconnector->dc_link, + aconnector->dc_sink->sink_signal) ? 1 : 0; link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw; link->dp.assr_enabled = config->assr_enabled; link->dp.mst_enabled = config->mst_enabled; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 29f07c26d0..d793eec69d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -83,17 +83,16 @@ static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps) * void * */ enum dc_edid_status dm_helpers_parse_edid_caps( - struct dc_link *link, + struct dc_context *ctx, const struct dc_edid *edid, struct dc_edid_caps *edid_caps) { - struct amdgpu_dm_connector *aconnector = link->priv; - struct drm_connector *connector = &aconnector->base; struct edid *edid_buf = (struct edid *) edid->raw_edid; struct cea_sad *sads; int sad_count = -1; int sadb_count = -1; int i = 0; + int j = 0; uint8_t *sadb = NULL; enum dc_edid_status result = EDID_OK; @@ -112,11 +111,23 @@ enum dc_edid_status dm_helpers_parse_edid_caps( edid_caps->manufacture_week = edid_buf->mfg_week; edid_caps->manufacture_year = edid_buf->mfg_year; - drm_edid_get_monitor_name(edid_buf, - edid_caps->display_name, - AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS); + /* One of the four detailed_timings stores the monitor name. It's + * stored in an array of length 13. */ + for (i = 0; i < 4; i++) { + if (edid_buf->detailed_timings[i].data.other_data.type == 0xfc) { + while (j < 13 && edid_buf->detailed_timings[i].data.other_data.data.str.str[j]) { + if (edid_buf->detailed_timings[i].data.other_data.data.str.str[j] == '\n') + break; - edid_caps->edid_hdmi = connector->display_info.is_hdmi; + edid_caps->display_name[j] = + edid_buf->detailed_timings[i].data.other_data.data.str.str[j]; + j++; + } + } + } + + edid_caps->edid_hdmi = drm_detect_hdmi_monitor( + (struct edid *) edid->raw_edid); sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) @@ -208,7 +219,6 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( struct drm_dp_mst_topology_mgr *mst_mgr; struct drm_dp_mst_port *mst_port; bool ret; - u8 link_coding_cap = DP_8b_10b_ENCODING; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; /* Accessing the connector state is required for vcpi_slots allocation @@ -228,10 +238,6 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( mst_port = aconnector->port; -#if defined(CONFIG_DRM_AMD_DC_DCN) - link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(aconnector->dc_link); -#endif - if (enable) { ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, @@ -245,7 +251,7 @@ bool dm_helpers_dp_mst_write_payload_allocation_table( } /* It's OK for this to fail */ - drm_dp_update_payload_part1(mst_mgr, (link_coding_cap == DP_CAP_ANSI_128B132B) ? 0:1); + drm_dp_update_payload_part1(mst_mgr); /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or * AUX message. The sequence is slot 1-63 allocated sequence for each @@ -573,18 +579,9 @@ bool dm_helpers_dp_write_dsc_enable( ret = drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1); } - if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || stream->signal == SIGNAL_TYPE_EDP) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) { -#endif - ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); - DC_LOG_DC("Send DSC %s to SST RX\n", enable_dsc ? "enable" : "disable"); -#if defined(CONFIG_DRM_AMD_DC_DCN) - } else if (stream->sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER) { - ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); - DC_LOG_DC("Send DSC %s to DP-HDMI PCON\n", enable_dsc ? "enable" : "disable"); - } -#endif + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) { + ret = dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1); + DC_LOG_DC("Send DSC %s to sst display\n", enable_dsc ? "enable" : "disable"); } return (ret > 0); @@ -648,8 +645,14 @@ enum dc_edid_status dm_helpers_read_local_edid( /* We don't need the original edid anymore */ kfree(edid); - /* connector->display_info is parsed from EDID and saved - * into drm_connector->display_info + /* connector->display_info will be parsed from EDID and saved + * into drm_connector->display_info from edid by call stack + * below: + * drm_parse_ycbcr420_deep_color_info + * drm_parse_hdmi_forum_vsdb + * drm_parse_cea_ext + * drm_add_display_info + * drm_connector_update_edid_property * * drm_connector->display_info will be used by amdgpu_dm funcs, * like fill_stream_properties_from_drm_display_mode @@ -657,7 +660,7 @@ enum dc_edid_status dm_helpers_read_local_edid( amdgpu_dm_update_connector_after_detect(aconnector); edid_status = dm_helpers_parse_edid_caps( - link, + ctx, &sink->dc_edid, &sink->edid_caps); @@ -680,21 +683,8 @@ int dm_helper_dmub_aux_transfer_sync( struct aux_payload *payload, enum aux_return_code_type *operation_result) { - return amdgpu_dm_process_dmub_aux_transfer_sync(true, ctx, - link->link_index, (void *)payload, - (void *)operation_result); + return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload, operation_result); } - -int dm_helpers_dmub_set_config_sync(struct dc_context *ctx, - const struct dc_link *link, - struct set_config_cmd_payload *payload, - enum set_config_status *operation_result) -{ - return amdgpu_dm_process_dmub_aux_transfer_sync(false, ctx, - link->link_index, (void *)payload, - (void *)operation_result); -} - void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks) { /* TODO: something */ @@ -796,17 +786,3 @@ void dm_helpers_mst_enable_stream_features(const struct dc_stream_state *stream) &new_downspread.raw, sizeof(new_downspread)); } - -#if defined(CONFIG_DRM_AMD_DC_DCN) -void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz) -{ - // FPGA programming for this clock in diags framework that - // needs to go through dm layer, therefore leave dummy interace here -} - - -void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable) -{ - /* TODO: add peridic detection implementation */ -} -#endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index cc34a35d0b..74885ff77f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -66,8 +66,6 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0; payload.write = (msg->request & DP_AUX_I2C_READ) == 0; payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0; - payload.write_status_update = - (msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0; payload.defer_delay = 0; result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, @@ -546,18 +544,17 @@ static int kbps_to_peak_pbn(int kbps) static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params, struct dsc_mst_fairness_vars *vars, - int count, - int k) + int count) { int i; for (i = 0; i < count; i++) { memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg)); - if (vars[i + k].dsc_enabled && dc_dsc_compute_config( + if (vars[i].dsc_enabled && dc_dsc_compute_config( params[i].sink->ctx->dc->res_pool->dscs[0], ¶ms[i].sink->dsc_caps.dsc_dec_caps, params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, - params[i].sink->edid_caps.panel_patch.max_dsc_target_bpp_limit, + 0, 0, params[i].timing, ¶ms[i].timing->dsc_cfg)) { @@ -566,7 +563,7 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p if (params[i].bpp_overwrite) params[i].timing->dsc_cfg.bits_per_pixel = params[i].bpp_overwrite; else - params[i].timing->dsc_cfg.bits_per_pixel = vars[i + k].bpp_x16; + params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16; if (params[i].num_slices_h) params[i].timing->dsc_cfg.num_slices_h = params[i].num_slices_h; @@ -589,7 +586,7 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) param.sink->ctx->dc->res_pool->dscs[0], ¶m.sink->dsc_caps.dsc_dec_caps, param.sink->ctx->dc->debug.dsc_min_slice_height_override, - param.sink->edid_caps.panel_patch.max_dsc_target_bpp_limit, + 0, (int) kbps, param.timing, &dsc_config); return dsc_config.bits_per_pixel; @@ -599,8 +596,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, struct dc_link *dc_link, struct dsc_mst_fairness_params *params, struct dsc_mst_fairness_vars *vars, - int count, - int k) + int count) { int i; bool bpp_increased[MAX_PIPES]; @@ -615,9 +611,8 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, pbn_per_timeslot = dm_mst_get_pbn_divider(dc_link); for (i = 0; i < count; i++) { - if (vars[i + k].dsc_enabled) { - initial_slack[i] = - kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i + k].pbn; + if (vars[i].dsc_enabled) { + initial_slack[i] = kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i].pbn; bpp_increased[i] = false; remaining_to_increase += 1; } else { @@ -644,7 +639,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state, link_timeslots_used = 0; for (i = 0; i < count; i++) - link_timeslots_used += DIV_ROUND_UP(vars[i + k].pbn, pbn_per_timeslot); + link_timeslots_used += DIV_ROUND_UP(vars[i].pbn, pbn_per_timeslot); fair_pbn_alloc = (63 - link_timeslots_used) / remaining_to_increase * pbn_per_timeslot; @@ -697,8 +692,7 @@ static void try_disable_dsc(struct drm_atomic_state *state, struct dc_link *dc_link, struct dsc_mst_fairness_params *params, struct dsc_mst_fairness_vars *vars, - int count, - int k) + int count) { int i; bool tried[MAX_PIPES]; @@ -708,8 +702,8 @@ static void try_disable_dsc(struct drm_atomic_state *state, int remaining_to_try = 0; for (i = 0; i < count; i++) { - if (vars[i + k].dsc_enabled - && vars[i + k].bpp_x16 == params[i].bw_range.max_target_bpp_x16 + if (vars[i].dsc_enabled + && vars[i].bpp_x16 == params[i].bw_range.max_target_bpp_x16 && params[i].clock_force_enable == DSC_CLK_FORCE_DEFAULT) { kbps_increase[i] = params[i].bw_range.stream_kbps - params[i].bw_range.max_kbps; tried[i] = false; @@ -764,10 +758,9 @@ static void try_disable_dsc(struct drm_atomic_state *state, static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, struct dc_state *dc_state, struct dc_link *dc_link, - struct dsc_mst_fairness_vars *vars, - int *link_vars_start_index) + struct dsc_mst_fairness_vars *vars) { - int i, k; + int i; struct dc_stream_state *stream; struct dsc_mst_fairness_params params[MAX_PIPES]; struct amdgpu_dm_connector *aconnector; @@ -785,17 +778,11 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, if (stream->link != dc_link) continue; - aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; - if (!aconnector) - continue; - - if (!aconnector->port) - continue; - stream->timing.flags.DSC = 0; params[count].timing = &stream->timing; params[count].sink = stream->sink; + aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; params[count].aconnector = aconnector; params[count].port = aconnector->port; params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable; @@ -817,55 +804,44 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, count++; } - - if (count == 0) { - ASSERT(0); - return true; - } - - /* k is start index of vars for current phy link used by mst hub */ - k = *link_vars_start_index; - /* set vars start index for next mst hub phy link */ - *link_vars_start_index += count; - /* Try no compression */ for (i = 0; i < count; i++) { - vars[i + k].aconnector = params[i].aconnector; - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); - vars[i + k].dsc_enabled = false; - vars[i + k].bpp_x16 = 0; + vars[i].aconnector = params[i].aconnector; + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i].dsc_enabled = false; + vars[i].bpp_x16 = 0; if (drm_dp_atomic_find_vcpi_slots(state, params[i].port->mgr, params[i].port, - vars[i + k].pbn, + vars[i].pbn, dm_mst_get_pbn_divider(dc_link)) < 0) return false; } if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) { - set_dsc_configs_from_fairness_vars(params, vars, count, k); + set_dsc_configs_from_fairness_vars(params, vars, count); return true; } /* Try max compression */ for (i = 0; i < count; i++) { if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); - vars[i + k].dsc_enabled = true; - vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); + vars[i].dsc_enabled = true; + vars[i].bpp_x16 = params[i].bw_range.min_target_bpp_x16; if (drm_dp_atomic_find_vcpi_slots(state, params[i].port->mgr, params[i].port, - vars[i + k].pbn, + vars[i].pbn, dm_mst_get_pbn_divider(dc_link)) < 0) return false; } else { - vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); - vars[i + k].dsc_enabled = false; - vars[i + k].bpp_x16 = 0; + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i].dsc_enabled = false; + vars[i].bpp_x16 = 0; if (drm_dp_atomic_find_vcpi_slots(state, params[i].port->mgr, params[i].port, - vars[i + k].pbn, + vars[i].pbn, dm_mst_get_pbn_divider(dc_link)) < 0) return false; } @@ -874,76 +850,15 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, return false; /* Optimize degree of compression */ - increase_dsc_bpp(state, dc_link, params, vars, count, k); + increase_dsc_bpp(state, dc_link, params, vars, count); - try_disable_dsc(state, dc_link, params, vars, count, k); + try_disable_dsc(state, dc_link, params, vars, count); - set_dsc_configs_from_fairness_vars(params, vars, count, k); + set_dsc_configs_from_fairness_vars(params, vars, count); return true; } -static bool is_dsc_need_re_compute( - struct drm_atomic_state *state, - struct dc_state *dc_state, - struct dc_link *dc_link) -{ - int i; - bool is_dsc_need_re_compute = false; - - /* only check phy used by mst branch */ - if (dc_link->type != dc_connection_mst_branch) - return false; - - /* check if there is mode change in new request */ - for (i = 0; i < dc_state->stream_count; i++) { - struct amdgpu_dm_connector *aconnector; - struct dc_stream_state *stream; - struct drm_crtc_state *new_crtc_state; - struct drm_connector_state *new_conn_state; - - stream = dc_state->streams[i]; - - if (!stream) - continue; - - /* check if stream using the same link for mst */ - if (stream->link != dc_link) - continue; - - aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context; - if (!aconnector) - continue; - - new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base); - - if (!new_conn_state) - continue; - - if (IS_ERR(new_conn_state)) - continue; - - if (!new_conn_state->crtc) - continue; - - new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc); - - if (!new_crtc_state) - continue; - - if (IS_ERR(new_crtc_state)) - continue; - - if (new_crtc_state->enable && new_crtc_state->active) { - if (new_crtc_state->mode_changed || new_crtc_state->active_changed || - new_crtc_state->connectors_changed) - is_dsc_need_re_compute = true; - } - } - - return is_dsc_need_re_compute; -} - bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, struct dc_state *dc_state, struct dsc_mst_fairness_vars *vars) @@ -952,7 +867,6 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, struct dc_stream_state *stream; bool computed_streams[MAX_PIPES]; struct amdgpu_dm_connector *aconnector; - int link_vars_start_index = 0; for (i = 0; i < dc_state->stream_count; i++) computed_streams[i] = false; @@ -977,12 +891,8 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) return false; - if (!is_dsc_need_re_compute(state, dc_state, stream->link)) - continue; - mutex_lock(&aconnector->mst_mgr.lock); - if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, - vars, &link_vars_start_index)) { + if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars)) { mutex_unlock(&aconnector->mst_mgr.lock); return false; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index c510638b4f..70a554f1e7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -26,73 +26,6 @@ #include "amdgpu_dm_psr.h" #include "dc.h" #include "dm_helpers.h" -#include "amdgpu_dm.h" - -static bool link_get_psr_caps(struct dc_link *link) -{ - uint8_t psr_dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE]; - uint8_t edp_rev_dpcd_data; - - - - if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT, - psr_dpcd_data, sizeof(psr_dpcd_data))) - return false; - - if (!dm_helpers_dp_read_dpcd(NULL, link, DP_EDP_DPCD_REV, - &edp_rev_dpcd_data, sizeof(edp_rev_dpcd_data))) - return false; - - link->dpcd_caps.psr_caps.psr_version = psr_dpcd_data[0]; - link->dpcd_caps.psr_caps.edp_revision = edp_rev_dpcd_data; - -#ifdef CONFIG_DRM_AMD_DC_DCN - if (link->dpcd_caps.psr_caps.psr_version > 0x1) { - uint8_t alpm_dpcd_data; - uint8_t su_granularity_dpcd_data; - - if (!dm_helpers_dp_read_dpcd(NULL, link, DP_RECEIVER_ALPM_CAP, - &alpm_dpcd_data, sizeof(alpm_dpcd_data))) - return false; - - if (!dm_helpers_dp_read_dpcd(NULL, link, DP_PSR2_SU_Y_GRANULARITY, - &su_granularity_dpcd_data, sizeof(su_granularity_dpcd_data))) - return false; - - link->dpcd_caps.psr_caps.y_coordinate_required = psr_dpcd_data[1] & DP_PSR2_SU_Y_COORDINATE_REQUIRED; - link->dpcd_caps.psr_caps.su_granularity_required = psr_dpcd_data[1] & DP_PSR2_SU_GRANULARITY_REQUIRED; - - link->dpcd_caps.psr_caps.alpm_cap = alpm_dpcd_data & DP_ALPM_CAP; - link->dpcd_caps.psr_caps.standby_support = alpm_dpcd_data & (1 << 1); - - link->dpcd_caps.psr_caps.su_y_granularity = su_granularity_dpcd_data; - } -#endif - return true; -} - -#ifdef CONFIG_DRM_AMD_DC_DCN -static bool link_supports_psrsu(struct dc_link *link) -{ - struct dc *dc = link->ctx->dc; - - if (!dc->caps.dmcub_support) - return false; - - if (dc->ctx->dce_version < DCN_VERSION_3_1) - return false; - - if (!link->dpcd_caps.psr_caps.alpm_cap || - !link->dpcd_caps.psr_caps.y_coordinate_required) - return false; - - if (link->dpcd_caps.psr_caps.su_granularity_required && - !link->dpcd_caps.psr_caps.su_y_granularity) - return false; - - return true; -} -#endif /* * amdgpu_dm_set_psr_caps() - set link psr capabilities @@ -101,34 +34,26 @@ static bool link_supports_psrsu(struct dc_link *link) */ void amdgpu_dm_set_psr_caps(struct dc_link *link) { + uint8_t dpcd_data[EDP_PSR_RECEIVER_CAP_SIZE]; + if (!(link->connector_signal & SIGNAL_TYPE_EDP)) return; - if (link->type == dc_connection_none) return; + if (dm_helpers_dp_read_dpcd(NULL, link, DP_PSR_SUPPORT, + dpcd_data, sizeof(dpcd_data))) { + link->dpcd_caps.psr_caps.psr_version = dpcd_data[0]; - if (!link_get_psr_caps(link)) { - DRM_ERROR("amdgpu: Failed to read PSR Caps!\n"); - return; - } - - if (link->dpcd_caps.psr_caps.psr_version == 0) { - link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; - link->psr_settings.psr_feature_enabled = false; - - } else { -#ifdef CONFIG_DRM_AMD_DC_DCN - if (link_supports_psrsu(link)) - link->psr_settings.psr_version = DC_PSR_VERSION_SU_1; - else -#endif + if (dpcd_data[0] == 0) { + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + link->psr_settings.psr_feature_enabled = false; + } else { link->psr_settings.psr_version = DC_PSR_VERSION_1; + link->psr_settings.psr_feature_enabled = true; + } - link->psr_settings.psr_feature_enabled = true; + DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled); } - - DRM_INFO("PSR support:%d\n", link->psr_settings.psr_feature_enabled); - } /* @@ -182,8 +107,6 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream) */ // Init fail safe of 2 frames static unsigned int num_frames_static = 2; - unsigned int power_opt = 0; - bool psr_enable = true; DRM_DEBUG_DRIVER("Enabling psr...\n"); @@ -210,9 +133,7 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream) &stream, 1, ¶ms); - power_opt |= psr_power_opt_z10_static_screen; - - return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt); + return dc_link_set_psr_allow_active(link, true, false, false); } /* @@ -223,12 +144,10 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream) */ bool amdgpu_dm_psr_disable(struct dc_stream_state *stream) { - unsigned int power_opt = 0; - bool psr_enable = false; DRM_DEBUG_DRIVER("Disabling psr...\n"); - return dc_link_set_psr_allow_active(stream->link, &psr_enable, true, false, &power_opt); + return dc_link_set_psr_allow_active(stream->link, false, true, false); } /* diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c index ab0c6d1910..b1bf80da3a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c @@ -52,7 +52,7 @@ static DEFINE_PER_CPU(int, fpu_recursion_depth); * This function tells if the code is already under FPU protection or not. A * function that works as an API for a set of FPU operations can use this * function for checking if the caller invoked it after DC_FP_START(). For - * example, take a look at dcn20_fpu.c file. + * example, take a look at dcn2x.c file. */ inline void dc_assert_fp_enabled(void) { diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index b1f0d62602..943fcb1648 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -30,7 +30,6 @@ DC_LIBS += dcn20 DC_LIBS += dsc DC_LIBS += dcn10 dml DC_LIBS += dcn21 -DC_LIBS += dcn201 DC_LIBS += dcn30 DC_LIBS += dcn301 DC_LIBS += dcn302 @@ -59,7 +58,7 @@ include $(AMD_DC) DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \ dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \ -dc_link_enc_cfg.o dc_link_dpia.o dc_link_dpcd.o +dc_link_enc_cfg.o dc_link_dpcd.o ifdef CONFIG_DRM_AMD_DC_DCN DISPLAY_CORE += dc_vm_helper.o diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 1e385d55e7..6dbde74c1e 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -99,10 +99,6 @@ static enum bp_result get_firmware_info_v3_2( struct bios_parser *bp, struct dc_firmware_info *info); -static enum bp_result get_firmware_info_v3_4( - struct bios_parser *bp, - struct dc_firmware_info *info); - static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, struct atom_display_object_path_v2 *object); @@ -1430,10 +1426,8 @@ static enum bp_result bios_parser_get_firmware_info( break; case 2: case 3: - result = get_firmware_info_v3_2(bp, info); - break; case 4: - result = get_firmware_info_v3_4(bp, info); + result = get_firmware_info_v3_2(bp, info); break; default: break; @@ -1581,88 +1575,6 @@ static enum bp_result get_firmware_info_v3_2( return BP_RESULT_OK; } -static enum bp_result get_firmware_info_v3_4( - struct bios_parser *bp, - struct dc_firmware_info *info) -{ - struct atom_firmware_info_v3_4 *firmware_info; - struct atom_common_table_header *header; - struct atom_data_revision revision; - struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL; - struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL; - if (!info) - return BP_RESULT_BADINPUT; - - firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4, - DATA_TABLES(firmwareinfo)); - - if (!firmware_info) - return BP_RESULT_BADBIOSTABLE; - - memset(info, 0, sizeof(*info)); - - header = GET_IMAGE(struct atom_common_table_header, - DATA_TABLES(dce_info)); - - get_atom_data_table_revision(header, &revision); - - switch (revision.major) { - case 4: - switch (revision.minor) { - case 4: - dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, - DATA_TABLES(dce_info)); - - if (!dce_info_v4_4) - return BP_RESULT_BADBIOSTABLE; - - /* 100MHz expected */ - info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10; - info->dp_phy_ref_clk = dce_info_v4_4->dpphy_refclk_10khz * 10; - /* 50MHz expected */ - info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10; - - /* Get SMU Display PLL VCO Frequency in KHz*/ - info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10; - break; - - default: - /* should not come here, keep as backup, as was before */ - dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1, - DATA_TABLES(dce_info)); - - if (!dce_info_v4_1) - return BP_RESULT_BADBIOSTABLE; - - info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10; - info->dp_phy_ref_clk = dce_info_v4_1->dpphy_refclk_10khz * 10; - info->i2c_engine_ref_clk = dce_info_v4_1->i2c_engine_refclk_10khz * 10; - break; - } - break; - - default: - ASSERT(0); - break; - } - - header = GET_IMAGE(struct atom_common_table_header, - DATA_TABLES(smu_info)); - get_atom_data_table_revision(header, &revision); - - // We need to convert from 10KHz units into KHz units. - info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; - - if (firmware_info->board_i2c_feature_id == 0x2) { - info->oem_i2c_present = true; - info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; - } else { - info->oem_i2c_present = false; - } - - return BP_RESULT_OK; -} - static enum bp_result bios_parser_get_encoder_cap_info( struct dc_bios *dcb, struct graphics_object_id object_id, @@ -1692,16 +1604,6 @@ static enum bp_result bios_parser_get_encoder_cap_info( ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; info->HDMI_6GB_EN = (record->encodercaps & ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) - info->IS_DP2_CAPABLE = (record->encodercaps & - ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0; - info->DP_UHBR10_EN = (record->encodercaps & - ATOM_ENCODER_CAP_RECORD_UHBR10_EN) ? 1 : 0; - info->DP_UHBR13_5_EN = (record->encodercaps & - ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0; - info->DP_UHBR20_EN = (record->encodercaps & - ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0; -#endif info->DP_IS_USB_C = (record->encodercaps & ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0; @@ -2321,8 +2223,6 @@ static enum bp_result get_integrated_info_v2_2( info->ext_disp_conn_info.checksum = info_v2_2->extdispconninfo.checksum; - info->ext_disp_conn_info.fixdpvoltageswing = - info_v2_2->extdispconninfo.fixdpvoltageswing; info->edp1_info.edp_backlight_pwm_hz = le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz); @@ -2995,7 +2895,7 @@ static bool bios_parser2_construct( &bp->object_info_tbl.revision); if (bp->object_info_tbl.revision.major == 1 - && bp->object_info_tbl.revision.minor == 4) { + && bp->object_info_tbl.revision.minor >= 4) { struct display_object_info_table_v1_4 *tbl_v1_4; tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4, @@ -3004,10 +2904,8 @@ static bool bios_parser2_construct( return false; bp->object_info_tbl.v1_4 = tbl_v1_4; - } else { - ASSERT(0); + } else return false; - } dal_firmware_parser_init_cmd_tbl(bp); dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c index 9afa5eb2e6..f1f672a997 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c @@ -44,7 +44,9 @@ bp->base.ctx->logger #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\ - (offsetof(struct atom_master_list_of_##MasterOrData##_functions_v2_1, FieldName) / sizeof(uint16_t)) + (((char *)(&((\ + struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\ + ->FieldName)-(char *)0)/sizeof(uint16_t)) #define EXEC_BIOS_CMD_TABLE(fname, params)\ (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \ @@ -338,13 +340,6 @@ static enum bp_result transmitter_control_v1_7( const struct command_table_helper *cmd = bp->cmd_helper; struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_0; - - if (dc_is_dp_signal(cntl->signal)) - hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_DP_0; -#endif - dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter); dig_v1_7.action = (uint8_t)cntl->action; @@ -358,9 +353,6 @@ static enum bp_result transmitter_control_v1_7( dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id; -#if defined(CONFIG_DRM_AMD_DC_DCN) - dig_v1_7.HPO_instance = hpo_instance; -#endif dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10; if (cntl->action == TRANSMITTER_CONTROL_ENABLE || diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c index eedc553f34..cb3fd44cb1 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c @@ -70,7 +70,6 @@ bool dal_bios_parser_init_cmd_tbl_helper2( case DCN_VERSION_1_01: case DCN_VERSION_2_0: case DCN_VERSION_2_1: - case DCN_VERSION_2_01: case DCN_VERSION_3_0: case DCN_VERSION_3_01: case DCN_VERSION_3_02: diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index e447c74be7..0e18df1283 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -459,9 +459,9 @@ static void dcn_bw_calc_rq_dlg_ttu( struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &pipe->dlg_regs; struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &pipe->ttu_regs; struct _vcs_dpi_display_rq_regs_st *rq_regs = &pipe->rq_regs; - struct _vcs_dpi_display_rq_params_st *rq_param = &pipe->dml_rq_param; - struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param = &pipe->dml_dlg_sys_param; - struct _vcs_dpi_display_e2e_pipe_params_st *input = &pipe->dml_input; + struct _vcs_dpi_display_rq_params_st rq_param = {0}; + struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0}; + struct _vcs_dpi_display_e2e_pipe_params_st input = { { { 0 } } }; float total_active_bw = 0; float total_prefetch_bw = 0; int total_flip_bytes = 0; @@ -470,47 +470,45 @@ static void dcn_bw_calc_rq_dlg_ttu( memset(dlg_regs, 0, sizeof(*dlg_regs)); memset(ttu_regs, 0, sizeof(*ttu_regs)); memset(rq_regs, 0, sizeof(*rq_regs)); - memset(rq_param, 0, sizeof(*rq_param)); - memset(dlg_sys_param, 0, sizeof(*dlg_sys_param)); - memset(input, 0, sizeof(*input)); for (i = 0; i < number_of_planes; i++) { total_active_bw += v->read_bandwidth[i]; total_prefetch_bw += v->prefetch_bandwidth[i]; total_flip_bytes += v->total_immediate_flip_bytes[i]; } - dlg_sys_param->total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw); - if (dlg_sys_param->total_flip_bw < 0.0) - dlg_sys_param->total_flip_bw = 0; + dlg_sys_param.total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw); + if (dlg_sys_param.total_flip_bw < 0.0) + dlg_sys_param.total_flip_bw = 0; - dlg_sys_param->t_mclk_wm_us = v->dram_clock_change_watermark; - dlg_sys_param->t_sr_wm_us = v->stutter_enter_plus_exit_watermark; - dlg_sys_param->t_urg_wm_us = v->urgent_watermark; - dlg_sys_param->t_extra_us = v->urgent_extra_latency; - dlg_sys_param->deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep; - dlg_sys_param->total_flip_bytes = total_flip_bytes; + dlg_sys_param.t_mclk_wm_us = v->dram_clock_change_watermark; + dlg_sys_param.t_sr_wm_us = v->stutter_enter_plus_exit_watermark; + dlg_sys_param.t_urg_wm_us = v->urgent_watermark; + dlg_sys_param.t_extra_us = v->urgent_extra_latency; + dlg_sys_param.deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep; + dlg_sys_param.total_flip_bytes = total_flip_bytes; - pipe_ctx_to_e2e_pipe_params(pipe, &input->pipe); - input->clks_cfg.dcfclk_mhz = v->dcfclk; - input->clks_cfg.dispclk_mhz = v->dispclk; - input->clks_cfg.dppclk_mhz = v->dppclk; - input->clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; - input->clks_cfg.socclk_mhz = v->socclk; - input->clks_cfg.voltage = v->voltage_level; + pipe_ctx_to_e2e_pipe_params(pipe, &input.pipe); + input.clks_cfg.dcfclk_mhz = v->dcfclk; + input.clks_cfg.dispclk_mhz = v->dispclk; + input.clks_cfg.dppclk_mhz = v->dppclk; + input.clks_cfg.refclk_mhz = dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000.0; + input.clks_cfg.socclk_mhz = v->socclk; + input.clks_cfg.voltage = v->voltage_level; // dc->dml.logger = pool->base.logger; - input->dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444; - input->dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp; + input.dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444; + input.dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp; //input[in_idx].dout.output_standard; /*todo: soc->sr_enter_plus_exit_time??*/ + dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep; - dml1_rq_dlg_get_rq_params(dml, rq_param, &input->pipe.src); + dml1_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src); dml1_extract_rq_regs(dml, rq_regs, rq_param); dml1_rq_dlg_get_dlg_params( dml, dlg_regs, ttu_regs, - &rq_param->dlg, + rq_param.dlg, dlg_sys_param, input, true, @@ -738,9 +736,7 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v, hack_force_pipe_split(v, context->streams[0]->timing.pix_clk_100hz); } -static unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, - uint32_t hw_internal_rev, - uint32_t pci_revision_id) +unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, uint32_t hw_internal_rev, uint32_t pci_revision_id) { /* for low power RV2 variants, the highest voltage level we want is 0 */ if ((chip_family == FAMILY_RV) && @@ -764,7 +760,7 @@ static unsigned int get_highest_allowed_voltage_level(uint32_t chip_family, return 4; } -bool dcn10_validate_bandwidth( +bool dcn_validate_bandwidth( struct dc *dc, struct dc_state *context, bool fast_validate) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile index 6bd73e49a6..7fa0b007a7 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile @@ -93,15 +93,6 @@ AMD_DAL_CLK_MGR_DCN20 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn20/,$(CLK_MGR_DC AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN20) -############################################################################### -# DCN201 -############################################################################### -CLK_MGR_DCN201 = dcn201_clk_mgr.o - -AMD_DAL_CLK_MGR_DCN201 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn201/,$(CLK_MGR_DCN201)) - -AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN201) - ############################################################################### # DCN21 ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 9200c8ce02..6420527fe4 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -39,7 +39,6 @@ #include "dcn10/rv2_clk_mgr.h" #include "dcn20/dcn20_clk_mgr.h" #include "dcn21/rn_clk_mgr.h" -#include "dcn201/dcn201_clk_mgr.h" #include "dcn30/dcn30_clk_mgr.h" #include "dcn301/vg_clk_mgr.h" #include "dcn31/dcn31_clk_mgr.h" @@ -100,13 +99,11 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m if (edp_num) { for (panel_inst = 0; panel_inst < edp_num; panel_inst++) { - bool allow_active = false; - edp_link = edp_links[panel_inst]; if (!edp_link->psr_settings.psr_feature_enabled) continue; clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active; - dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL); + dc_link_set_psr_allow_active(edp_link, false, false, false); } } @@ -126,7 +123,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr) if (!edp_link->psr_settings.psr_feature_enabled) continue; dc_link_set_psr_allow_active(edp_link, - &clk_mgr->psr_allow_active_cache, false, false, NULL); + clk_mgr->psr_allow_active_cache, false, false); } } @@ -259,10 +256,6 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); return &clk_mgr->base; } - if (asic_id.chip_id == DEVICE_ID_NV_13FE) { - dcn201_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); - return &clk_mgr->base; - } dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); return &clk_mgr->base; } @@ -285,8 +278,13 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p BREAK_TO_DEBUGGER(); return NULL; } - - dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); + if (ASICREV_IS_YELLOW_CARP(asic_id.hw_internal_rev)) { + /* TODO: to add DCN31 clk_mgr support, once CLK IP header files are available, + * for now use DCN3.0 clk mgr. + */ + dcn31_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); + return &clk_mgr->base.base; + } return &clk_mgr->base.base; } #endif @@ -322,6 +320,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) break; case FAMILY_YELLOW_CARP: + if (ASICREV_IS_YELLOW_CARP(clk_mgr_base->ctx->asic_id.hw_internal_rev)) dcn31_clk_mgr_destroy(clk_mgr); break; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c index 60761ff3cb..76ec8ec92e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c @@ -34,7 +34,7 @@ #include "rv1_clk_mgr_vbios_smu.h" #include "rv1_clk_mgr_clk.h" -static void rv1_init_clocks(struct clk_mgr *clk_mgr) +void rv1_init_clocks(struct clk_mgr *clk_mgr) { memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c index 06bab24d8e..fe18bb9e19 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr_vbios_smu.c @@ -28,8 +28,6 @@ #include "reg_helper.h" #include -#include "rv1_clk_mgr_vbios_smu.h" - #define MAX_INSTANCE 5 #define MAX_SEGMENT 5 diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c index cac80ba690..0d01aa9f15 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -38,7 +38,6 @@ #include "clk/clk_11_0_0_offset.h" #include "clk/clk_11_0_0_sh_mask.h" - #undef FN #define FN(reg_name, field_name) \ clk_mgr->clk_mgr_shift->field_name, clk_mgr->clk_mgr_mask->field_name @@ -400,7 +399,7 @@ void dcn2_init_clocks(struct clk_mgr *clk_mgr) clk_mgr->clks.prev_p_state_change_support = true; } -static void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base) +void dcn2_enable_pme_wa(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); struct pp_smu_funcs_nv *pp_smu = NULL; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index f4dee0e48a..6185f9475f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -55,7 +55,9 @@ /* TODO: evaluate how to lower or disable all dcn clocks in screen off case */ -static int rn_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context) +int rn_get_active_display_cnt_wa( + struct dc *dc, + struct dc_state *context) { int i, display_count; bool tmds_present = false; @@ -64,9 +66,11 @@ static int rn_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context) for (i = 0; i < context->stream_count; i++) { const struct dc_stream_state *stream = context->streams[i]; + /* Extend the WA to DP for Linux*/ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || - stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) + stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK || + stream->signal == SIGNAL_TYPE_DISPLAY_PORT) tmds_present = true; } @@ -74,8 +78,7 @@ static int rn_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context) const struct dc_link *link = dc->links[i]; /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ - if (link->link_enc->funcs->is_dig_enabled && - link->link_enc->funcs->is_dig_enabled(link->link_enc)) + if (link->link_enc->funcs->is_dig_enabled(link->link_enc)) display_count++; } @@ -86,7 +89,7 @@ static int rn_get_active_display_cnt_wa(struct dc *dc, struct dc_state *context) return display_count; } -static void rn_set_low_power_state(struct clk_mgr *clk_mgr_base) +void rn_set_low_power_state(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); @@ -120,7 +123,7 @@ static void rn_update_clocks_update_dpp_dto(struct clk_mgr_internal *clk_mgr, } -static void rn_update_clocks(struct clk_mgr *clk_mgr_base, +void rn_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) { @@ -146,7 +149,6 @@ static void rn_update_clocks(struct clk_mgr *clk_mgr_base, if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { display_count = rn_get_active_display_cnt_wa(dc, context); - /* if we can go lower, go lower */ if (display_count == 0) { rn_vbios_smu_set_dcn_low_power_state(clk_mgr, DCN_PWR_STATE_LOW_POWER); @@ -427,14 +429,25 @@ static void rn_dump_clk_registers(struct clk_state_registers_and_bypass *regs_an } } -static void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) +/* This function produce translated logical clk state values*/ +void rn_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) +{ + struct clk_state_registers_and_bypass sb = { 0 }; + struct clk_log_info log_info = { 0 }; + + rn_dump_clk_registers(&sb, clk_mgr_base, &log_info); + + s->dprefclk_khz = sb.dprefclk * 1000; +} + +void rn_enable_pme_wa(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); rn_vbios_smu_enable_pme_wa(clk_mgr); } -static void rn_init_clocks(struct clk_mgr *clk_mgr) +void rn_init_clocks(struct clk_mgr *clk_mgr) { memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); // Assumption is that boot state always supports pstate diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c index 8161a6ae41..9f7eed6688 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c @@ -33,8 +33,6 @@ #include "mp/mp_12_0_0_offset.h" #include "mp/mp_12_0_0_sh_mask.h" -#include "rn_clk_mgr_vbios_smu.h" - #define REG(reg_name) \ (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) @@ -88,9 +86,7 @@ static uint32_t rn_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, unsig } -static int rn_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, - unsigned int msg_id, - unsigned int param) +int rn_vbios_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, unsigned int msg_id, unsigned int param) { uint32_t result; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index 10c7be40df..5c5cbeb59c 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -252,7 +252,6 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, bool update_dispclk = false; bool enter_display_off = false; bool dpp_clock_lowered = false; - bool update_pstate_unsupported_clk = false; struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu; bool force_reset = false; bool update_uclk = false; @@ -300,28 +299,13 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base, clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support; total_plane_count = clk_mgr_helper_get_active_plane_cnt(dc, context); p_state_change_support = new_clocks->p_state_change_support || (total_plane_count == 0); - - // invalidate the current P-State forced min in certain dc_mode_softmax situations - if (dc->clk_mgr->dc_mode_softmax_enabled && safe_to_lower && !p_state_change_support) { - if ((new_clocks->dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) != - (clk_mgr_base->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)) - update_pstate_unsupported_clk = true; - } - - if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support) || - update_pstate_unsupported_clk) { + if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) { clk_mgr_base->clks.p_state_change_support = p_state_change_support; /* to disable P-State switching, set UCLK min = max */ - if (!clk_mgr_base->clks.p_state_change_support) { - if (dc->clk_mgr->dc_mode_softmax_enabled && - new_clocks->dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) - dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, - dc->clk_mgr->bw_params->dc_mode_softmax_memclk); - else - dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, + if (!clk_mgr_base->clks.p_state_change_support) + dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz); - } } /* Always update saved value, even if new value not set due to P-State switching unsupported */ @@ -437,24 +421,6 @@ static void dcn3_set_hard_max_memclk(struct clk_mgr *clk_mgr_base) clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz); } -static void dcn3_set_max_memclk(struct clk_mgr *clk_mgr_base, unsigned int memclk_mhz) -{ - struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); - - if (!clk_mgr->smu_present) - return; - - dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, memclk_mhz); -} -static void dcn3_set_min_memclk(struct clk_mgr *clk_mgr_base, unsigned int memclk_mhz) -{ - struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); - - if (!clk_mgr->smu_present) - return; - dcn30_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, memclk_mhz); -} - /* Get current memclk states, update bounding box */ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) { @@ -470,8 +436,6 @@ static void dcn3_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) &num_levels); clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1; - clk_mgr_base->bw_params->dc_mode_softmax_memclk = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_UCLK); - /* Refresh bounding box */ DC_FP_START(); clk_mgr_base->ctx->dc->res_pool->funcs->update_bw_bounding_box( @@ -543,8 +507,6 @@ static struct clk_mgr_funcs dcn3_funcs = { .notify_wm_ranges = dcn3_notify_wm_ranges, .set_hard_min_memclk = dcn3_set_hard_min_memclk, .set_hard_max_memclk = dcn3_set_hard_max_memclk, - .set_max_memclk = dcn3_set_max_memclk, - .set_min_memclk = dcn3_set_min_memclk, .get_memclk_states_from_smu = dcn3_get_memclk_states_from_smu, .are_clock_states_equal = dcn3_are_clock_states_equal, .enable_pme_wa = dcn3_enable_pme_wa, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c index d9920d9183..6ea6426158 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/dcn301_smu.c @@ -88,9 +88,9 @@ static uint32_t dcn301_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, u return res_val; } -static int dcn301_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, - unsigned int msg_id, - unsigned int param) +int dcn301_smu_send_msg_with_param( + struct clk_mgr_internal *clk_mgr, + unsigned int msg_id, unsigned int param) { uint32_t result; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index bc4ddc36fe..329ce4e84b 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -89,9 +89,9 @@ static int vg_get_active_display_cnt_wa( return display_count; } -static void vg_update_clocks(struct clk_mgr *clk_mgr_base, - struct dc_state *context, - bool safe_to_lower) +void vg_update_clocks(struct clk_mgr *clk_mgr_base, + struct dc_state *context, + bool safe_to_lower) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; @@ -367,6 +367,18 @@ static void vg_dump_clk_registers(struct clk_state_registers_and_bypass *regs_an } } +/* This function produce translated logical clk state values*/ +void vg_get_clk_states(struct clk_mgr *clk_mgr_base, struct clk_states *s) +{ + + struct clk_state_registers_and_bypass sb = { 0 }; + struct clk_log_info log_info = { 0 }; + + vg_dump_clk_registers(&sb, clk_mgr_base, &log_info); + + s->dprefclk_khz = sb.dprefclk * 1000; +} + static void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) { struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); @@ -374,7 +386,7 @@ static void vg_enable_pme_wa(struct clk_mgr *clk_mgr_base) dcn301_smu_enable_pme_wa(clk_mgr); } -static void vg_init_clocks(struct clk_mgr *clk_mgr) +void vg_init_clocks(struct clk_mgr *clk_mgr) { memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); // Assumption is that boot state always supports pstate @@ -741,7 +753,7 @@ void vg_clk_mgr_construct( sizeof(struct watermarks), &clk_mgr->smu_wm_set.mc_address.quad_part); - if (!clk_mgr->smu_wm_set.wm_set) { + if (clk_mgr->smu_wm_set.wm_set == 0) { clk_mgr->smu_wm_set.wm_set = &dummy_wms; clk_mgr->smu_wm_set.mc_address.quad_part = 0; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 9d17c5a5ae..8f6e6496ea 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -66,7 +66,7 @@ #define TO_CLK_MGR_DCN31(clk_mgr)\ container_of(clk_mgr, struct clk_mgr_dcn31, base) -static int dcn31_get_active_display_cnt_wa( +int dcn31_get_active_display_cnt_wa( struct dc *dc, struct dc_state *context) { @@ -87,7 +87,7 @@ static int dcn31_get_active_display_cnt_wa( const struct dc_link *link = dc->links[i]; /* abusing the fact that the dig and phy are coupled to see if the phy is enabled */ - if (link->link_enc && link->link_enc->funcs->is_dig_enabled && + if (link->link_enc->funcs->is_dig_enabled && link->link_enc->funcs->is_dig_enabled(link->link_enc)) display_count++; } @@ -118,7 +118,7 @@ static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) } } -void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, +static void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower) { @@ -142,7 +142,6 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_ALLOW && new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { dcn31_smu_set_Z9_support(clk_mgr, true); - dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, true); clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; } @@ -168,7 +167,6 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, if (new_clocks->zstate_support == DCN_ZSTATE_SUPPORT_DISALLOW && new_clocks->zstate_support != clk_mgr_base->clks.zstate_support) { dcn31_smu_set_Z9_support(clk_mgr, false); - dm_helpers_enable_periodic_detection(clk_mgr_base->ctx, false); clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; } @@ -220,17 +218,14 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, update_dispclk = true; } + /* TODO: add back DTO programming when DPPCLK restore is fixed in FSDL*/ if (dpp_clock_lowered) { // increase per DPP DTO before lowering global dppclk - dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); dcn31_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); } else { // increase global DPPCLK before lowering per DPP DTO if (update_dppclk || update_dispclk) dcn31_smu_set_dppclk(clk_mgr, clk_mgr_base->clks.dppclk_khz); - // always update dtos unless clock is lowered and not safe to lower - if (new_clocks->dppclk_khz >= dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz) - dcn20_update_clocks_update_dpp_dto(clk_mgr, context, safe_to_lower); } // notify DMCUB of latest clocks @@ -285,7 +280,7 @@ static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base) dcn31_smu_enable_pme_wa(clk_mgr); } -void dcn31_init_clocks(struct clk_mgr *clk_mgr) +static void dcn31_init_clocks(struct clk_mgr *clk_mgr) { memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); // Assumption is that boot state always supports pstate @@ -295,7 +290,7 @@ void dcn31_init_clocks(struct clk_mgr *clk_mgr) clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; } -bool dcn31_are_clock_states_equal(struct dc_clocks *a, +static bool dcn31_are_clock_states_equal(struct dc_clocks *a, struct dc_clocks *b) { if (a->dispclk_khz != b->dispclk_khz) @@ -541,9 +536,10 @@ static unsigned int find_clk_for_voltage( return clock; } -static void dcn31_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk_mgr, - struct integrated_info *bios_info, - const DpmClocks_t *clock_table) +void dcn31_clk_mgr_helper_populate_bw_params( + struct clk_mgr_internal *clk_mgr, + struct integrated_info *bios_info, + const DpmClocks_t *clock_table) { int i, j; struct clk_bw_params *bw_params = clk_mgr->base.bw_params; @@ -652,7 +648,7 @@ void dcn31_clk_mgr_construct( sizeof(struct dcn31_watermarks), &clk_mgr->smu_wm_set.mc_address.quad_part); - if (!clk_mgr->smu_wm_set.wm_set) { + if (clk_mgr->smu_wm_set.wm_set == 0) { clk_mgr->smu_wm_set.wm_set = &dummy_wms; clk_mgr->smu_wm_set.mc_address.quad_part = 0; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h index 961b10a494..f8f1005355 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h @@ -39,13 +39,6 @@ struct clk_mgr_dcn31 { struct dcn31_smu_watermark_set smu_wm_set; }; -bool dcn31_are_clock_states_equal(struct dc_clocks *a, - struct dc_clocks *b); -void dcn31_init_clocks(struct clk_mgr *clk_mgr); -void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, - struct dc_state *context, - bool safe_to_lower); - void dcn31_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_dcn31 *clk_mgr, struct pp_smu_funcs *pp_smu, diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c index de3f4643ee..21d2cbc3cb 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c @@ -95,9 +95,9 @@ static uint32_t dcn31_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, un return res_val; } -static int dcn31_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, - unsigned int msg_id, - unsigned int param) +int dcn31_smu_send_msg_with_param( + struct clk_mgr_internal *clk_mgr, + unsigned int msg_id, unsigned int param) { uint32_t result; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ba1aa994db..b37c4d2e7a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -221,33 +221,14 @@ static bool create_links( link = link_create(&link_init_params); if (link) { - dc->links[dc->link_count] = link; - link->dc = dc; - ++dc->link_count; + dc->links[dc->link_count] = link; + link->dc = dc; + ++dc->link_count; } } DC_LOG_DC("BIOS object table - end"); - /* Create a link for each usb4 dpia port */ - for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) { - struct link_init_data link_init_params = {0}; - struct dc_link *link; - - link_init_params.ctx = dc->ctx; - link_init_params.connector_index = i; - link_init_params.link_index = dc->link_count; - link_init_params.dc = dc; - link_init_params.is_dpia_link = true; - - link = link_create(&link_init_params); - if (link) { - dc->links[dc->link_count] = link; - link->dc = dc; - ++dc->link_count; - } - } - for (i = 0; i < num_virtual_links; i++) { struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); struct encoder_init_data enc_init = {0}; @@ -295,75 +276,6 @@ static bool create_links( return false; } -/* Create additional DIG link encoder objects if fewer than the platform - * supports were created during link construction. This can happen if the - * number of physical connectors is less than the number of DIGs. - */ -static bool create_link_encoders(struct dc *dc) -{ - bool res = true; - unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia; - unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc; - int i; - - /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG - * link encoders and physical display endpoints and does not require - * additional link encoder objects. - */ - if (num_usb4_dpia == 0) - return res; - - /* Create as many link encoder objects as the platform supports. DPIA - * endpoints can be programmably mapped to any DIG. - */ - if (num_dig_link_enc > dc->res_pool->dig_link_enc_count) { - for (i = 0; i < num_dig_link_enc; i++) { - struct link_encoder *link_enc = dc->res_pool->link_encoders[i]; - - if (!link_enc && dc->res_pool->funcs->link_enc_create_minimal) { - link_enc = dc->res_pool->funcs->link_enc_create_minimal(dc->ctx, - (enum engine_id)(ENGINE_ID_DIGA + i)); - if (link_enc) { - dc->res_pool->link_encoders[i] = link_enc; - dc->res_pool->dig_link_enc_count++; - } else { - res = false; - } - } - } - } - - return res; -} - -/* Destroy any additional DIG link encoder objects created by - * create_link_encoders(). - * NB: Must only be called after destroy_links(). - */ -static void destroy_link_encoders(struct dc *dc) -{ - unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia; - unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc; - int i; - - /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG - * link encoders and physical display endpoints and does not require - * additional link encoder objects. - */ - if (num_usb4_dpia == 0) - return; - - for (i = 0; i < num_dig_link_enc; i++) { - struct link_encoder *link_enc = dc->res_pool->link_encoders[i]; - - if (link_enc) { - link_enc->funcs->destroy(&link_enc); - dc->res_pool->link_encoders[i] = NULL; - dc->res_pool->dig_link_enc_count--; - } - } -} - static struct dc_perf_trace *dc_perf_trace_create(void) { return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL); @@ -790,10 +702,6 @@ void dc_stream_set_static_screen_params(struct dc *dc, static void dc_destruct(struct dc *dc) { - // reset link encoder assignment table on destruct - if (dc->res_pool && dc->res_pool->funcs->link_encs_assign) - link_enc_cfg_init(dc, dc->current_state); - if (dc->current_state) { dc_release_state(dc->current_state); dc->current_state = NULL; @@ -801,8 +709,6 @@ static void dc_destruct(struct dc *dc) destroy_links(dc); - destroy_link_encoders(dc); - if (dc->clk_mgr) { dc_destroy_clk_mgr(dc->clk_mgr); dc->clk_mgr = NULL; @@ -1005,16 +911,13 @@ static bool dc_construct(struct dc *dc, goto fail; } + dc_resource_state_construct(dc, dc->current_state); + if (!create_links(dc, init_params->num_virtual_links)) goto fail; - /* Create additional DIG link encoder objects if fewer than the platform - * supports were created during link construction. - */ - if (!create_link_encoders(dc)) - goto fail; - - dc_resource_state_construct(dc, dc->current_state); + /* Initialise DIG link encoder resource tracking variables. */ + link_enc_cfg_init(dc, dc->current_state); return true; @@ -1071,8 +974,6 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) struct dc_stream_state *old_stream = dc->current_state->res_ctx.pipe_ctx[i].stream; bool should_disable = true; - bool pipe_split_change = - context->res_ctx.pipe_ctx[i].top_pipe != dc->current_state->res_ctx.pipe_ctx[i].top_pipe; for (j = 0; j < context->stream_count; j++) { if (old_stream == context->streams[j]) { @@ -1080,9 +981,6 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) break; } } - if (!should_disable && pipe_split_change) - should_disable = true; - if (should_disable && old_stream) { dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); @@ -1409,34 +1307,20 @@ static void program_timing_sync( status->timing_sync_info.master = false; } + /* remove any other unblanked pipes as they have already been synced */ + for (j = j + 1; j < group_size; j++) { + bool is_blanked; - /* remove any other pipes that are already been synced */ - if (dc->config.use_pipe_ctx_sync_logic) { - /* check pipe's syncd to decide which pipe to be removed */ - for (j = 1; j < group_size; j++) { - if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) { - group_size--; - pipe_set[j] = pipe_set[group_size]; - j--; - } else - /* link slave pipe's syncd with master pipe */ - pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd; - } - } else { - for (j = j + 1; j < group_size; j++) { - bool is_blanked; - - if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) - is_blanked = - pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); - else - is_blanked = - pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); - if (!is_blanked) { - group_size--; - pipe_set[j] = pipe_set[group_size]; - j--; - } + if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) + is_blanked = + pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); + else + is_blanked = + pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); + if (!is_blanked) { + group_size--; + pipe_set[j] = pipe_set[group_size]; + j--; } } @@ -1665,7 +1549,7 @@ static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context) } #if defined(CONFIG_DRM_AMD_DC_DCN) -void dc_z10_restore(const struct dc *dc) +void dc_z10_restore(struct dc *dc) { if (dc->hwss.z10_restore) dc->hwss.z10_restore(dc); @@ -1832,19 +1716,6 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context) dc_stream_log(dc, stream); } - /* - * Previous validation was perfomred with fast_validation = true and - * the full DML state required for hardware programming was skipped. - * - * Re-validate here to calculate these parameters / watermarks. - */ - result = dc_validate_global_state(dc, context, false); - if (result != DC_OK) { - DC_LOG_ERROR("DC commit global validation failure: %s (%d)", - dc_status_to_str(result), result); - return result; - } - result = dc_commit_state_no_check(dc, context); return (result == DC_OK); @@ -1907,27 +1778,6 @@ static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) return false; } -#ifdef CONFIG_DRM_AMD_DC_DCN -/* Perform updates here which need to be deferred until next vupdate - * - * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered - * but forcing lut memory to shutdown state is immediate. This causes - * single frame corruption as lut gets disabled mid-frame unless shutdown - * is deferred until after entering bypass. - */ -static void process_deferred_updates(struct dc *dc) -{ - int i = 0; - - if (dc->debug.enable_mem_low_power.bits.cm) { - ASSERT(dc->dcn_ip->max_num_dpp); - for (i = 0; i < dc->dcn_ip->max_num_dpp; i++) - if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update) - dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]); - } -} -#endif /* CONFIG_DRM_AMD_DC_DCN */ - void dc_post_update_surfaces_to_stream(struct dc *dc) { int i; @@ -1938,11 +1788,6 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) post_surface_trace(dc); - if (dc->ctx->dce_version >= DCE_VERSION_MAX) - TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); - else - TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); - if (is_flip_pending_in_pipes(dc, context)) return; @@ -1953,10 +1798,6 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); } -#ifdef CONFIG_DRM_AMD_DC_DCN - process_deferred_updates(dc); -#endif - dc->hwss.optimize_bandwidth(dc, context); dc->optimized_required = false; @@ -2154,7 +1995,7 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa } if (u->plane_info->dcc.enable != u->surface->dcc.enable - || u->plane_info->dcc.dcc_ind_blk != u->surface->dcc.dcc_ind_blk + || u->plane_info->dcc.independent_64b_blks != u->surface->dcc.independent_64b_blks || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) { /* During DCC on/off, stutter period is calculated before * DCC has fully transitioned. This results in incorrect @@ -2307,9 +2148,6 @@ static enum surface_update_type det_surface_update(const struct dc *dc, update_flags->bits.gamma_change = 1; } - if (u->lut3d_func || u->func_shaper) - update_flags->bits.lut_3d = 1; - if (u->hdr_mult.value) if (u->hdr_mult.value != u->surface->hdr_mult.value) { update_flags->bits.hdr_mult = 1; @@ -2323,7 +2161,6 @@ static enum surface_update_type det_surface_update(const struct dc *dc, if (update_flags->bits.input_csc_change || update_flags->bits.coeff_reduction_change - || update_flags->bits.lut_3d || update_flags->bits.gamma_change || update_flags->bits.gamut_remap_change) { type = UPDATE_TYPE_FULL; @@ -2382,11 +2219,6 @@ static enum surface_update_type check_update_surfaces_for_stream( if (stream_update->dsc_config) su_flags->bits.dsc_changed = 1; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (stream_update->mst_bw_update) - su_flags->bits.mst_bw = 1; -#endif - if (su_flags->raw != 0) overall_type = UPDATE_TYPE_FULL; @@ -2764,15 +2596,6 @@ static void commit_planes_do_stream_update(struct dc *dc, if (stream_update->dsc_config) dp_update_dsc_config(pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (stream_update->mst_bw_update) { - if (stream_update->mst_bw_update->is_increase) - dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); - else - dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); - } -#endif - if (stream_update->pending_test_pattern) { dc_link_dp_set_test_pattern(stream->link, stream->test_pattern.type, @@ -2995,12 +2818,12 @@ static void commit_planes_for_stream(struct dc *dc, #ifdef CONFIG_DRM_AMD_DC_DCN if (dc->debug.validate_dml_output) { for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i]; - if (cur_pipe->stream == NULL) + struct pipe_ctx cur_pipe = context->res_ctx.pipe_ctx[i]; + if (cur_pipe.stream == NULL) continue; - cur_pipe->plane_res.hubp->funcs->validate_dml_output( - cur_pipe->plane_res.hubp, dc->ctx, + cur_pipe.plane_res.hubp->funcs->validate_dml_output( + cur_pipe.plane_res.hubp, dc->ctx, &context->res_ctx.pipe_ctx[i].rq_regs, &context->res_ctx.pipe_ctx[i].dlg_regs, &context->res_ctx.pipe_ctx[i].ttu_regs); @@ -3151,14 +2974,6 @@ void dc_commit_updates_for_stream(struct dc *dc, if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) new_pipe->plane_state->force_full_update = true; } - } else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) { - /* - * Previous frame finished and HW is ready for optimization. - * - * Only relevant for DCN behavior where we can guarantee the optimization - * is safe to apply - retain the legacy behavior for DCE. - */ - dc_post_update_surfaces_to_stream(dc); } @@ -3215,11 +3030,14 @@ void dc_commit_updates_for_stream(struct dc *dc, pipe_ctx->plane_state->force_full_update = false; } } - - /* Legacy optimization path for DCE. */ - if (update_type >= UPDATE_TYPE_FULL && dc_ctx->dce_version < DCE_VERSION_MAX) { + /*let's use current_state to update watermark etc*/ + if (update_type >= UPDATE_TYPE_FULL) { dc_post_update_surfaces_to_stream(dc); - TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); + + if (dc_ctx->dce_version >= DCE_VERSION_MAX) + TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); + else + TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); } return; @@ -3442,7 +3260,7 @@ struct dc_sink *dc_link_add_remote_sink( goto fail_add_sink; edid_status = dm_helpers_parse_edid_caps( - link, + link->ctx, &dc_sink->dc_edid, &dc_sink->edid_caps); @@ -3522,7 +3340,6 @@ void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_ bool dc_set_psr_allow_active(struct dc *dc, bool enable) { int i; - bool allow_active; for (i = 0; i < dc->current_state->stream_count ; i++) { struct dc_link *link; @@ -3534,12 +3351,10 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable) if (link->psr_settings.psr_feature_enabled) { if (enable && !link->psr_settings.psr_allow_active) { - allow_active = true; - if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL)) + if (!dc_link_set_psr_allow_active(link, true, false, false)) return false; } else if (!enable && link->psr_settings.psr_allow_active) { - allow_active = false; - if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL)) + if (!dc_link_set_psr_allow_active(link, false, true, false)) return false; } } @@ -3599,98 +3414,6 @@ void dc_lock_memory_clock_frequency(struct dc *dc) core_link_enable_stream(dc->current_state, &dc->current_state->res_ctx.pipe_ctx[i]); } -static void blank_and_force_memclk(struct dc *dc, bool apply, unsigned int memclk_mhz) -{ - struct dc_state *context = dc->current_state; - struct hubp *hubp; - struct pipe_ctx *pipe; - int i; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->stream != NULL) { - dc->hwss.disable_pixel_data(dc, pipe, true); - - // wait for double buffer - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE); - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VBLANK); - pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE); - - hubp = pipe->plane_res.hubp; - hubp->funcs->set_blank_regs(hubp, true); - } - } - - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, memclk_mhz); - dc->clk_mgr->funcs->set_min_memclk(dc->clk_mgr, memclk_mhz); - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe = &context->res_ctx.pipe_ctx[i]; - - if (pipe->stream != NULL) { - dc->hwss.disable_pixel_data(dc, pipe, false); - - hubp = pipe->plane_res.hubp; - hubp->funcs->set_blank_regs(hubp, false); - } - } -} - - -/** - * dc_enable_dcmode_clk_limit() - lower clocks in dc (battery) mode - * @dc: pointer to dc of the dm calling this - * @enable: True = transition to DC mode, false = transition back to AC mode - * - * Some SoCs define additional clock limits when in DC mode, DM should - * invoke this function when the platform undergoes a power source transition - * so DC can apply/unapply the limit. This interface may be disruptive to - * the onscreen content. - * - * Context: Triggered by OS through DM interface, or manually by escape calls. - * Need to hold a dclock when doing so. - * - * Return: none (void function) - * - */ -void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable) -{ - uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; - unsigned int softMax, maxDPM, funcMin; - bool p_state_change_support; - - if (!ASICREV_IS_BEIGE_GOBY_P(hw_internal_rev)) - return; - - softMax = dc->clk_mgr->bw_params->dc_mode_softmax_memclk; - maxDPM = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz; - funcMin = (dc->clk_mgr->clks.dramclk_khz + 999) / 1000; - p_state_change_support = dc->clk_mgr->clks.p_state_change_support; - - if (enable && !dc->clk_mgr->dc_mode_softmax_enabled) { - if (p_state_change_support) { - if (funcMin <= softMax) - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, softMax); - // else: No-Op - } else { - if (funcMin <= softMax) - blank_and_force_memclk(dc, true, softMax); - // else: No-Op - } - } else if (!enable && dc->clk_mgr->dc_mode_softmax_enabled) { - if (p_state_change_support) { - if (funcMin <= softMax) - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, maxDPM); - // else: No-Op - } else { - if (funcMin <= softMax) - blank_and_force_memclk(dc, true, maxDPM); - // else: No-Op - } - } - dc->clk_mgr->dc_mode_softmax_enabled = enable; -} bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane, struct dc_cursor_attributes *cursor_attr) { @@ -3715,13 +3438,6 @@ void dc_hardware_release(struct dc *dc) */ bool dc_enable_dmub_notifications(struct dc *dc) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* YELLOW_CARP B0 USB4 DPIA needs dmub notifications for interrupts */ - if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && - dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 && - !dc->debug.dpia_debug.bits.disable_dpia) - return true; -#endif /* dmub aux needs dmub notifications to be enabled */ return dc->debug.enable_dmub_aux_for_legacy_ddc; } @@ -3747,12 +3463,7 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc, cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS; cmd.dp_aux_access.header.payload_bytes = 0; - /* For dpia, ddc_pin is set to NULL */ - if (!dc->links[link_index]->ddc->ddc_pin) - cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA; - else - cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC; - + cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC; cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst; cmd.dp_aux_access.aux_control.sw_crc_enabled = 0; cmd.dp_aux_access.aux_control.timeout = 0; @@ -3796,130 +3507,6 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc, return true; } -uint8_t get_link_index_from_dpia_port_index(const struct dc *dc, - uint8_t dpia_port_index) -{ - uint8_t index, link_index = 0xFF; - - for (index = 0; index < dc->link_count; index++) { - /* ddc_hw_inst has dpia port index for dpia links - * and ddc instance for legacy links - */ - if (!dc->links[index]->ddc->ddc_pin) { - if (dc->links[index]->ddc_hw_inst == dpia_port_index) { - link_index = index; - break; - } - } - } - ASSERT(link_index != 0xFF); - return link_index; -} - -/** - ***************************************************************************** - * Function: dc_process_dmub_set_config_async - * - * @brief - * Submits set_config command to dmub via inbox message - * - * @param - * [in] dc: dc structure - * [in] link_index: link index - * [in] payload: aux payload - * [out] notify: set_config immediate reply - * - * @return - * True if successful, False if failure - ***************************************************************************** - */ -bool dc_process_dmub_set_config_async(struct dc *dc, - uint32_t link_index, - struct set_config_cmd_payload *payload, - struct dmub_notification *notify) -{ - union dmub_rb_cmd cmd = {0}; - struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; - bool is_cmd_complete = true; - - /* prepare SET_CONFIG command */ - cmd.set_config_access.header.type = DMUB_CMD__DPIA; - cmd.set_config_access.header.sub_type = DMUB_CMD__DPIA_SET_CONFIG_ACCESS; - - cmd.set_config_access.set_config_control.instance = dc->links[link_index]->ddc_hw_inst; - cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type; - cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data; - - if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) { - /* command is not processed by dmub */ - notify->sc_status = SET_CONFIG_UNKNOWN_ERROR; - return is_cmd_complete; - } - - /* command processed by dmub, if ret_status is 1, it is completed instantly */ - if (cmd.set_config_access.header.ret_status == 1) - notify->sc_status = cmd.set_config_access.set_config_control.immed_status; - else - /* cmd pending, will receive notification via outbox */ - is_cmd_complete = false; - - return is_cmd_complete; -} - -/** - ***************************************************************************** - * Function: dc_process_dmub_set_mst_slots - * - * @brief - * Submits mst slot allocation command to dmub via inbox message - * - * @param - * [in] dc: dc structure - * [in] link_index: link index - * [in] mst_alloc_slots: mst slots to be allotted - * [out] mst_slots_in_use: mst slots in use returned in failure case - * - * @return - * DC_OK if successful, DC_ERROR if failure - ***************************************************************************** - */ -enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, - uint32_t link_index, - uint8_t mst_alloc_slots, - uint8_t *mst_slots_in_use) -{ - union dmub_rb_cmd cmd = {0}; - struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; - - /* prepare MST_ALLOC_SLOTS command */ - cmd.set_mst_alloc_slots.header.type = DMUB_CMD__DPIA; - cmd.set_mst_alloc_slots.header.sub_type = DMUB_CMD__DPIA_MST_ALLOC_SLOTS; - - cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst; - cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots; - - if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) - /* command is not processed by dmub */ - return DC_ERROR_UNEXPECTED; - - /* command processed by dmub, if ret_status is 1 */ - if (cmd.set_config_access.header.ret_status != 1) - /* command processing error */ - return DC_ERROR_UNEXPECTED; - - /* command processed and we have a status of 2, mst not enabled in dpia */ - if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 2) - return DC_FAIL_UNSUPPORTED_1; - - /* previously configured mst alloc and used slots did not match */ - if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 3) { - *mst_slots_in_use = cmd.set_mst_alloc_slots.mst_slots_control.mst_slots_in_use; - return DC_NOT_SUPPORTED; - } - - return DC_OK; -} - /** * dc_disable_accelerated_mode - disable accelerated mode * @dc: dc structure @@ -3928,57 +3515,3 @@ void dc_disable_accelerated_mode(struct dc *dc) { bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 0); } - - -/** - ***************************************************************************** - * dc_notify_vsync_int_state() - notifies vsync enable/disable state - * @dc: dc structure - * @stream: stream where vsync int state changed - * @enable: whether vsync is enabled or disabled - * - * Called when vsync is enabled/disabled - * Will notify DMUB to start/stop ABM interrupts after steady state is reached - * - ***************************************************************************** - */ -void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable) -{ - int i; - int edp_num; - struct pipe_ctx *pipe = NULL; - struct dc_link *link = stream->sink->link; - struct dc_link *edp_links[MAX_NUM_EDP]; - - - if (link->psr_settings.psr_feature_enabled) - return; - - /*find primary pipe associated with stream*/ - for (i = 0; i < MAX_PIPES; i++) { - pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - - if (pipe->stream == stream && pipe->stream_res.tg) - break; - } - - if (i == MAX_PIPES) { - ASSERT(0); - return; - } - - get_edp_links(dc, edp_links, &edp_num); - - /* Determine panel inst */ - for (i = 0; i < edp_num; i++) { - if (edp_links[i] == link) - break; - } - - if (i == edp_num) { - return; - } - - if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause) - pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst); -} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index 643762542e..21be2a6843 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -422,8 +422,6 @@ char *dc_status_to_str(enum dc_status status) return "The operation is not supported."; case DC_UNSUPPORTED_VALUE: return "The value specified is not supported."; - case DC_NO_LINK_ENC_RESOURCE: - return "No link encoder resource"; case DC_ERROR_UNEXPECTED: return "Unexpected error"; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index b5e570d33c..3c4205248e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -51,8 +51,6 @@ #include "inc/link_enc_cfg.h" #include "inc/link_dpcd.h" -#include "dc/dcn30/dcn30_vpg.h" - #define DC_LOGGER_INIT(logger) #define LINK_INFO(...) \ @@ -239,10 +237,10 @@ bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type) /* Link may not have physical HPD pin. */ if (link->ep_type != DISPLAY_ENDPOINT_PHY) { - if (link->is_hpd_pending || !link->hpd_status) - *type = dc_connection_none; - else + if (link->hpd_status) *type = dc_connection_single; + else + *type = dc_connection_none; return true; } @@ -643,13 +641,13 @@ static void query_hdcp_capability(enum signal_type signal, struct dc_link *link) static void read_current_link_settings_on_detect(struct dc_link *link) { - union lane_count_set lane_count_set = {0}; + union lane_count_set lane_count_set = { {0} }; uint8_t link_bw_set; uint8_t link_rate_set; uint32_t read_dpcd_retry_cnt = 10; enum dc_status status = DC_ERROR_UNEXPECTED; int i; - union max_down_spread max_down_spread = {0}; + union max_down_spread max_down_spread = { {0} }; // Read DPCD 00101h to find out the number of lanes currently set for (i = 0; i < read_dpcd_retry_cnt; i++) { @@ -727,18 +725,6 @@ static bool detect_dp(struct dc_link *link, dal_ddc_service_set_transaction_type(link->ddc, sink_caps->transaction_type); -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* Apply work around for tunneled MST on certain USB4 docks. Always use DSC if dock - * reports DSC support. - */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && - link->type == dc_connection_mst_branch && - link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 && - link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT && - !link->dc->debug.dpia_debug.bits.disable_mst_dsc_work_around) - link->wa_flags.dpia_mst_dsc_always_on = true; -#endif - #if defined(CONFIG_DRM_AMD_DC_HDCP) /* In case of fallback to SST when topology discovery below fails * HDCP caps will be querried again later by the upper layer (caller @@ -850,7 +836,6 @@ static bool dc_link_detect_helper(struct dc_link *link, enum dc_connection_type pre_connection_type = dc_connection_none; bool perform_dp_seamless_boot = false; const uint32_t post_oui_delay = 30; // 30ms - struct link_resource link_res = { 0 }; DC_LOGGER_INIT(link->ctx->logger); @@ -943,14 +928,6 @@ static bool dc_link_detect_helper(struct dc_link *link, return false; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING) - link_res.hpo_dp_link_enc = resource_get_hpo_dp_link_enc_for_det_lt( - &link->dc->current_state->res_ctx, - link->dc->res_pool, - link); -#endif - if (link->type == dc_connection_mst_branch) { LINK_INFO("link=%d, mst branch is now Connected\n", link->link_index); @@ -959,7 +936,7 @@ static bool dc_link_detect_helper(struct dc_link *link, * empty which leads to allocate_mst_payload() has "0" * pbn_per_slot value leading to exception on dc_fixpt_div() */ - dp_verify_mst_link_cap(link, &link_res); + dp_verify_mst_link_cap(link); /* * This call will initiate MST topology discovery. Which @@ -1123,7 +1100,6 @@ static bool dc_link_detect_helper(struct dc_link *link, // verify link cap for SST non-seamless boot if (!perform_dp_seamless_boot) dp_verify_link_cap_with_retries(link, - &link_res, &link->reported_link_cap, LINK_TRAINING_MAX_VERIFY_RETRY); } else { @@ -1189,10 +1165,6 @@ static bool dc_link_detect_helper(struct dc_link *link, LINK_INFO("link=%d, mst branch is now Disconnected\n", link->link_index); - /* Disable work around which keeps DSC on for tunneled MST on certain USB4 docks. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) - link->wa_flags.dpia_mst_dsc_always_on = false; - dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); link->mst_stream_alloc_table.stream_count = 0; @@ -1201,11 +1173,6 @@ static bool dc_link_detect_helper(struct dc_link *link, sizeof(link->mst_stream_alloc_table.stream_allocations)); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING) - reset_dp_hpo_stream_encoders_for_link(link); -#endif - link->type = dc_connection_none; sink_caps.signal = SIGNAL_TYPE_NONE; /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk @@ -1242,10 +1209,6 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) } } -#if defined(CONFIG_DRM_AMD_DC_DCN) - dc_z10_restore(dc); -#endif - /* get out of low power state */ if (!can_apply_seamless_boot && reason != DETECT_REASON_BOOT) clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); @@ -1415,8 +1378,8 @@ static enum transmitter translate_encoder_to_transmitter(struct graphics_object_ } } -static bool dc_link_construct_legacy(struct dc_link *link, - const struct link_init_data *init_params) +static bool dc_link_construct(struct dc_link *link, + const struct link_init_data *init_params) { uint8_t i; struct ddc_service_init_data ddc_service_init_data = { { 0 } }; @@ -1586,9 +1549,6 @@ static bool dc_link_construct_legacy(struct dc_link *link, } DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C); -#if defined(CONFIG_DRM_AMD_DC_DCN) - DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE); -#endif /* Update link encoder tracking variables. These are used for the dynamic * assignment of link encoders to streams. @@ -1650,14 +1610,6 @@ static bool dc_link_construct_legacy(struct dc_link *link, DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X", link->ddi_channel_mapping.raw); DC_LOG_DC("BIOS object table - chip_caps: %d", link->chip_caps); } - - if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) { - link->bios_forced_drive_settings.VOLTAGE_SWING = - (info->ext_disp_conn_info.fixdpvoltageswing & 0x3); - link->bios_forced_drive_settings.PRE_EMPHASIS = - ((info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3); - } - break; } } @@ -1699,80 +1651,6 @@ static bool dc_link_construct_legacy(struct dc_link *link, return false; } -static bool dc_link_construct_dpia(struct dc_link *link, - const struct link_init_data *init_params) -{ - struct ddc_service_init_data ddc_service_init_data = { { 0 } }; - struct dc_context *dc_ctx = init_params->ctx; - - DC_LOGGER_INIT(dc_ctx->logger); - - /* Initialized irq source for hpd and hpd rx */ - link->irq_source_hpd = DC_IRQ_SOURCE_INVALID; - link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID; - link->link_status.dpcd_caps = &link->dpcd_caps; - - link->dc = init_params->dc; - link->ctx = dc_ctx; - link->link_index = init_params->link_index; - - memset(&link->preferred_training_settings, 0, - sizeof(struct dc_link_training_overrides)); - memset(&link->preferred_link_setting, 0, - sizeof(struct dc_link_settings)); - - /* Dummy Init for linkid */ - link->link_id.type = OBJECT_TYPE_CONNECTOR; - link->link_id.id = CONNECTOR_ID_DISPLAY_PORT; - link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index; - link->is_internal_display = false; - link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT; - LINK_INFO("Connector[%d] description:signal %d\n", - init_params->connector_index, - link->connector_signal); - - link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA; - link->is_dig_mapping_flexible = true; - - /* TODO: Initialize link : funcs->link_init */ - - ddc_service_init_data.ctx = link->ctx; - ddc_service_init_data.id = link->link_id; - ddc_service_init_data.link = link; - /* Set indicator for dpia link so that ddc won't be created */ - ddc_service_init_data.is_dpia_link = true; - - link->ddc = dal_ddc_service_create(&ddc_service_init_data); - if (!link->ddc) { - DC_ERROR("Failed to create ddc_service!\n"); - goto ddc_create_fail; - } - - /* Set dpia port index : 0 to number of dpia ports */ - link->ddc_hw_inst = init_params->connector_index; - - /* TODO: Create link encoder */ - - link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; - - /* Some docks seem to NAK I2C writes to segment pointer with mot=0. */ - link->wa_flags.dp_mot_reset_segment = true; - - return true; - -ddc_create_fail: - return false; -} - -static bool dc_link_construct(struct dc_link *link, - const struct link_init_data *init_params) -{ - /* Handle dpia case */ - if (init_params->is_dpia_link) - return dc_link_construct_dpia(link, init_params); - else - return dc_link_construct_legacy(link, init_params); -} /******************************************************************************* * Public functions ******************************************************************************/ @@ -1865,47 +1743,17 @@ static enum dc_status enable_link_dp(struct dc_state *state, /* get link settings for video mode timing */ decide_link_settings(stream, &link_settings); - /* Train with fallback when enabling DPIA link. Conventional links are - * trained with fallback during sink detection. - */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) - do_fallback = true; - -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* - * Temporary w/a to get DP2.0 link rates to work with SST. - * TODO DP2.0 - Workaround: Remove w/a if and when the issue is resolved. - */ - if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING && - pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - link->dc->debug.set_mst_en_for_sst) { - dp_enable_mst_on_sink(link, true); - } -#endif - if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { /*in case it is not on*/ link->dc->hwss.edp_power_control(link, true); link->dc->hwss.edp_wait_for_hpd_ready(link, true); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) { - /* TODO - DP2.0 HW: calculate 32 symbol clock for HPO encoder */ - } else { - pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = - link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; - if (state->clk_mgr && !apply_seamless_boot_optimization) - state->clk_mgr->funcs->update_clocks(state->clk_mgr, - state, false); - } -#else pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = - link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; + link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; if (state->clk_mgr && !apply_seamless_boot_optimization) state->clk_mgr->funcs->update_clocks(state->clk_mgr, - state, false); -#endif + state, false); // during mode switch we do DP_SET_POWER off then on, and OUI is lost dpcd_set_source_specific_data(link); @@ -1934,12 +1782,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, else fec_enable = true; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) - dp_set_fec_enable(link, fec_enable); -#else dp_set_fec_enable(link, fec_enable); -#endif // during mode set we do DP_SET_POWER off then on, aux writes are lost if (link->dpcd_sink_ext_caps.bits.oled == 1 || @@ -1991,57 +1834,6 @@ static enum dc_status enable_link_dp_mst( return enable_link_dp(state, pipe_ctx); } -void dc_link_blank_all_dp_displays(struct dc *dc) -{ - unsigned int i; - uint8_t dpcd_power_state = '\0'; - enum dc_status status = DC_ERROR_UNEXPECTED; - - for (i = 0; i < dc->link_count; i++) { - if ((dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) || - (dc->links[i]->priv == NULL) || (dc->links[i]->local_sink == NULL)) - continue; - - /* DP 2.0 spec requires that we read LTTPR caps first */ - dp_retrieve_lttpr_cap(dc->links[i]); - /* if any of the displays are lit up turn them off */ - status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, - &dpcd_power_state, sizeof(dpcd_power_state)); - - if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) - dc_link_blank_dp_stream(dc->links[i], true); - } - -} - -void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init) -{ - unsigned int j; - struct dc *dc = link->ctx->dc; - enum signal_type signal = link->connector_signal; - - if ((signal == SIGNAL_TYPE_EDP) || - (signal == SIGNAL_TYPE_DISPLAY_PORT)) { - if (link->ep_type == DISPLAY_ENDPOINT_PHY && - link->link_enc->funcs->get_dig_frontend && - link->link_enc->funcs->is_dig_enabled(link->link_enc)) { - unsigned int fe = link->link_enc->funcs->get_dig_frontend(link->link_enc); - - if (fe != ENGINE_ID_UNKNOWN) - for (j = 0; j < dc->res_pool->stream_enc_count; j++) { - if (fe == dc->res_pool->stream_enc[j]->id) { - dc->res_pool->stream_enc[j]->funcs->dp_blank(link, - dc->res_pool->stream_enc[j]); - break; - } - } - } - - if ((!link->wa_flags.dp_keep_receiver_powered) || hw_init) - dp_receiver_power_ctrl(link, false); - } -} - static bool get_ext_hdmi_settings(struct pipe_ctx *pipe_ctx, enum engine_id eng_id, struct ext_hdmi_settings *settings) @@ -2479,8 +2271,7 @@ static void write_i2c_redriver_setting( DC_LOG_DEBUG("Set redriver failed"); } -static void disable_link(struct dc_link *link, const struct link_resource *link_res, - enum signal_type signal) +static void disable_link(struct dc_link *link, enum signal_type signal) { /* * TODO: implement call for dp_set_hw_test_pattern @@ -2495,25 +2286,15 @@ static void disable_link(struct dc_link *link, const struct link_resource *link_ if (dc_is_dp_signal(signal)) { /* SST DP, eDP */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dc_link_settings link_settings = link->cur_link_settings; -#endif if (dc_is_dp_sst_signal(signal)) - dp_disable_link_phy(link, link_res, signal); + dp_disable_link_phy(link, signal); else - dp_disable_link_phy_mst(link, link_res, signal); + dp_disable_link_phy_mst(link, signal); if (dc_is_dp_sst_signal(signal) || link->mst_stream_alloc_table.stream_count == 0) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) { - dp_set_fec_enable(link, false); - dp_set_fec_ready(link, link_res, false); - } -#else dp_set_fec_enable(link, false); - dp_set_fec_ready(link, link_res, false); -#endif + dp_set_fec_ready(link, false); } } else { if (signal != SIGNAL_TYPE_VIRTUAL) @@ -2623,7 +2404,7 @@ static enum dc_status enable_link( * new link settings. */ if (link->link_status.link_active) { - disable_link(link, &pipe_ctx->link_res, pipe_ctx->stream->signal); + disable_link(link, pipe_ctx->stream->signal); } switch (pipe_ctx->stream->signal) { @@ -2696,14 +2477,9 @@ static bool dp_active_dongle_validate_timing( break; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dpcd_caps->dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER && - dongle_caps->extendedCapValid == true) { -#else if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || dongle_caps->extendedCapValid == false) return true; -#endif /* Check Pixel Encoding */ switch (timing->pixel_encoding) { @@ -2743,106 +2519,8 @@ static bool dp_active_dongle_validate_timing( return false; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps > 0) { // DP to HDMI FRL converter - struct dc_crtc_timing outputTiming = *timing; - - if (timing->flags.DSC && !timing->dsc_cfg.is_frl) - /* DP input has DSC, HDMI FRL output doesn't have DSC, remove DSC from output timing */ - outputTiming.flags.DSC = 0; - if (dc_bandwidth_in_kbps_from_timing(&outputTiming) > dongle_caps->dp_hdmi_frl_max_link_bw_in_kbps) - return false; - } else { // DP to HDMI TMDS converter - if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10)) - return false; - } -#else if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10)) return false; -#endif - -#if defined(CONFIG_DRM_AMD_DC_DCN) - } - - if (dpcd_caps->channel_coding_cap.bits.DP_128b_132b_SUPPORTED == 0 && - dpcd_caps->dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT == 0 && - dongle_caps->dfp_cap_ext.supported) { - - if (dongle_caps->dfp_cap_ext.max_pixel_rate_in_mps < (timing->pix_clk_100hz / 10000)) - return false; - - if (dongle_caps->dfp_cap_ext.max_video_h_active_width < timing->h_addressable) - return false; - - if (dongle_caps->dfp_cap_ext.max_video_v_active_height < timing->v_addressable) - return false; - - if (timing->pixel_encoding == PIXEL_ENCODING_RGB) { - if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb) - return false; - if (timing->display_color_depth == COLOR_DEPTH_666 && - !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_6bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_888 && - !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_8bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_101010 && - !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_10bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_121212 && - !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_12bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_161616 && - !dongle_caps->dfp_cap_ext.rgb_color_depth_caps.support_16bpc) - return false; - } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) { - if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb) - return false; - if (timing->display_color_depth == COLOR_DEPTH_888 && - !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_8bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_101010 && - !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_10bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_121212 && - !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_12bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_161616 && - !dongle_caps->dfp_cap_ext.ycbcr444_color_depth_caps.support_16bpc) - return false; - } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) { - if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb) - return false; - if (timing->display_color_depth == COLOR_DEPTH_888 && - !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_8bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_101010 && - !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_10bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_121212 && - !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_12bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_161616 && - !dongle_caps->dfp_cap_ext.ycbcr422_color_depth_caps.support_16bpc) - return false; - } else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) { - if (!dongle_caps->dfp_cap_ext.encoding_format_caps.support_rgb) - return false; - if (timing->display_color_depth == COLOR_DEPTH_888 && - !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_8bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_101010 && - !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_10bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_121212 && - !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_12bpc) - return false; - else if (timing->display_color_depth == COLOR_DEPTH_161616 && - !dongle_caps->dfp_cap_ext.ycbcr420_color_depth_caps.support_16bpc) - return false; - } - } -#endif return true; } @@ -2986,8 +2664,8 @@ bool dc_link_set_backlight_level(const struct dc_link *link, return true; } -bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active, - bool wait, bool force_static, const unsigned int *power_opts) +bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, + bool wait, bool force_static) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; @@ -3000,33 +2678,20 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) return false; - /* Set power optimization flag */ - if (power_opts && link->psr_settings.psr_power_opt != *power_opts) { - link->psr_settings.psr_power_opt = *power_opts; - - if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt) - psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst); - } - - /* Enable or Disable PSR */ - if (allow_active && link->psr_settings.psr_allow_active != *allow_active) { - link->psr_settings.psr_allow_active = *allow_active; - + link->psr_settings.psr_allow_active = allow_active; #if defined(CONFIG_DRM_AMD_DC_DCN) - if (!link->psr_settings.psr_allow_active) - dc_z10_restore(dc); + if (!allow_active) + dc_z10_restore(dc); #endif - if (psr != NULL && link->psr_settings.psr_feature_enabled) { - if (force_static && psr->funcs->psr_force_static) - psr->funcs->psr_force_static(psr, panel_inst); - psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst); - } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && - link->psr_settings.psr_feature_enabled) - dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait); - else - return false; - } + if (psr != NULL && link->psr_settings.psr_feature_enabled) { + if (force_static && psr->funcs->psr_force_static) + psr->funcs->psr_force_static(psr, panel_inst); + psr->funcs->psr_enable(psr, allow_active, wait, panel_inst); + } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled) + dmcu->funcs->set_psr_enable(dmcu, allow_active, wait); + else + return false; return true; } @@ -3315,12 +2980,10 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx) static void update_mst_stream_alloc_table( struct dc_link *link, struct stream_encoder *stream_enc, -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_stream_encoder *hpo_dp_stream_enc, // TODO: Rename stream_enc to dio_stream_enc? -#endif const struct dp_mst_stream_allocation_table *proposed_table) { - struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { 0 }; + struct link_mst_stream_allocation work_table[MAX_CONTROLLER_NUM] = { + { 0 } }; struct link_mst_stream_allocation *dc_alloc; int i; @@ -3353,9 +3016,6 @@ static void update_mst_stream_alloc_table( work_table[i].slot_count = proposed_table->stream_allocations[i].slot_count; work_table[i].stream_enc = stream_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - work_table[i].hpo_dp_stream_enc = hpo_dp_stream_enc; -#endif } } @@ -3366,109 +3026,6 @@ static void update_mst_stream_alloc_table( link->mst_stream_alloc_table.stream_allocations[i] = work_table[i]; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static void dc_log_vcp_x_y(const struct dc_link *link, struct fixed31_32 avg_time_slots_per_mtp) -{ - const uint32_t VCP_Y_PRECISION = 1000; - uint64_t vcp_x, vcp_y; - - // Add 0.5*(1/VCP_Y_PRECISION) to round up to decimal precision - avg_time_slots_per_mtp = dc_fixpt_add( - avg_time_slots_per_mtp, dc_fixpt_from_fraction(1, 2 * VCP_Y_PRECISION)); - - vcp_x = dc_fixpt_floor(avg_time_slots_per_mtp); - vcp_y = dc_fixpt_floor( - dc_fixpt_mul_int( - dc_fixpt_sub_int(avg_time_slots_per_mtp, dc_fixpt_floor(avg_time_slots_per_mtp)), - VCP_Y_PRECISION)); - - if (link->type == dc_connection_mst_branch) - DC_LOG_DP2("MST Update Payload: set_throttled_vcp_size slot X.Y for MST stream " - "X: %lld Y: %lld/%d", vcp_x, vcp_y, VCP_Y_PRECISION); - else - DC_LOG_DP2("SST Update Payload: set_throttled_vcp_size slot X.Y for SST stream " - "X: %lld Y: %lld/%d", vcp_x, vcp_y, VCP_Y_PRECISION); -} - -/* - * Payload allocation/deallocation for SST introduced in DP2.0 - */ -static enum dc_status dc_link_update_sst_payload(struct pipe_ctx *pipe_ctx, - bool allocate) -{ - struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->link; - struct hpo_dp_link_encoder *hpo_dp_link_encoder = pipe_ctx->link_res.hpo_dp_link_enc; - struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc; - struct link_mst_stream_allocation_table proposed_table = {0}; - struct fixed31_32 avg_time_slots_per_mtp; - DC_LOGGER_INIT(link->ctx->logger); - - /* slot X.Y for SST payload deallocate */ - if (!allocate) { - avg_time_slots_per_mtp = dc_fixpt_from_int(0); - - dc_log_vcp_x_y(link, avg_time_slots_per_mtp); - - hpo_dp_link_encoder->funcs->set_throttled_vcp_size( - hpo_dp_link_encoder, - hpo_dp_stream_encoder->inst, - avg_time_slots_per_mtp); - } - - /* calculate VC payload and update branch with new payload allocation table*/ - if (!dpcd_write_128b_132b_sst_payload_allocation_table( - stream, - link, - &proposed_table, - allocate)) { - DC_LOG_ERROR("SST Update Payload: Failed to update " - "allocation table for " - "pipe idx: %d\n", - pipe_ctx->pipe_idx); - } - - proposed_table.stream_allocations[0].hpo_dp_stream_enc = hpo_dp_stream_encoder; - - ASSERT(proposed_table.stream_count == 1); - - //TODO - DP2.0 Logging: Instead of hpo_dp_stream_enc pointer, log instance id - DC_LOG_DP2("SST Update Payload: hpo_dp_stream_enc: %p " - "vcp_id: %d " - "slot_count: %d\n", - (void *) proposed_table.stream_allocations[0].hpo_dp_stream_enc, - proposed_table.stream_allocations[0].vcp_id, - proposed_table.stream_allocations[0].slot_count); - - /* program DP source TX for payload */ - hpo_dp_link_encoder->funcs->update_stream_allocation_table( - hpo_dp_link_encoder, - &proposed_table); - - /* poll for ACT handled */ - if (!dpcd_poll_for_allocation_change_trigger(link)) { - // Failures will result in blackscreen and errors logged - BREAK_TO_DEBUGGER(); - } - - /* slot X.Y for SST payload allocate */ - if (allocate) { - avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link); - - dc_log_vcp_x_y(link, avg_time_slots_per_mtp); - - hpo_dp_link_encoder->funcs->set_throttled_vcp_size( - hpo_dp_link_encoder, - hpo_dp_stream_encoder->inst, - avg_time_slots_per_mtp); - } - - /* Always return DC_OK. - * If part of sequence fails, log failure(s) and show blackscreen - */ - return DC_OK; -} -#endif /* convert link_mst_stream_alloc_table to dm dp_mst_stream_alloc_table * because stream_encoder is not exposed to dm @@ -3477,27 +3034,16 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - struct link_encoder *link_encoder = NULL; + struct link_encoder *link_encoder = link->link_enc; struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_link_encoder *hpo_dp_link_encoder = pipe_ctx->link_res.hpo_dp_link_enc; - struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc; -#endif struct dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp; struct fixed31_32 pbn; struct fixed31_32 pbn_per_slot; - int i; + uint8_t i; enum act_return_status ret; DC_LOGGER_INIT(link->ctx->logger); - /* Link encoder may have been dynamically assigned to non-physical display endpoint. */ - if (link->ep_type == DISPLAY_ENDPOINT_PHY) - link_encoder = link->link_enc; - else if (link->dc->res_pool->funcs->link_encs_assign) - link_encoder = link_enc_cfg_get_link_enc_used_by_stream(pipe_ctx->stream->ctx->dc, stream); - ASSERT(link_encoder); - /* enable_link_dp_mst already check link->enabled_stream_count * and stream is in link->stream[]. This is called during set mode, * stream_enc is available. @@ -3510,14 +3056,7 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) &proposed_table, true)) { update_mst_stream_alloc_table( -#if defined(CONFIG_DRM_AMD_DC_DCN) - link, - pipe_ctx->stream_res.stream_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc, - &proposed_table); -#else link, pipe_ctx->stream_res.stream_enc, &proposed_table); -#endif } else DC_LOG_WARNING("Failed to update" @@ -3531,20 +3070,6 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) link->mst_stream_alloc_table.stream_count); for (i = 0; i < MAX_CONTROLLER_NUM; i++) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - DC_LOG_MST("stream_enc[%d]: %p " - "stream[%d].hpo_dp_stream_enc: %p " - "stream[%d].vcp_id: %d " - "stream[%d].slot_count: %d\n", - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc, - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc, - i, - link->mst_stream_alloc_table.stream_allocations[i].vcp_id, - i, - link->mst_stream_alloc_table.stream_allocations[i].slot_count); -#else DC_LOG_MST("stream_enc[%d]: %p " "stream[%d].vcp_id: %d " "stream[%d].slot_count: %d\n", @@ -3554,47 +3079,14 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) link->mst_stream_alloc_table.stream_allocations[i].vcp_id, i, link->mst_stream_alloc_table.stream_allocations[i].slot_count); -#endif } ASSERT(proposed_table.stream_count > 0); - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { - static enum dc_status status; - uint8_t mst_alloc_slots = 0, prev_mst_slots_in_use = 0xFF; - - for (i = 0; i < link->mst_stream_alloc_table.stream_count; i++) - mst_alloc_slots += link->mst_stream_alloc_table.stream_allocations[i].slot_count; - - status = dc_process_dmub_set_mst_slots(link->dc, link->link_index, - mst_alloc_slots, &prev_mst_slots_in_use); - ASSERT(status == DC_OK); - DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n", - status, mst_alloc_slots, prev_mst_slots_in_use); - } - /* program DP source TX for payload */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - switch (dp_get_link_encoding_format(&link->cur_link_settings)) { - case DP_8b_10b_ENCODING: - link_encoder->funcs->update_mst_stream_allocation_table( - link_encoder, - &link->mst_stream_alloc_table); - break; - case DP_128b_132b_ENCODING: - hpo_dp_link_encoder->funcs->update_stream_allocation_table( - hpo_dp_link_encoder, - &link->mst_stream_alloc_table); - break; - case DP_UNKNOWN_ENCODING: - DC_LOG_ERROR("Failure: unknown encoding format\n"); - return DC_ERROR_UNEXPECTED; - } -#else link_encoder->funcs->update_mst_stream_allocation_table( link_encoder, &link->mst_stream_alloc_table); -#endif /* send down message */ ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger( @@ -3617,215 +3109,26 @@ enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx) pbn = get_pbn_from_timing(pipe_ctx); avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); -#if defined(CONFIG_DRM_AMD_DC_DCN) - switch (dp_get_link_encoding_format(&link->cur_link_settings)) { - case DP_8b_10b_ENCODING: - stream_encoder->funcs->set_throttled_vcp_size( - stream_encoder, - avg_time_slots_per_mtp); - break; - case DP_128b_132b_ENCODING: - hpo_dp_link_encoder->funcs->set_throttled_vcp_size( - hpo_dp_link_encoder, - hpo_dp_stream_encoder->inst, - avg_time_slots_per_mtp); - break; - case DP_UNKNOWN_ENCODING: - DC_LOG_ERROR("Failure: unknown encoding format\n"); - return DC_ERROR_UNEXPECTED; - } -#else stream_encoder->funcs->set_throttled_vcp_size( stream_encoder, avg_time_slots_per_mtp); -#endif return DC_OK; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps) -{ - struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->link; - struct fixed31_32 avg_time_slots_per_mtp; - struct fixed31_32 pbn; - struct fixed31_32 pbn_per_slot; - struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc; - struct dp_mst_stream_allocation_table proposed_table = {0}; - uint8_t i; - enum act_return_status ret; - DC_LOGGER_INIT(link->ctx->logger); - - /* decrease throttled vcp size */ - pbn_per_slot = get_pbn_per_slot(stream); - pbn = get_pbn_from_bw_in_kbps(bw_in_kbps); - avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); - - stream_encoder->funcs->set_throttled_vcp_size( - stream_encoder, - avg_time_slots_per_mtp); - - /* send ALLOCATE_PAYLOAD sideband message with updated pbn */ - dm_helpers_dp_mst_send_payload_allocation( - stream->ctx, - stream, - true); - - /* notify immediate branch device table update */ - if (dm_helpers_dp_mst_write_payload_allocation_table( - stream->ctx, - stream, - &proposed_table, - true)) { - /* update mst stream allocation table software state */ - update_mst_stream_alloc_table( - link, - pipe_ctx->stream_res.stream_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc, - &proposed_table); - } else { - DC_LOG_WARNING("Failed to update" - "MST allocation table for" - "pipe idx:%d\n", - pipe_ctx->pipe_idx); - } - - DC_LOG_MST("%s " - "stream_count: %d: \n ", - __func__, - link->mst_stream_alloc_table.stream_count); - - for (i = 0; i < MAX_CONTROLLER_NUM; i++) { - DC_LOG_MST("stream_enc[%d]: %p " - "stream[%d].vcp_id: %d " - "stream[%d].slot_count: %d\n", - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc, - i, - link->mst_stream_alloc_table.stream_allocations[i].vcp_id, - i, - link->mst_stream_alloc_table.stream_allocations[i].slot_count); - } - - ASSERT(proposed_table.stream_count > 0); - - /* update mst stream allocation table hardware state */ - link_encoder->funcs->update_mst_stream_allocation_table( - link_encoder, - &link->mst_stream_alloc_table); - - /* poll for immediate branch device ACT handled */ - ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger( - stream->ctx, - stream); - - return DC_OK; -} - -enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t bw_in_kbps) -{ - struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->link; - struct fixed31_32 avg_time_slots_per_mtp; - struct fixed31_32 pbn; - struct fixed31_32 pbn_per_slot; - struct link_encoder *link_encoder = link->link_enc; - struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc; - struct dp_mst_stream_allocation_table proposed_table = {0}; - uint8_t i; - enum act_return_status ret; - DC_LOGGER_INIT(link->ctx->logger); - - /* notify immediate branch device table update */ - if (dm_helpers_dp_mst_write_payload_allocation_table( - stream->ctx, - stream, - &proposed_table, - true)) { - /* update mst stream allocation table software state */ - update_mst_stream_alloc_table( - link, - pipe_ctx->stream_res.stream_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc, - &proposed_table); - } - - DC_LOG_MST("%s " - "stream_count: %d: \n ", - __func__, - link->mst_stream_alloc_table.stream_count); - - for (i = 0; i < MAX_CONTROLLER_NUM; i++) { - DC_LOG_MST("stream_enc[%d]: %p " - "stream[%d].vcp_id: %d " - "stream[%d].slot_count: %d\n", - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc, - i, - link->mst_stream_alloc_table.stream_allocations[i].vcp_id, - i, - link->mst_stream_alloc_table.stream_allocations[i].slot_count); - } - - ASSERT(proposed_table.stream_count > 0); - - /* update mst stream allocation table hardware state */ - link_encoder->funcs->update_mst_stream_allocation_table( - link_encoder, - &link->mst_stream_alloc_table); - - /* poll for immediate branch device ACT handled */ - ret = dm_helpers_dp_mst_poll_for_allocation_change_trigger( - stream->ctx, - stream); - - if (ret != ACT_LINK_LOST) { - /* send ALLOCATE_PAYLOAD sideband message with updated pbn */ - dm_helpers_dp_mst_send_payload_allocation( - stream->ctx, - stream, - true); - } - - /* increase throttled vcp size */ - pbn = get_pbn_from_bw_in_kbps(bw_in_kbps); - pbn_per_slot = get_pbn_per_slot(stream); - avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); - - stream_encoder->funcs->set_throttled_vcp_size( - stream_encoder, - avg_time_slots_per_mtp); - - return DC_OK; -} -#endif - static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) { struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; - struct link_encoder *link_encoder = NULL; + struct link_encoder *link_encoder = link->link_enc; struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_link_encoder *hpo_dp_link_encoder = pipe_ctx->link_res.hpo_dp_link_enc; - struct hpo_dp_stream_encoder *hpo_dp_stream_encoder = pipe_ctx->stream_res.hpo_dp_stream_enc; -#endif struct dp_mst_stream_allocation_table proposed_table = {0}; struct fixed31_32 avg_time_slots_per_mtp = dc_fixpt_from_int(0); - int i; + uint8_t i; bool mst_mode = (link->type == dc_connection_mst_branch); DC_LOGGER_INIT(link->ctx->logger); - /* Link encoder may have been dynamically assigned to non-physical display endpoint. */ - if (link->ep_type == DISPLAY_ENDPOINT_PHY) - link_encoder = link->link_enc; - else if (link->dc->res_pool->funcs->link_encs_assign) - link_encoder = link_enc_cfg_get_link_enc_used_by_stream(pipe_ctx->stream->ctx->dc, stream); - ASSERT(link_encoder); - /* deallocate_mst_payload is called before disable link. When mode or * disable/enable monitor, new stream is created which is not in link * stream[] yet. For this, payload is not allocated yet, so de-alloc @@ -3834,28 +3137,9 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) */ /* slot X.Y */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - switch (dp_get_link_encoding_format(&link->cur_link_settings)) { - case DP_8b_10b_ENCODING: - stream_encoder->funcs->set_throttled_vcp_size( - stream_encoder, - avg_time_slots_per_mtp); - break; - case DP_128b_132b_ENCODING: - hpo_dp_link_encoder->funcs->set_throttled_vcp_size( - hpo_dp_link_encoder, - hpo_dp_stream_encoder->inst, - avg_time_slots_per_mtp); - break; - case DP_UNKNOWN_ENCODING: - DC_LOG_ERROR("Failure: unknown encoding format\n"); - return DC_ERROR_UNEXPECTED; - } -#else stream_encoder->funcs->set_throttled_vcp_size( stream_encoder, avg_time_slots_per_mtp); -#endif /* TODO: which component is responsible for remove payload table? */ if (mst_mode) { @@ -3865,16 +3149,8 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) &proposed_table, false)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - update_mst_stream_alloc_table( - link, - pipe_ctx->stream_res.stream_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc, - &proposed_table); -#else update_mst_stream_alloc_table( link, pipe_ctx->stream_res.stream_enc, &proposed_table); -#endif } else { DC_LOG_WARNING("Failed to update" @@ -3890,20 +3166,6 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) link->mst_stream_alloc_table.stream_count); for (i = 0; i < MAX_CONTROLLER_NUM; i++) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - DC_LOG_MST("stream_enc[%d]: %p " - "stream[%d].hpo_dp_stream_enc: %p " - "stream[%d].vcp_id: %d " - "stream[%d].slot_count: %d\n", - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].stream_enc, - i, - (void *) link->mst_stream_alloc_table.stream_allocations[i].hpo_dp_stream_enc, - i, - link->mst_stream_alloc_table.stream_allocations[i].vcp_id, - i, - link->mst_stream_alloc_table.stream_allocations[i].slot_count); -#else DC_LOG_MST("stream_enc[%d]: %p " "stream[%d].vcp_id: %d " "stream[%d].slot_count: %d\n", @@ -3913,44 +3175,11 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) link->mst_stream_alloc_table.stream_allocations[i].vcp_id, i, link->mst_stream_alloc_table.stream_allocations[i].slot_count); -#endif } - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { - enum dc_status status; - uint8_t mst_alloc_slots = 0, prev_mst_slots_in_use = 0xFF; - - for (i = 0; i < link->mst_stream_alloc_table.stream_count; i++) - mst_alloc_slots += link->mst_stream_alloc_table.stream_allocations[i].slot_count; - - status = dc_process_dmub_set_mst_slots(link->dc, link->link_index, - mst_alloc_slots, &prev_mst_slots_in_use); - ASSERT(status != DC_NOT_SUPPORTED); - DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n", - status, mst_alloc_slots, prev_mst_slots_in_use); - } - -#if defined(CONFIG_DRM_AMD_DC_DCN) - switch (dp_get_link_encoding_format(&link->cur_link_settings)) { - case DP_8b_10b_ENCODING: - link_encoder->funcs->update_mst_stream_allocation_table( - link_encoder, - &link->mst_stream_alloc_table); - break; - case DP_128b_132b_ENCODING: - hpo_dp_link_encoder->funcs->update_stream_allocation_table( - hpo_dp_link_encoder, - &link->mst_stream_alloc_table); - break; - case DP_UNKNOWN_ENCODING: - DC_LOG_ERROR("Failure: unknown encoding format\n"); - return DC_ERROR_UNEXPECTED; - } -#else link_encoder->funcs->update_mst_stream_allocation_table( link_encoder, &link->mst_stream_alloc_table); -#endif if (mst_mode) { dm_helpers_dp_mst_poll_for_allocation_change_trigger( @@ -3971,155 +3200,27 @@ static enum dc_status deallocate_mst_payload(struct pipe_ctx *pipe_ctx) static void update_psp_stream_config(struct pipe_ctx *pipe_ctx, bool dpms_off) { struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp; - struct link_encoder *link_enc = NULL; - struct cp_psp_stream_config config = {0}; - enum dp_panel_mode panel_mode = - dp_get_panel_mode(pipe_ctx->stream->link); + if (cp_psp && cp_psp->funcs.update_stream_config) { + struct cp_psp_stream_config config = {0}; + enum dp_panel_mode panel_mode = + dp_get_panel_mode(pipe_ctx->stream->link); - if (cp_psp == NULL || cp_psp->funcs.update_stream_config == NULL) - return; - - if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_PHY) - link_enc = pipe_ctx->stream->link->link_enc; - else if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && - pipe_ctx->stream->link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_stream( - pipe_ctx->stream->ctx->dc, - pipe_ctx->stream); - ASSERT(link_enc); - if (link_enc == NULL) - return; - - /* otg instance */ - config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst; - - /* dig front end */ - config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst; - - /* stream encoder index */ - config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA; + config.otg_inst = (uint8_t) pipe_ctx->stream_res.tg->inst; + /*stream_enc_inst*/ + config.dig_fe = (uint8_t) pipe_ctx->stream_res.stream_enc->stream_enc_inst; + config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst; #if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - config.stream_enc_idx = - pipe_ctx->stream_res.hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0; + config.stream_enc_idx = pipe_ctx->stream_res.stream_enc->id - ENGINE_ID_DIGA; + config.link_enc_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A; + config.phy_idx = pipe_ctx->stream->link->link_enc->transmitter - TRANSMITTER_UNIPHY_A; #endif - - /* dig back end */ - config.dig_be = pipe_ctx->stream->link->link_enc_hw_inst; - - /* link encoder index */ - config.link_enc_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - config.link_enc_idx = pipe_ctx->link_res.hpo_dp_link_enc->inst; -#endif - /* dio output index */ - config.dio_output_idx = link_enc->transmitter - TRANSMITTER_UNIPHY_A; - - /* phy index */ - config.phy_idx = resource_transmitter_to_phy_idx( - pipe_ctx->stream->link->dc, link_enc->transmitter); - if (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) - /* USB4 DPIA doesn't use PHY in our soc, initialize it to 0 */ - config.phy_idx = 0; - - /* stream properties */ - config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP) ? 1 : 0; - config.mst_enabled = (pipe_ctx->stream->signal == - SIGNAL_TYPE_DISPLAY_PORT_MST) ? 1 : 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) - config.dp2_enabled = is_dp_128b_132b_signal(pipe_ctx) ? 1 : 0; -#endif - config.usb4_enabled = (pipe_ctx->stream->link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ? - 1 : 0; - config.dpms_off = dpms_off; - - /* dm stream context */ - config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context; - - cp_psp->funcs.update_stream_config(cp_psp->handle, &config); -} -#endif - -#if defined(CONFIG_DRM_AMD_DC_DCN) -static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pipe_ctx *pipe_ctx) -{ - struct dc *dc = pipe_ctx->stream->ctx->dc; - struct dc_stream_state *stream = pipe_ctx->stream; - struct link_mst_stream_allocation_table proposed_table = {0}; - struct fixed31_32 avg_time_slots_per_mtp; - uint8_t req_slot_count = 0; - uint8_t vc_id = 1; /// VC ID always 1 for SST - - struct dc_link_settings link_settings = {0}; - DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); - - decide_link_settings(stream, &link_settings); - stream->link->cur_link_settings = link_settings; - - /* Enable clock, Configure lane count, and Enable Link Encoder*/ - enable_dp_hpo_output(stream->link, &pipe_ctx->link_res, &stream->link->cur_link_settings); - -#ifdef DIAGS_BUILD - /* Workaround for FPGA HPO capture DP link data: - * HPO capture will set link to active mode - * This workaround is required to get a capture from start of frame - */ - if (!dc->debug.fpga_hpo_capture_en) { - struct encoder_set_dp_phy_pattern_param params = {0}; - params.dp_phy_pattern = DP_TEST_PATTERN_VIDEO_MODE; - - /* Set link active */ - stream->link->hpo_dp_link_enc->funcs->set_link_test_pattern( - stream->link->hpo_dp_link_enc, - ¶ms); + config.dpms_off = dpms_off; + config.dm_stream_ctx = pipe_ctx->stream->dm_stream_context; + config.assr_enabled = (panel_mode == DP_PANEL_MODE_EDP); + config.mst_enabled = (pipe_ctx->stream->signal == + SIGNAL_TYPE_DISPLAY_PORT_MST); + cp_psp->funcs.update_stream_config(cp_psp->handle, &config); } -#endif - - /* Enable DP_STREAM_ENC */ - dc->hwss.enable_stream(pipe_ctx); - - /* Set DPS PPS SDP (AKA "info frames") */ - if (pipe_ctx->stream->timing.flags.DSC) { - dp_set_dsc_pps_sdp(pipe_ctx, true, true); - } - - /* Allocate Payload */ - if ((stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) && (state->stream_count > 1)) { - // MST case - uint8_t i; - - proposed_table.stream_count = state->stream_count; - for (i = 0; i < state->stream_count; i++) { - avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(state->streams[i], state->streams[i]->link); - req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp); - proposed_table.stream_allocations[i].slot_count = req_slot_count; - proposed_table.stream_allocations[i].vcp_id = i+1; - /* NOTE: This makes assumption that pipe_ctx index is same as stream index */ - proposed_table.stream_allocations[i].hpo_dp_stream_enc = state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc; - } - } else { - // SST case - avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, stream->link); - req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp); - proposed_table.stream_count = 1; /// Always 1 stream for SST - proposed_table.stream_allocations[0].slot_count = req_slot_count; - proposed_table.stream_allocations[0].vcp_id = vc_id; - proposed_table.stream_allocations[0].hpo_dp_stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; - } - - pipe_ctx->link_res.hpo_dp_link_enc->funcs->update_stream_allocation_table( - pipe_ctx->link_res.hpo_dp_link_enc, - &proposed_table); - - pipe_ctx->link_res.hpo_dp_link_enc->funcs->set_throttled_vcp_size( - pipe_ctx->link_res.hpo_dp_link_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc->inst, - avg_time_slots_per_mtp); - - - - dc->hwss.unblank_stream(pipe_ctx, &stream->link->cur_link_settings); } #endif @@ -4129,15 +3230,9 @@ void core_link_enable_stream( { struct dc *dc = pipe_ctx->stream->ctx->dc; struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->sink->link; enum dc_status status; - struct link_encoder *link_enc; #if defined(CONFIG_DRM_AMD_DC_DCN) enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; - struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; - - if (is_dp_128b_132b_signal(pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; #endif DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); @@ -4145,57 +3240,23 @@ void core_link_enable_stream( dc_is_virtual_signal(pipe_ctx->stream->signal)) return; - if (dc->res_pool->funcs->link_encs_assign && stream->link->ep_type != DISPLAY_ENDPOINT_PHY) - link_enc = link_enc_cfg_get_link_enc_used_by_stream(dc, stream); - else - link_enc = stream->link->link_enc; - ASSERT(link_enc); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (!dc_is_virtual_signal(pipe_ctx->stream->signal) - && !is_dp_128b_132b_signal(pipe_ctx)) { -#else if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) { -#endif - if (link_enc) - link_enc->funcs->setup( - link_enc, - pipe_ctx->stream->signal); + stream->link->link_enc->funcs->setup( + stream->link->link_enc, + pipe_ctx->stream->signal); pipe_ctx->stream_res.stream_enc->funcs->setup_stereo_sync( pipe_ctx->stream_res.stream_enc, pipe_ctx->stream_res.tg->inst, stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->set_stream_attribute( - pipe_ctx->stream_res.hpo_dp_stream_enc, - &stream->timing, - stream->output_color_space, - stream->use_vsc_sdp_for_colorimetry, - stream->timing.flags.DSC, - false); - otg_out_dest = OUT_MUX_HPO_DP; - } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { + if (dc_is_dp_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( - pipe_ctx->stream_res.stream_enc, - &stream->timing, - stream->output_color_space, - stream->use_vsc_sdp_for_colorimetry, - stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP); - } -#else - pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute( pipe_ctx->stream_res.stream_enc, &stream->timing, stream->output_color_space, stream->use_vsc_sdp_for_colorimetry, stream->link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP); -#endif - - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR); if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->hdmi_set_stream_attribute( @@ -4229,18 +3290,9 @@ void core_link_enable_stream( pipe_ctx->stream->apply_edp_fast_boot_optimization = false; -#if defined(CONFIG_DRM_AMD_DC_DCN) - // Enable VPG before building infoframe - if (vpg && vpg->funcs->vpg_poweron) - vpg->funcs->vpg_poweron(vpg); -#endif - resource_build_info_frame(pipe_ctx); dc->hwss.update_info_frame(pipe_ctx); - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); - /* Do not touch link on seamless boot optimization. */ if (pipe_ctx->stream->apply_seamless_boot_optimization) { pipe_ctx->stream->dpms_off = false; @@ -4263,8 +3315,7 @@ void core_link_enable_stream( /* eDP lit up by bios already, no need to enable again. */ if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && apply_edp_fast_boot_optimization && - !pipe_ctx->stream->timing.flags.DSC && - !pipe_ctx->next_odm_pipe) { + !pipe_ctx->stream->timing.flags.DSC) { pipe_ctx->stream->dpms_off = false; #if defined(CONFIG_DRM_AMD_DC_HDCP) update_psp_stream_config(pipe_ctx, false); @@ -4301,9 +3352,6 @@ void core_link_enable_stream( */ if (status != DC_FAIL_DP_LINK_TRAINING || pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - if (false == stream->link->link_status.link_active) - disable_link(stream->link, &pipe_ctx->link_res, - pipe_ctx->stream->signal); BREAK_TO_DEBUGGER(); return; } @@ -4319,16 +3367,10 @@ void core_link_enable_stream( * as a workaround for the incorrect value being applied * from transmitter control. */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (!(dc_is_virtual_signal(pipe_ctx->stream->signal) || - is_dp_128b_132b_signal(pipe_ctx))) -#else if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) -#endif - if (link_enc) - link_enc->funcs->setup( - link_enc, - pipe_ctx->stream->signal); + stream->link->link_enc->funcs->setup( + stream->link->link_enc, + pipe_ctx->stream->signal); dc->hwss.enable_stream(pipe_ctx); @@ -4337,17 +3379,12 @@ void core_link_enable_stream( if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) { dp_set_dsc_on_rx(pipe_ctx, true); - dp_set_dsc_pps_sdp(pipe_ctx, true, true); + dp_set_dsc_pps_sdp(pipe_ctx, true); } } if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) dc_link_allocate_mst_payload(pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - is_dp_128b_132b_signal(pipe_ctx)) - dc_link_update_sst_payload(pipe_ctx, true); -#endif dc->hwss.unblank_stream(pipe_ctx, &pipe_ctx->stream->link->cur_link_settings); @@ -4364,11 +3401,6 @@ void core_link_enable_stream( dc->hwss.enable_audio_stream(pipe_ctx); } else { // if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - fpga_dp_hpo_enable_link_and_stream(state, pipe_ctx); - } -#endif if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) dp_set_dsc_enable(pipe_ctx, true); @@ -4385,12 +3417,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) struct dc *dc = pipe_ctx->stream->ctx->dc; struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->sink->link; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct vpg *vpg = pipe_ctx->stream_res.stream_enc->vpg; - - if (is_dp_128b_132b_signal(pipe_ctx)) - vpg = pipe_ctx->stream_res.hpo_dp_stream_enc->vpg; -#endif if (!IS_DIAG_DC(dc->ctx->dce_environment) && dc_is_virtual_signal(pipe_ctx->stream->signal)) @@ -4410,11 +3436,6 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - is_dp_128b_132b_signal(pipe_ctx)) - dc_link_update_sst_payload(pipe_ctx, false); -#endif if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { struct ext_hdmi_settings settings = {0}; @@ -4441,44 +3462,14 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) } } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT && - !is_dp_128b_132b_signal(pipe_ctx)) { - - /* In DP1.x SST mode, our encoder will go to TPS1 - * when link is on but stream is off. - * Disabling link before stream will avoid exposing TPS1 pattern - * during the disable sequence as it will confuse some receivers - * state machine. - * In DP2 or MST mode, our encoder will stay video active - */ - disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); - dc->hwss.disable_stream(pipe_ctx); - } else { - dc->hwss.disable_stream(pipe_ctx); - disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); - } -#else - disable_link(pipe_ctx->stream->link, &pipe_ctx->link_res, pipe_ctx->stream->signal); + disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); dc->hwss.disable_stream(pipe_ctx); -#endif if (pipe_ctx->stream->timing.flags.DSC) { if (dc_is_dp_signal(pipe_ctx->stream->signal)) dp_set_dsc_enable(pipe_ctx, false); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - if (pipe_ctx->stream_res.tg->funcs->set_out_mux) - pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO); - } -#endif - -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (vpg && vpg->funcs->vpg_powerdown) - vpg->funcs->vpg_powerdown(vpg); -#endif } void core_link_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) @@ -4542,22 +3533,16 @@ void dc_link_set_drive_settings(struct dc *dc, { int i; - struct pipe_ctx *pipe = NULL; - const struct link_resource *link_res; - link_res = dc_link_get_cur_link_res(link); - - for (i = 0; i < MAX_PIPES; i++) { - pipe = &dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe->stream && pipe->stream->link) { - if (pipe->stream->link == link) - break; - } + for (i = 0; i < dc->link_count; i++) { + if (dc->links[i] == link) + break; } - if (pipe && link_res) - dc_link_dp_set_drive_settings(pipe->stream->link, link_res, lt_settings); - else + + if (i >= dc->link_count) ASSERT_CRITICAL(false); + + dc_link_dp_set_drive_settings(dc->links[i], lt_settings); } void dc_link_set_preferred_link_settings(struct dc *dc, @@ -4617,11 +3602,6 @@ void dc_link_set_preferred_training_settings(struct dc *dc, if (link_setting != NULL) { link->preferred_link_setting = *link_setting; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(link_setting) == DP_128b_132b_ENCODING) - /* TODO: add dc update for acquiring link res */ - skip_immediate_retrain = true; -#endif } else { link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN; link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN; @@ -4663,38 +3643,6 @@ uint32_t dc_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_setting) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint32_t total_data_bw_efficiency_x10000 = 0; - uint32_t link_rate_per_lane_kbps = 0; - - switch (dp_get_link_encoding_format(link_setting)) { - case DP_8b_10b_ENCODING: - /* For 8b/10b encoding: - * link rate is defined in the unit of LINK_RATE_REF_FREQ_IN_KHZ per DP byte per lane. - * data bandwidth efficiency is 80% with additional 3% overhead if FEC is supported. - */ - link_rate_per_lane_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE; - total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000; - if (dc_link_should_enable_fec(link)) { - total_data_bw_efficiency_x10000 /= 100; - total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100; - } - break; - case DP_128b_132b_ENCODING: - /* For 128b/132b encoding: - * link rate is defined in the unit of 10mbps per lane. - * total data bandwidth efficiency is always 96.71%. - */ - link_rate_per_lane_kbps = link_setting->link_rate * 10000; - total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000; - break; - default: - break; - } - - /* overall effective link bandwidth = link rate per lane * lane count * total data bandwidth efficiency */ - return link_rate_per_lane_kbps * link_setting->lane_count / 10000 * total_data_bw_efficiency_x10000; -#else uint32_t link_bw_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */ @@ -4725,9 +3673,9 @@ uint32_t dc_link_bandwidth_kbps( long long fec_link_bw_kbps = link_bw_kbps * 970LL; link_bw_kbps = (uint32_t)(div64_s64(fec_link_bw_kbps, 1000LL)); } + return link_bw_kbps; -#endif } const struct dc_link_settings *dc_link_get_link_cap( @@ -4747,9 +3695,6 @@ void dc_link_overwrite_extended_receiver_cap( bool dc_link_is_fec_supported(const struct dc_link *link) { - /* TODO - use asic cap instead of link_enc->features - * we no longer know which link enc to use for this link before commit - */ struct link_encoder *link_enc = NULL; /* Links supporting dynamically assigned link encoder will be assigned next @@ -4757,14 +3702,14 @@ bool dc_link_is_fec_supported(const struct dc_link *link) */ if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) { - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); if (link_enc == NULL) - link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc); + link_enc = link_enc_cfg_get_next_avail_link_enc(link->dc, link->dc->current_state); } else link_enc = link->link_enc; ASSERT(link_enc); - return (dc_is_dp_signal(link->connector_signal) && link_enc && + return (dc_is_dp_signal(link->connector_signal) && link_enc->features.fec_supported && link->dpcd_caps.fec_cap.bits.FEC_CAPABLE && !IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment)); @@ -4778,10 +3723,8 @@ bool dc_link_should_enable_fec(const struct dc_link *link) if ((link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT_MST && link->local_sink && link->local_sink->edid_caps.panel_patch.disable_fec) || - (link->connector_signal == SIGNAL_TYPE_EDP - // enable FEC for EDP if DSC is supported - && link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT == false - )) + (link->connector_signal == SIGNAL_TYPE_EDP && + link->dc->debug.force_enable_edp_fec == false)) // Disable FEC for eDP is_fec_disable = true; if (dc_link_is_fec_supported(link) && !link->dc->debug.disable_fec && !is_fec_disable) @@ -4802,7 +3745,7 @@ uint32_t dc_bandwidth_in_kbps_from_timing( timing->dsc_cfg.bits_per_pixel, timing->dsc_cfg.num_slices_h, timing->dsc_cfg.is_dp); -#endif /* CONFIG_DRM_AMD_DC_DCN */ +#endif switch (timing->display_color_depth) { case COLOR_DEPTH_666: @@ -4844,125 +3787,3 @@ uint32_t dc_bandwidth_in_kbps_from_timing( return kbps; } - -const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link) -{ - int i; - struct pipe_ctx *pipe = NULL; - const struct link_resource *link_res = NULL; - - for (i = 0; i < MAX_PIPES; i++) { - pipe = &link->dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe->stream && pipe->stream->link && pipe->top_pipe == NULL) { - if (pipe->stream->link == link) { - link_res = &pipe->link_res; - break; - } - } - } - - return link_res; -} - -/** - * dc_get_cur_link_res_map() - take a snapshot of current link resource allocation state - * @dc: pointer to dc of the dm calling this - * @map: a dc link resource snapshot defined internally to dc. - * - * DM needs to capture a snapshot of current link resource allocation mapping - * and store it in its persistent storage. - * - * Some of the link resource is using first come first serve policy. - * The allocation mapping depends on original hotplug order. This information - * is lost after driver is loaded next time. The snapshot is used in order to - * restore link resource to its previous state so user will get consistent - * link capability allocation across reboot. - * - * Return: none (void function) - * - */ -void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map) -{ -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dc_link *link; - uint8_t i; - uint32_t hpo_dp_recycle_map = 0; - - *map = 0; - - if (dc->caps.dp_hpo) { - for (i = 0; i < dc->caps.max_links; i++) { - link = dc->links[i]; - if (link->link_status.link_active && - dp_get_link_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING && - dp_get_link_encoding_format(&link->cur_link_settings) != DP_128b_132b_ENCODING) - /* hpo dp link encoder is considered as recycled, when RX reports 128b/132b encoding capability - * but current link doesn't use it. - */ - hpo_dp_recycle_map |= (1 << i); - } - *map |= (hpo_dp_recycle_map << LINK_RES_HPO_DP_REC_MAP__SHIFT); - } -#endif -} - -/** - * dc_restore_link_res_map() - restore link resource allocation state from a snapshot - * @dc: pointer to dc of the dm calling this - * @map: a dc link resource snapshot defined internally to dc. - * - * DM needs to call this function after initial link detection on boot and - * before first commit streams to restore link resource allocation state - * from previous boot session. - * - * Some of the link resource is using first come first serve policy. - * The allocation mapping depends on original hotplug order. This information - * is lost after driver is loaded next time. The snapshot is used in order to - * restore link resource to its previous state so user will get consistent - * link capability allocation across reboot. - * - * Return: none (void function) - * - */ -void dc_restore_link_res_map(const struct dc *dc, uint32_t *map) -{ -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dc_link *link; - uint8_t i; - unsigned int available_hpo_dp_count; - uint32_t hpo_dp_recycle_map = (*map & LINK_RES_HPO_DP_REC_MAP__MASK) - >> LINK_RES_HPO_DP_REC_MAP__SHIFT; - - if (dc->caps.dp_hpo) { - available_hpo_dp_count = dc->res_pool->hpo_dp_link_enc_count; - /* remove excess 128b/132b encoding support for not recycled links */ - for (i = 0; i < dc->caps.max_links; i++) { - if ((hpo_dp_recycle_map & (1 << i)) == 0) { - link = dc->links[i]; - if (link->type != dc_connection_none && - dp_get_link_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) { - if (available_hpo_dp_count > 0) - available_hpo_dp_count--; - else - /* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */ - link->verified_link_cap.link_rate = LINK_RATE_HIGH3; - } - } - } - /* remove excess 128b/132b encoding support for recycled links */ - for (i = 0; i < dc->caps.max_links; i++) { - if ((hpo_dp_recycle_map & (1 << i)) != 0) { - link = dc->links[i]; - if (link->type != dc_connection_none && - dp_get_link_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) { - if (available_hpo_dp_count > 0) - available_hpo_dp_count--; - else - /* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */ - link->verified_link_cap.link_rate = LINK_RATE_HIGH3; - } - } - } - } -#endif -} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 24dc662ec3..ba6b56f202 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -196,8 +196,7 @@ static void ddc_service_construct( ddc_service->link = init_data->link; ddc_service->ctx = init_data->ctx; - if (init_data->is_dpia_link || - dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) { + if (BP_RESULT_OK != dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info)) { ddc_service->ddc_pin = NULL; } else { DC_LOGGER_INIT(ddc_service->ctx->logger); @@ -554,7 +553,6 @@ bool dal_ddc_service_query_ddc_data( payload.address = address; payload.reply = NULL; payload.defer_delay = get_defer_delay(ddc); - payload.write_status_update = false; if (write_size != 0) { payload.write = true; @@ -626,24 +624,24 @@ bool dal_ddc_submit_aux_command(struct ddc_service *ddc, do { struct aux_payload current_payload; bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >= - payload->length; - uint32_t payload_length = is_end_of_payload ? - payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE; + payload->length; current_payload.address = payload->address; current_payload.data = &payload->data[retrieved]; current_payload.defer_delay = payload->defer_delay; current_payload.i2c_over_aux = payload->i2c_over_aux; - current_payload.length = payload_length; - /* set mot (middle of transaction) to false if it is the last payload */ + current_payload.length = is_end_of_payload ? + payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE; + /* set mot (middle of transaction) to false + * if it is the last payload + */ current_payload.mot = is_end_of_payload ? payload->mot:true; - current_payload.write_status_update = false; current_payload.reply = payload->reply; current_payload.write = payload->write; ret = dc_link_aux_transfer_with_retries(ddc, ¤t_payload); - retrieved += payload_length; + retrieved += current_payload.length; } while (retrieved < payload->length && ret == true); return ret; @@ -660,12 +658,10 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, struct aux_payload *payload, enum aux_return_code_type *operation_result) { - if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc || - !ddc->ddc_pin) { + if (dc_enable_dmub_notifications(ddc->ctx->dc)) return dce_aux_transfer_dmub_raw(ddc, payload, operation_result); - } else { + else return dce_aux_transfer_raw(ddc, payload, operation_result); - } } /* dc_link_aux_transfer_with_retries() - Attempt to submit an @@ -764,7 +760,7 @@ void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service) dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset, sizeof(offset), &tmds_config, sizeof(tmds_config)); if (tmds_config & 0x1) { - union hdmi_scdc_status_flags_data status_data = {0}; + union hdmi_scdc_status_flags_data status_data = { {0} }; uint8_t scramble_status = 0; offset = HDMI_SCDC_SCRAMBLER_STATUS; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 61b8f29a0c..605b96873d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -36,7 +36,6 @@ #include "dpcd_defs.h" #include "dc_dmub_srv.h" #include "dce/dmub_hw_lock_mgr.h" -#include "inc/dc_link_dpia.h" #include "inc/link_enc_cfg.h" /*Travis*/ @@ -62,82 +61,28 @@ enum { POST_LT_ADJ_REQ_TIMEOUT = 200 }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct dp_lt_fallback_entry { - enum dc_lane_count lane_count; - enum dc_link_rate link_rate; -}; - -static const struct dp_lt_fallback_entry dp_lt_fallbacks[] = { - /* This link training fallback array is ordered by - * link bandwidth from highest to lowest. - * DP specs makes it a normative policy to always - * choose the next highest link bandwidth during - * link training fallback. - */ - {LANE_COUNT_FOUR, LINK_RATE_UHBR20}, - {LANE_COUNT_FOUR, LINK_RATE_UHBR13_5}, - {LANE_COUNT_TWO, LINK_RATE_UHBR20}, - {LANE_COUNT_FOUR, LINK_RATE_UHBR10}, - {LANE_COUNT_TWO, LINK_RATE_UHBR13_5}, - {LANE_COUNT_FOUR, LINK_RATE_HIGH3}, - {LANE_COUNT_ONE, LINK_RATE_UHBR20}, - {LANE_COUNT_TWO, LINK_RATE_UHBR10}, - {LANE_COUNT_FOUR, LINK_RATE_HIGH2}, - {LANE_COUNT_ONE, LINK_RATE_UHBR13_5}, - {LANE_COUNT_TWO, LINK_RATE_HIGH3}, - {LANE_COUNT_ONE, LINK_RATE_UHBR10}, - {LANE_COUNT_TWO, LINK_RATE_HIGH2}, - {LANE_COUNT_FOUR, LINK_RATE_HIGH}, - {LANE_COUNT_ONE, LINK_RATE_HIGH3}, - {LANE_COUNT_FOUR, LINK_RATE_LOW}, - {LANE_COUNT_ONE, LINK_RATE_HIGH2}, - {LANE_COUNT_TWO, LINK_RATE_HIGH}, - {LANE_COUNT_TWO, LINK_RATE_LOW}, - {LANE_COUNT_ONE, LINK_RATE_HIGH}, - {LANE_COUNT_ONE, LINK_RATE_LOW}, -}; -#endif - static bool decide_fallback_link_setting( - struct dc_link *link, struct dc_link_settings initial_link_settings, struct dc_link_settings *current_link_setting, enum link_training_result training_result); static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_a, struct dc_link_settings link_setting_b); -static void maximize_lane_settings(const struct link_training_settings *lt_settings, - struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); -static void override_lane_settings(const struct link_training_settings *lt_settings, - struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link, const struct dc_link_settings *link_settings) { union training_aux_rd_interval training_rd_interval; uint32_t wait_in_micro_secs = 100; -#if defined(CONFIG_DRM_AMD_DC_DCN) + memset(&training_rd_interval, 0, sizeof(training_rd_interval)); - if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING && - link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { - core_link_read_dpcd( - link, - DP_TRAINING_AUX_RD_INTERVAL, - (uint8_t *)&training_rd_interval, - sizeof(training_rd_interval)); - if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) - wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000; - } -#else core_link_read_dpcd( link, DP_TRAINING_AUX_RD_INTERVAL, (uint8_t *)&training_rd_interval, sizeof(training_rd_interval)); if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) - wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000; -#endif + wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000; return wait_in_micro_secs; } @@ -145,36 +90,6 @@ static uint32_t get_eq_training_aux_rd_interval( struct dc_link *link, const struct dc_link_settings *link_settings) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - union training_aux_rd_interval training_rd_interval; - - memset(&training_rd_interval, 0, sizeof(training_rd_interval)); - if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { - core_link_read_dpcd( - link, - DP_128b_132b_TRAINING_AUX_RD_INTERVAL, - (uint8_t *)&training_rd_interval, - sizeof(training_rd_interval)); - } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING && - link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { - core_link_read_dpcd( - link, - DP_TRAINING_AUX_RD_INTERVAL, - (uint8_t *)&training_rd_interval, - sizeof(training_rd_interval)); - } - - switch (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) { - case 0: return 400; - case 1: return 4000; - case 2: return 8000; - case 3: return 12000; - case 4: return 16000; - case 5: return 32000; - case 6: return 64000; - default: return 400; - } -#else union training_aux_rd_interval training_rd_interval; uint32_t wait_in_micro_secs = 400; @@ -194,21 +109,13 @@ static uint32_t get_eq_training_aux_rd_interval( } return wait_in_micro_secs; -#endif } void dp_wait_for_training_aux_rd_interval( struct dc_link *link, uint32_t wait_in_micro_secs) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (wait_in_micro_secs > 1000) - msleep(wait_in_micro_secs/1000); - else - udelay(wait_in_micro_secs); -#else udelay(wait_in_micro_secs); -#endif DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n", __func__, @@ -236,17 +143,6 @@ enum dpcd_training_patterns case DP_TRAINING_PATTERN_SEQUENCE_4: dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_128b_132b_TPS1: - dpcd_tr_pattern = DPCD_128b_132b_TPS1; - break; - case DP_128b_132b_TPS2: - dpcd_tr_pattern = DPCD_128b_132b_TPS2; - break; - case DP_128b_132b_TPS2_CDS: - dpcd_tr_pattern = DPCD_128b_132b_TPS2_CDS; - break; -#endif case DP_TRAINING_PATTERN_VIDEOIDLE: dpcd_tr_pattern = DPCD_TRAINING_PATTERN_VIDEOIDLE; break; @@ -264,7 +160,7 @@ static void dpcd_set_training_pattern( struct dc_link *link, enum dc_dp_training_pattern training_pattern) { - union dpcd_training_pattern dpcd_pattern = {0}; + union dpcd_training_pattern dpcd_pattern = { {0} }; dpcd_pattern.v1_4.TRAINING_PATTERN_SET = dc_dp_training_pattern_to_dpcd_training_pattern( @@ -285,57 +181,13 @@ static void dpcd_set_training_pattern( static enum dc_dp_training_pattern decide_cr_training_pattern( const struct dc_link_settings *link_settings) { - switch (dp_get_link_encoding_format(link_settings)) { - case DP_8b_10b_ENCODING: - default: - return DP_TRAINING_PATTERN_SEQUENCE_1; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_128b_132b_ENCODING: - return DP_128b_132b_TPS1; -#endif - } + return DP_TRAINING_PATTERN_SEQUENCE_1; } static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link, const struct dc_link_settings *link_settings) { struct link_encoder *link_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct encoder_feature_support *enc_caps; - struct dpcd_caps *rx_caps = &link->dpcd_caps; - enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2; - - /* Access link encoder capability based on whether it is statically - * or dynamically assigned to a link. - */ - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); - else - link_enc = link->link_enc; - ASSERT(link_enc); - enc_caps = &link_enc->features; - - switch (dp_get_link_encoding_format(link_settings)) { - case DP_8b_10b_ENCODING: - if (enc_caps->flags.bits.IS_TPS4_CAPABLE && - rx_caps->max_down_spread.bits.TPS4_SUPPORTED) - pattern = DP_TRAINING_PATTERN_SEQUENCE_4; - else if (enc_caps->flags.bits.IS_TPS3_CAPABLE && - rx_caps->max_ln_count.bits.TPS3_SUPPORTED) - pattern = DP_TRAINING_PATTERN_SEQUENCE_3; - else - pattern = DP_TRAINING_PATTERN_SEQUENCE_2; - break; - case DP_128b_132b_ENCODING: - pattern = DP_128b_132b_TPS2; - break; - default: - pattern = DP_TRAINING_PATTERN_SEQUENCE_2; - break; - } - return pattern; -#else enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2; struct encoder_feature_support *features; struct dpcd_caps *dpcd_caps = &link->dpcd_caps; @@ -345,7 +197,7 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li */ if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); else link_enc = link->link_enc; ASSERT(link_enc); @@ -366,254 +218,6 @@ static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *li return DP_TRAINING_PATTERN_SEQUENCE_3; return DP_TRAINING_PATTERN_SEQUENCE_2; -#endif -} - -#if defined(CONFIG_DRM_AMD_DC_DCN) -static uint8_t get_dpcd_link_rate(const struct dc_link_settings *link_settings) -{ - uint8_t link_rate = 0; - enum dp_link_encoding encoding = dp_get_link_encoding_format(link_settings); - - if (encoding == DP_128b_132b_ENCODING) - switch (link_settings->link_rate) { - case LINK_RATE_UHBR10: - link_rate = 0x1; - break; - case LINK_RATE_UHBR20: - link_rate = 0x2; - break; - case LINK_RATE_UHBR13_5: - link_rate = 0x4; - break; - default: - link_rate = 0; - break; - } - else if (encoding == DP_8b_10b_ENCODING) - link_rate = (uint8_t) link_settings->link_rate; - else - link_rate = 0; - - return link_rate; -} -#endif - -static void vendor_specific_lttpr_wa_one_start(struct dc_link *link) -{ - const uint8_t vendor_lttpr_write_data[4] = {0x1, 0x50, 0x63, 0xff}; - const uint8_t offset = dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; - - if (offset != 0xFF) - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - - /* W/A for certain LTTPR to reset their lane settings, part one of two */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data[0], - sizeof(vendor_lttpr_write_data)); -} - -static void vendor_specific_lttpr_wa_one_end( - struct dc_link *link, - uint8_t retry_count) -{ - const uint8_t vendor_lttpr_write_data[4] = {0x1, 0x50, 0x63, 0x0}; - const uint8_t offset = dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; - - if (!retry_count) { - if (offset != 0xFF) - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - - /* W/A for certain LTTPR to reset their lane settings, part two of two */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data[0], - sizeof(vendor_lttpr_write_data)); - } -} - -static void vendor_specific_lttpr_wa_one_two( - struct dc_link *link, - const uint8_t rate) -{ - if (link->apply_vendor_specific_lttpr_link_rate_wa) { - uint8_t toggle_rate = 0x0; - - if (rate == 0x6) - toggle_rate = 0xA; - else - toggle_rate = 0x6; - - if (link->vendor_specific_lttpr_link_rate_wa == rate) { - /* W/A for certain LTTPR to reset internal state for link training */ - core_link_write_dpcd( - link, - DP_LINK_BW_SET, - &toggle_rate, - 1); - } - - /* Store the last attempted link rate for this link */ - link->vendor_specific_lttpr_link_rate_wa = rate; - } -} - -static void vendor_specific_lttpr_wa_three( - struct dc_link *link, - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX]) -{ - const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63}; - const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63}; - const uint8_t offset = dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; - uint32_t vendor_lttpr_read_address = 0xF0053; - uint8_t dprx_vs = 0; - uint8_t dprx_pe = 0; - uint8_t lane; - - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - vendor_lttpr_read_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - - /* W/A to read lane settings requested by DPRX */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_vs, - 1); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_pe, - 1); - - for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { - dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE = (dprx_vs >> (2 * lane)) & 0x3; - dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE = (dprx_pe >> (2 * lane)) & 0x3; - } -} - -static void vendor_specific_lttpr_wa_three_dpcd( - struct dc_link *link, - union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX]) -{ - union lane_adjust lane_adjust[LANE_COUNT_DP_MAX]; - uint8_t lane = 0; - - vendor_specific_lttpr_wa_three(link, lane_adjust); - - for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { - dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = lane_adjust[lane].bits.VOLTAGE_SWING_LANE; - dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET = lane_adjust[lane].bits.PRE_EMPHASIS_LANE; - } -} - -static void vendor_specific_lttpr_wa_four( - struct dc_link *link, - bool apply_wa) -{ - const uint8_t vendor_lttpr_write_data_one[4] = {0x1, 0x55, 0x63, 0x8}; - const uint8_t vendor_lttpr_write_data_two[4] = {0x1, 0x55, 0x63, 0x0}; - const uint8_t offset = dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; -#if defined(CONFIG_DRM_AMD_DC_DP2_0) - uint8_t sink_status = 0; - uint8_t i; -#endif - - if (offset != 0xFF) - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - - /* W/A to pass through DPCD write of TPS=0 to DPRX */ - if (apply_wa) { - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_one[0], - sizeof(vendor_lttpr_write_data_one)); - } - - /* clear training pattern set */ - dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE); - - if (apply_wa) { - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_two[0], - sizeof(vendor_lttpr_write_data_two)); - } - -#if defined(CONFIG_DRM_AMD_DC_DP2_0) - /* poll for intra-hop disable */ - for (i = 0; i < 10; i++) { - if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) && - (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0) - break; - udelay(1000); - } -#endif -} - -static void vendor_specific_lttpr_wa_five( - struct dc_link *link, - const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX], - uint8_t lane_count) -{ - const uint32_t vendor_lttpr_write_address = 0xF004F; - const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; - uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; - uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; - uint8_t lane = 0; - - for (lane = 0; lane < lane_count; lane++) { - vendor_lttpr_write_data_vs[3] |= - dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane); - vendor_lttpr_write_data_pe[3] |= - dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET << (2 * lane); - } - - /* Force LTTPR to output desired VS and PE */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); } enum dc_status dpcd_set_link_settings( @@ -623,8 +227,8 @@ enum dc_status dpcd_set_link_settings( uint8_t rate; enum dc_status status; - union down_spread_ctrl downspread = {0}; - union lane_count_set lane_count_set = {0}; + union down_spread_ctrl downspread = { {0} }; + union lane_count_set lane_count_set = { {0} }; downspread.raw = (uint8_t) (lt_settings->link_settings.link_spread); @@ -648,7 +252,7 @@ enum dc_status dpcd_set_link_settings( status = core_link_write_dpcd(link, DP_LANE_COUNT_SET, &lane_count_set.raw, 1); - if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 && + if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && lt_settings->link_settings.use_link_rate_set == true) { rate = 0; /* WA for some MUX chips that will power down with eDP and lose supported @@ -665,20 +269,7 @@ enum dc_status dpcd_set_link_settings( status = core_link_write_dpcd(link, DP_LINK_RATE_SET, <_settings->link_settings.link_rate_set, 1); } else { -#if defined(CONFIG_DRM_AMD_DC_DCN) - rate = get_dpcd_link_rate(<_settings->link_settings); -#else rate = (uint8_t) (lt_settings->link_settings.link_rate); -#endif - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) - vendor_specific_lttpr_wa_one_start(link); - - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) - vendor_specific_lttpr_wa_one_two(link, rate); - status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); } @@ -720,10 +311,6 @@ uint8_t dc_dp_initialize_scrambling_data_symbols( disable_scrabled_data_symbols = 1; break; case DP_TRAINING_PATTERN_SEQUENCE_4: -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_128b_132b_TPS1: - case DP_128b_132b_TPS2: -#endif disable_scrabled_data_symbols = 0; break; default: @@ -746,10 +333,13 @@ static void dpcd_set_lt_pattern_and_lane_settings( enum dc_dp_training_pattern pattern, uint32_t offset) { + union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } }; + uint32_t dpcd_base_lt_offset; uint8_t dpcd_lt_buffer[5] = {0}; - union dpcd_training_pattern dpcd_pattern = { 0 }; + union dpcd_training_pattern dpcd_pattern = { {0} }; + uint32_t lane; uint32_t size_in_bytes; bool edp_workaround = false; /* TODO link_prop.INTERNAL */ dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET; @@ -782,57 +372,53 @@ static void dpcd_set_lt_pattern_and_lane_settings( dpcd_base_lt_offset, dpcd_pattern.v1_4.TRAINING_PATTERN_SET); } + /***************************************************************** + * DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set + *****************************************************************/ + for (lane = 0; lane < + (uint32_t)(lt_settings->link_settings.lane_count); lane++) { + + dpcd_lane[lane].bits.VOLTAGE_SWING_SET = + (uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING); + dpcd_lane[lane].bits.PRE_EMPHASIS_SET = + (uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS); + + dpcd_lane[lane].bits.MAX_SWING_REACHED = + (lt_settings->lane_settings[lane].VOLTAGE_SWING == + VOLTAGE_SWING_MAX_LEVEL ? 1 : 0); + dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED = + (lt_settings->lane_settings[lane].PRE_EMPHASIS == + PRE_EMPHASIS_MAX_LEVEL ? 1 : 0); + } /* concatenate everything into one buffer*/ - size_in_bytes = lt_settings->link_settings.lane_count * - sizeof(lt_settings->dpcd_lane_settings[0]); + + size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]); // 0x00103 - 0x00102 memmove( &dpcd_lt_buffer[DP_TRAINING_LANE0_SET - DP_TRAINING_PATTERN_SET], - lt_settings->dpcd_lane_settings, + dpcd_lane, size_in_bytes); if (is_repeater(link, offset)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_128b_132b_ENCODING) - DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n" - " 0x%X TX_FFE_PRESET_VALUE = %x\n", - __func__, - offset, - dpcd_base_lt_offset, - lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE); - else if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING) -#endif DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n" " 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, offset, dpcd_base_lt_offset, - lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET, - lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET, - lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED, - lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED); + dpcd_lane[0].bits.VOLTAGE_SWING_SET, + dpcd_lane[0].bits.PRE_EMPHASIS_SET, + dpcd_lane[0].bits.MAX_SWING_REACHED, + dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED); } else { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_128b_132b_ENCODING) - DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n", - __func__, - dpcd_base_lt_offset, - lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE); - else if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING) -#endif DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, dpcd_base_lt_offset, - lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET, - lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET, - lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED, - lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED); + dpcd_lane[0].bits.VOLTAGE_SWING_SET, + dpcd_lane[0].bits.PRE_EMPHASIS_SET, + dpcd_lane[0].bits.MAX_SWING_REACHED, + dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED); } if (edp_workaround) { /* for eDP write in 2 parts because the 5-byte burst is @@ -847,18 +433,9 @@ static void dpcd_set_lt_pattern_and_lane_settings( core_link_write_dpcd( link, DP_TRAINING_LANE0_SET, - (uint8_t *)(lt_settings->dpcd_lane_settings), + (uint8_t *)(dpcd_lane), size_in_bytes); -#if defined(CONFIG_DRM_AMD_DC_DCN) - } else if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_128b_132b_ENCODING) { - core_link_write_dpcd( - link, - dpcd_base_lt_offset, - dpcd_lt_buffer, - sizeof(dpcd_lt_buffer)); -#endif } else /* write it all in (1 + number-of-lanes)-byte burst*/ core_link_write_dpcd( @@ -866,6 +443,8 @@ static void dpcd_set_lt_pattern_and_lane_settings( dpcd_base_lt_offset, dpcd_lt_buffer, size_in_bytes + sizeof(dpcd_pattern.raw)); + + link->cur_lane_setting = lt_settings->lane_settings[0]; } bool dp_is_cr_done(enum dc_lane_count ln_count, @@ -907,75 +486,27 @@ bool dp_is_interlane_aligned(union lane_align_status_updated align_status) return align_status.bits.INTERLANE_ALIGN_DONE == 1; } -void dp_hw_to_dpcd_lane_settings( - const struct link_training_settings *lt_settings, - const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) -{ - uint8_t lane = 0; - - for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { - if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING) { - dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET = - (uint8_t)(hw_lane_settings[lane].VOLTAGE_SWING); - dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET = - (uint8_t)(hw_lane_settings[lane].PRE_EMPHASIS); - dpcd_lane_settings[lane].bits.MAX_SWING_REACHED = - (hw_lane_settings[lane].VOLTAGE_SWING == - VOLTAGE_SWING_MAX_LEVEL ? 1 : 0); - dpcd_lane_settings[lane].bits.MAX_PRE_EMPHASIS_REACHED = - (hw_lane_settings[lane].PRE_EMPHASIS == - PRE_EMPHASIS_MAX_LEVEL ? 1 : 0); - } -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_128b_132b_ENCODING) { - dpcd_lane_settings[lane].tx_ffe.PRESET_VALUE = - hw_lane_settings[lane].FFE_PRESET.settings.level; - } -#endif - } -} - -void dp_decide_lane_settings( - const struct link_training_settings *lt_settings, - const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], - struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) +void dp_update_drive_settings( + struct link_training_settings *dest, + struct link_training_settings src) { uint32_t lane; + for (lane = 0; lane < src.link_settings.lane_count; lane++) { + if (dest->voltage_swing == NULL) + dest->lane_settings[lane].VOLTAGE_SWING = src.lane_settings[lane].VOLTAGE_SWING; + else + dest->lane_settings[lane].VOLTAGE_SWING = *dest->voltage_swing; - for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { - if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING) { - hw_lane_settings[lane].VOLTAGE_SWING = - (enum dc_voltage_swing)(ln_adjust[lane].bits. - VOLTAGE_SWING_LANE); - hw_lane_settings[lane].PRE_EMPHASIS = - (enum dc_pre_emphasis)(ln_adjust[lane].bits. - PRE_EMPHASIS_LANE); - } -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (dp_get_link_encoding_format(<_settings->link_settings) == - DP_128b_132b_ENCODING) { - hw_lane_settings[lane].FFE_PRESET.raw = - ln_adjust[lane].tx_ffe.PRESET_VALUE; - } -#endif + if (dest->pre_emphasis == NULL) + dest->lane_settings[lane].PRE_EMPHASIS = src.lane_settings[lane].PRE_EMPHASIS; + else + dest->lane_settings[lane].PRE_EMPHASIS = *dest->pre_emphasis; + + if (dest->post_cursor2 == NULL) + dest->lane_settings[lane].POST_CURSOR2 = src.lane_settings[lane].POST_CURSOR2; + else + dest->lane_settings[lane].POST_CURSOR2 = *dest->post_cursor2; } - dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings); - - if (lt_settings->disallow_per_lane_settings) { - /* we find the maximum of the requested settings across all lanes*/ - /* and set this maximum for all lanes*/ - maximize_lane_settings(lt_settings, hw_lane_settings); - override_lane_settings(lt_settings, hw_lane_settings); - - if (lt_settings->always_match_dpcd_with_hw_lane_settings) - dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings); - } - } static uint8_t get_nibble_at_index(const uint8_t *buf, @@ -1005,31 +536,46 @@ static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing( } -static void maximize_lane_settings(const struct link_training_settings *lt_settings, - struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) +static void find_max_drive_settings( + const struct link_training_settings *link_training_setting, + struct link_training_settings *max_lt_setting) { uint32_t lane; struct dc_lane_settings max_requested; - max_requested.VOLTAGE_SWING = lane_settings[0].VOLTAGE_SWING; - max_requested.PRE_EMPHASIS = lane_settings[0].PRE_EMPHASIS; -#if defined(CONFIG_DRM_AMD_DC_DCN) - max_requested.FFE_PRESET = lane_settings[0].FFE_PRESET; -#endif + max_requested.VOLTAGE_SWING = + link_training_setting-> + lane_settings[0].VOLTAGE_SWING; + max_requested.PRE_EMPHASIS = + link_training_setting-> + lane_settings[0].PRE_EMPHASIS; + /*max_requested.postCursor2 = + * link_training_setting->laneSettings[0].postCursor2;*/ /* Determine what the maximum of the requested settings are*/ - for (lane = 1; lane < lt_settings->link_settings.lane_count; lane++) { - if (lane_settings[lane].VOLTAGE_SWING > max_requested.VOLTAGE_SWING) - max_requested.VOLTAGE_SWING = lane_settings[lane].VOLTAGE_SWING; + for (lane = 1; lane < link_training_setting->link_settings.lane_count; + lane++) { + if (link_training_setting->lane_settings[lane].VOLTAGE_SWING > + max_requested.VOLTAGE_SWING) - if (lane_settings[lane].PRE_EMPHASIS > max_requested.PRE_EMPHASIS) - max_requested.PRE_EMPHASIS = lane_settings[lane].PRE_EMPHASIS; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (lane_settings[lane].FFE_PRESET.settings.level > - max_requested.FFE_PRESET.settings.level) - max_requested.FFE_PRESET.settings.level = - lane_settings[lane].FFE_PRESET.settings.level; -#endif + max_requested.VOLTAGE_SWING = + link_training_setting-> + lane_settings[lane].VOLTAGE_SWING; + + if (link_training_setting->lane_settings[lane].PRE_EMPHASIS > + max_requested.PRE_EMPHASIS) + max_requested.PRE_EMPHASIS = + link_training_setting-> + lane_settings[lane].PRE_EMPHASIS; + + /* + if (link_training_setting->laneSettings[lane].postCursor2 > + max_requested.postCursor2) + { + max_requested.postCursor2 = + link_training_setting->laneSettings[lane].postCursor2; + } + */ } /* make sure the requested settings are @@ -1039,10 +585,10 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL) max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (max_requested.FFE_PRESET.settings.level > DP_FFE_PRESET_MAX_LEVEL) - max_requested.FFE_PRESET.settings.level = DP_FFE_PRESET_MAX_LEVEL; -#endif + /* + if (max_requested.postCursor2 > PostCursor2_MaxLevel) + max_requested.postCursor2 = PostCursor2_MaxLevel; + */ /* make sure the pre-emphasis matches the voltage swing*/ if (max_requested.PRE_EMPHASIS > @@ -1052,58 +598,57 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti get_max_pre_emphasis_for_voltage_swing( max_requested.VOLTAGE_SWING); - for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { - lane_settings[lane].VOLTAGE_SWING = max_requested.VOLTAGE_SWING; - lane_settings[lane].PRE_EMPHASIS = max_requested.PRE_EMPHASIS; -#if defined(CONFIG_DRM_AMD_DC_DCN) - lane_settings[lane].FFE_PRESET = max_requested.FFE_PRESET; -#endif + /* + * Post Cursor2 levels are completely independent from + * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels + * can only be applied to each allowable combination of voltage + * swing and pre-emphasis levels */ + /* if ( max_requested.postCursor2 > + * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing)) + * max_requested.postCursor2 = + * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing); + */ + + max_lt_setting->link_settings.link_rate = + link_training_setting->link_settings.link_rate; + max_lt_setting->link_settings.lane_count = + link_training_setting->link_settings.lane_count; + max_lt_setting->link_settings.link_spread = + link_training_setting->link_settings.link_spread; + + for (lane = 0; lane < + link_training_setting->link_settings.lane_count; + lane++) { + max_lt_setting->lane_settings[lane].VOLTAGE_SWING = + max_requested.VOLTAGE_SWING; + max_lt_setting->lane_settings[lane].PRE_EMPHASIS = + max_requested.PRE_EMPHASIS; + /*max_lt_setting->laneSettings[lane].postCursor2 = + * max_requested.postCursor2; + */ } + } -static void override_lane_settings(const struct link_training_settings *lt_settings, - struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) -{ - uint32_t lane; - - if (lt_settings->voltage_swing == NULL && - lt_settings->pre_emphasis == NULL && -#if defined(CONFIG_DRM_AMD_DC_DCN) - lt_settings->ffe_preset == NULL && -#endif - lt_settings->post_cursor2 == NULL) - - return; - - for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) { - if (lt_settings->voltage_swing) - lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing; - if (lt_settings->pre_emphasis) - lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis; - if (lt_settings->post_cursor2) - lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (lt_settings->ffe_preset) - lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset; -#endif - } -} - -enum dc_status dp_get_lane_status_and_lane_adjust( +enum dc_status dp_get_lane_status_and_drive_settings( struct dc_link *link, const struct link_training_settings *link_training_setting, - union lane_status ln_status[LANE_COUNT_DP_MAX], - union lane_align_status_updated *ln_align, - union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], + union lane_status *ln_status, + union lane_align_status_updated *ln_status_updated, + struct link_training_settings *req_settings, uint32_t offset) { unsigned int lane01_status_address = DP_LANE0_1_STATUS; uint8_t lane_adjust_offset = 4; unsigned int lane01_adjust_address; uint8_t dpcd_buf[6] = {0}; + union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; + struct link_training_settings request_settings = { {0} }; uint32_t lane; enum dc_status status; + memset(req_settings, '\0', sizeof(struct link_training_settings)); + if (is_repeater(link, offset)) { lane01_status_address = DP_LANE0_1_STATUS_PHY_REPEATER1 + @@ -1123,11 +668,11 @@ enum dc_status dp_get_lane_status_and_lane_adjust( ln_status[lane].raw = get_nibble_at_index(&dpcd_buf[0], lane); - ln_adjust[lane].raw = + dpcd_lane_adjust[lane].raw = get_nibble_at_index(&dpcd_buf[lane_adjust_offset], lane); } - ln_align->raw = dpcd_buf[2]; + ln_status_updated->raw = dpcd_buf[2]; if (is_repeater(link, offset)) { DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n" @@ -1166,6 +711,39 @@ enum dc_status dp_get_lane_status_and_lane_adjust( dpcd_buf[lane_adjust_offset + 1]); } + /*copy to req_settings*/ + request_settings.link_settings.lane_count = + link_training_setting->link_settings.lane_count; + request_settings.link_settings.link_rate = + link_training_setting->link_settings.link_rate; + request_settings.link_settings.link_spread = + link_training_setting->link_settings.link_spread; + + for (lane = 0; lane < + (uint32_t)(link_training_setting->link_settings.lane_count); + lane++) { + + request_settings.lane_settings[lane].VOLTAGE_SWING = + (enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits. + VOLTAGE_SWING_LANE); + request_settings.lane_settings[lane].PRE_EMPHASIS = + (enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits. + PRE_EMPHASIS_LANE); + } + + /*Note: for postcursor2, read adjusted + * postcursor2 settings from*/ + /*DpcdAddress_AdjustRequestPostCursor2 = + *0x020C (not implemented yet)*/ + + /* we find the maximum of the requested settings across all lanes*/ + /* and set this maximum for all lanes*/ + find_max_drive_settings(&request_settings, req_settings); + + /* if post cursor 2 is needed in the future, + * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C + */ + return status; } @@ -1174,6 +752,8 @@ enum dc_status dpcd_set_lane_settings( const struct link_training_settings *link_training_setting, uint32_t offset) { + union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}}; + uint32_t lane; unsigned int lane0_set_address; enum dc_status status; @@ -1183,53 +763,71 @@ enum dc_status dpcd_set_lane_settings( lane0_set_address = DP_TRAINING_LANE0_SET_PHY_REPEATER1 + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + for (lane = 0; lane < + (uint32_t)(link_training_setting-> + link_settings.lane_count); + lane++) { + dpcd_lane[lane].bits.VOLTAGE_SWING_SET = + (uint8_t)(link_training_setting-> + lane_settings[lane].VOLTAGE_SWING); + dpcd_lane[lane].bits.PRE_EMPHASIS_SET = + (uint8_t)(link_training_setting-> + lane_settings[lane].PRE_EMPHASIS); + dpcd_lane[lane].bits.MAX_SWING_REACHED = + (link_training_setting-> + lane_settings[lane].VOLTAGE_SWING == + VOLTAGE_SWING_MAX_LEVEL ? 1 : 0); + dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED = + (link_training_setting-> + lane_settings[lane].PRE_EMPHASIS == + PRE_EMPHASIS_MAX_LEVEL ? 1 : 0); + } + status = core_link_write_dpcd(link, lane0_set_address, - (uint8_t *)(link_training_setting->dpcd_lane_settings), + (uint8_t *)(dpcd_lane), link_training_setting->link_settings.lane_count); + /* + if (LTSettings.link.rate == LinkRate_High2) + { + DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0}; + for ( uint32_t lane = 0; + lane < lane_count_DPMax; lane++) + { + dpcd_lane2[lane].bits.post_cursor2_set = + static_cast( + LTSettings.laneSettings[lane].postCursor2); + dpcd_lane2[lane].bits.max_post_cursor2_reached = 0; + } + m_pDpcdAccessSrv->WriteDpcdData( + DpcdAddress_Lane0Set2, + reinterpret_cast(dpcd_lane2), + LTSettings.link.lanes); + } + */ + if (is_repeater(link, offset)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_training_setting->link_settings) == - DP_128b_132b_ENCODING) - DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n" - " 0x%X TX_FFE_PRESET_VALUE = %x\n", - __func__, - offset, - lane0_set_address, - link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE); - else if (dp_get_link_encoding_format(&link_training_setting->link_settings) == - DP_8b_10b_ENCODING) -#endif DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n" " 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, offset, lane0_set_address, - link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET, - link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET, - link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED, - link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED); + dpcd_lane[0].bits.VOLTAGE_SWING_SET, + dpcd_lane[0].bits.PRE_EMPHASIS_SET, + dpcd_lane[0].bits.MAX_SWING_REACHED, + dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED); } else { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_training_setting->link_settings) == - DP_128b_132b_ENCODING) - DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n", - __func__, - lane0_set_address, - link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE); - else if (dp_get_link_encoding_format(&link_training_setting->link_settings) == - DP_8b_10b_ENCODING) -#endif DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n", __func__, lane0_set_address, - link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET, - link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET, - link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED, - link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED); + dpcd_lane[0].bits.VOLTAGE_SWING_SET, + dpcd_lane[0].bits.PRE_EMPHASIS_SET, + dpcd_lane[0].bits.MAX_SWING_REACHED, + dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED); } + link->cur_lane_setting = link_training_setting->lane_settings[0]; return status; } @@ -1241,7 +839,7 @@ bool dp_is_max_vs_reached( for (lane = 0; lane < (uint32_t)(lt_settings->link_settings.lane_count); lane++) { - if (lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET + if (lt_settings->lane_settings[lane].VOLTAGE_SWING == VOLTAGE_SWING_MAX_LEVEL) return true; } @@ -1251,7 +849,6 @@ bool dp_is_max_vs_reached( static bool perform_post_lt_adj_req_sequence( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings) { enum dc_lane_count lane_count = @@ -1272,17 +869,17 @@ static bool perform_post_lt_adj_req_sequence( adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT; adj_req_timer++) { + struct link_training_settings req_settings; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; - dp_get_lane_status_and_lane_adjust( + dp_get_lane_status_and_drive_settings( link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, - dpcd_lane_adjust, + &req_settings, DPRX); if (dpcd_lane_status_updated.bits. @@ -1300,10 +897,11 @@ static bool perform_post_lt_adj_req_sequence( for (lane = 0; lane < (uint32_t)(lane_count); lane++) { if (lt_settings-> - dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET != - dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE || - lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET != - dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE) { + lane_settings[lane].VOLTAGE_SWING != + req_settings.lane_settings[lane]. + VOLTAGE_SWING || + lt_settings->lane_settings[lane].PRE_EMPHASIS != + req_settings.lane_settings[lane].PRE_EMPHASIS) { req_drv_setting_changed = true; break; @@ -1311,11 +909,10 @@ static bool perform_post_lt_adj_req_sequence( } if (req_drv_setting_changed) { - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + dp_update_drive_settings( + lt_settings, req_settings); dc_link_dp_set_drive_settings(link, - link_res, lt_settings); break; } @@ -1357,14 +954,6 @@ uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval case 0x04: aux_rd_interval_us = 16000; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case 0x05: - aux_rd_interval_us = 32000; - break; - case 0x06: - aux_rd_interval_us = 64000; - break; -#endif default: break; } @@ -1390,35 +979,30 @@ enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count, static enum link_training_result perform_channel_equalization_sequence( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings, uint32_t offset) { + struct link_training_settings req_settings; enum dc_dp_training_pattern tr_pattern; uint32_t retries_ch_eq; uint32_t wait_time_microsec; enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; - union lane_align_status_updated dpcd_lane_status_updated = {0}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; + union lane_align_status_updated dpcd_lane_status_updated = { {0} }; + union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } }; /* Note: also check that TPS4 is a supported feature*/ + tr_pattern = lt_settings->pattern_for_eq; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_repeater(link, offset) && dp_get_link_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING) - tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4; -#else if (is_repeater(link, offset)) tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4; -#endif - dp_set_hw_training_pattern(link, link_res, tr_pattern, offset); + dp_set_hw_training_pattern(link, tr_pattern, offset); for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT; retries_ch_eq++) { - dp_set_hw_lane_settings(link, link_res, lt_settings, offset); + dp_set_hw_lane_settings(link, lt_settings, offset); /* 2. update DPCD*/ if (!retries_ch_eq) @@ -1441,12 +1025,6 @@ static enum link_training_result perform_channel_equalization_sequence( dp_translate_training_aux_read_interval( link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]); - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - wait_time_microsec = 16000; - } - dp_wait_for_training_aux_rd_interval( link, wait_time_microsec); @@ -1454,12 +1032,12 @@ static enum link_training_result perform_channel_equalization_sequence( /* 4. Read lane status and requested * drive settings as set by the sink*/ - dp_get_lane_status_and_lane_adjust( + dp_get_lane_status_and_drive_settings( link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, - dpcd_lane_adjust, + &req_settings, offset); /* 5. check CR done*/ @@ -1473,8 +1051,7 @@ static enum link_training_result perform_channel_equalization_sequence( return LINK_TRAINING_SUCCESS; /* 7. update VS/PE/PC2 in lt_settings*/ - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + dp_update_drive_settings(lt_settings, req_settings); } return LINK_TRAINING_EQ_FAIL_EQ; @@ -1482,36 +1059,34 @@ static enum link_training_result perform_channel_equalization_sequence( } static void start_clock_recovery_pattern_early(struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings, uint32_t offset) { DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS1. Wait 400us.\n", __func__); - dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset); - dp_set_hw_lane_settings(link, link_res, lt_settings, offset); + dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, offset); + dp_set_hw_lane_settings(link, lt_settings, offset); udelay(400); } static enum link_training_result perform_clock_recovery_sequence( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings, uint32_t offset) { uint32_t retries_cr; uint32_t retry_count; uint32_t wait_time_microsec; + struct link_training_settings req_settings; enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; retries_cr = 0; retry_count = 0; if (!link->ctx->dc->work_arounds.lt_early_cr_pattern) - dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset); + dp_set_hw_training_pattern(link, lt_settings->pattern_for_cr, offset); /* najeeb - The synaptics MST hub can put the LT in * infinite loop by switching the VS @@ -1528,7 +1103,6 @@ static enum link_training_result perform_clock_recovery_sequence( /* 1. call HWSS to set lane settings*/ dp_set_hw_lane_settings( link, - link_res, lt_settings, offset); @@ -1550,10 +1124,8 @@ static enum link_training_result perform_clock_recovery_sequence( /* 3. wait receiver to lock-on*/ wait_time_microsec = lt_settings->cr_pattern_time; - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) { - wait_time_microsec = 16000; - } + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) + wait_time_microsec = TRAINING_AUX_RD_INTERVAL; dp_wait_for_training_aux_rd_interval( link, @@ -1562,55 +1134,36 @@ static enum link_training_result perform_clock_recovery_sequence( /* 4. Read lane status and requested drive * settings as set by the sink */ - dp_get_lane_status_and_lane_adjust( + dp_get_lane_status_and_drive_settings( link, lt_settings, dpcd_lane_status, &dpcd_lane_status_updated, - dpcd_lane_adjust, + &req_settings, offset); - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - vendor_specific_lttpr_wa_one_end(link, retry_count); - vendor_specific_lttpr_wa_three(link, dpcd_lane_adjust); - } - /* 5. check CR done*/ if (dp_is_cr_done(lane_count, dpcd_lane_status)) return LINK_TRAINING_SUCCESS; /* 6. max VS reached*/ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if ((dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING) && - dp_is_max_vs_reached(lt_settings)) - break; -#else if (dp_is_max_vs_reached(lt_settings)) break; -#endif /* 7. same lane settings*/ /* Note: settings are the same for all lanes, * so comparing first lane is sufficient*/ - if ((dp_get_link_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING) && - lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET == - dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE) + if ((lt_settings->lane_settings[0].VOLTAGE_SWING == + req_settings.lane_settings[0].VOLTAGE_SWING) + && (lt_settings->lane_settings[0].PRE_EMPHASIS == + req_settings.lane_settings[0].PRE_EMPHASIS)) retries_cr++; -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if ((dp_get_link_encoding_format(<_settings->link_settings) == DP_128b_132b_ENCODING) && - lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE == - dpcd_lane_adjust[0].tx_ffe.PRESET_VALUE) - retries_cr++; -#endif else retries_cr = 0; /* 8. update VS/PE/PC2 in lt_settings*/ - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + dp_update_drive_settings(lt_settings, req_settings); + retry_count++; } @@ -1627,14 +1180,13 @@ static enum link_training_result perform_clock_recovery_sequence( static inline enum link_training_result dp_transition_to_video_idle( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings, enum link_training_result status) { - union lane_count_set lane_count_set = {0}; + union lane_count_set lane_count_set = { {0} }; /* 4. mainlink output idle pattern*/ - dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); + dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); /* * 5. post training adjust if required @@ -1642,11 +1194,7 @@ static inline enum link_training_result dp_transition_to_video_idle( * TPS4 must be used instead of POST_LT_ADJ_REQ. */ if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 || -#if defined(CONFIG_DRM_AMD_DC_DCN) - lt_settings->pattern_for_eq >= DP_TRAINING_PATTERN_SEQUENCE_4) { -#else lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4) { -#endif /* delay 5ms after Main Link output idle pattern and then check * DPCD 0202h. */ @@ -1658,7 +1206,7 @@ static inline enum link_training_result dp_transition_to_video_idle( } if (status == LINK_TRAINING_SUCCESS && - perform_post_lt_adj_req_sequence(link, link_res, lt_settings) == false) + perform_post_lt_adj_req_sequence(link, lt_settings) == false) status = LINK_TRAINING_LQA_FAIL; lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count; @@ -1740,40 +1288,8 @@ static inline void decide_8b_10b_training_settings( lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting); lt_settings->enhanced_framing = 1; lt_settings->should_set_fec_ready = true; - lt_settings->disallow_per_lane_settings = true; - lt_settings->always_match_dpcd_with_hw_lane_settings = true; - dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static inline void decide_128b_132b_training_settings(struct dc_link *link, - const struct dc_link_settings *link_settings, - struct link_training_settings *lt_settings) -{ - memset(lt_settings, 0, sizeof(*lt_settings)); - - lt_settings->link_settings = *link_settings; - /* TODO: should decide link spread when populating link_settings */ - lt_settings->link_settings.link_spread = link->dp_ss_off ? LINK_SPREAD_DISABLED : - LINK_SPREAD_05_DOWNSPREAD_30KHZ; - - lt_settings->pattern_for_cr = decide_cr_training_pattern(link_settings); - lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_settings); - lt_settings->eq_pattern_time = 2500; - lt_settings->eq_wait_time_limit = 400000; - lt_settings->eq_loop_count_limit = 20; - lt_settings->pattern_for_cds = DP_128b_132b_TPS2_CDS; - lt_settings->cds_pattern_time = 2500; - lt_settings->cds_wait_time_limit = (dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt) + 1) * 20000; - lt_settings->lttpr_mode = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) ? - LTTPR_MODE_NON_TRANSPARENT : LTTPR_MODE_TRANSPARENT; - lt_settings->disallow_per_lane_settings = true; - dp_hw_to_dpcd_lane_settings(lt_settings, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); -} -#endif - void dp_decide_training_settings( struct dc_link *link, const struct dc_link_settings *link_settings, @@ -1781,10 +1297,6 @@ void dp_decide_training_settings( { if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) decide_8b_10b_training_settings(link, link_settings, lt_settings); -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) - decide_128b_132b_training_settings(link, link_settings, lt_settings); -#endif } static void override_training_settings( @@ -1807,17 +1319,6 @@ static void override_training_settings( lt_settings->pre_emphasis = overrides->pre_emphasis; if (overrides->post_cursor2 != NULL) lt_settings->post_cursor2 = overrides->post_cursor2; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (overrides->ffe_preset != NULL) - lt_settings->ffe_preset = overrides->ffe_preset; -#endif - /* Override HW lane settings with BIOS forced values if present */ - if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - lt_settings->voltage_swing = &link->bios_forced_drive_settings.VOLTAGE_SWING; - lt_settings->pre_emphasis = &link->bios_forced_drive_settings.PRE_EMPHASIS; - lt_settings->always_match_dpcd_with_hw_lane_settings = false; - } for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { lt_settings->lane_settings[lane].VOLTAGE_SWING = lt_settings->voltage_swing != NULL ? @@ -1833,9 +1334,6 @@ static void override_training_settings( : POST_CURSOR2_DISABLED; } - dp_hw_to_dpcd_lane_settings(lt_settings, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); - /* Initialize training timings */ if (overrides->cr_pattern_time != NULL) lt_settings->cr_pattern_time = *overrides->cr_pattern_time; @@ -1880,7 +1378,7 @@ uint8_t dp_convert_to_count(uint8_t lttpr_repeater_count) return 0; // invalid value } -static enum dc_status configure_lttpr_mode_transparent(struct dc_link *link) +enum dc_status configure_lttpr_mode_transparent(struct dc_link *link) { uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT; @@ -1891,7 +1389,7 @@ static enum dc_status configure_lttpr_mode_transparent(struct dc_link *link) sizeof(repeater_mode)); } -static enum dc_status configure_lttpr_mode_non_transparent( +enum dc_status configure_lttpr_mode_non_transparent( struct dc_link *link, const struct link_training_settings *lt_settings) { @@ -1934,13 +1432,6 @@ static enum dc_status configure_lttpr_mode_non_transparent( if (encoding == DP_8b_10b_ENCODING) { repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - - /* Driver does not need to train the first hop. Skip DPCD read and clear - * AUX_RD_INTERVAL for DPTX-to-DPIA hop. - */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) - link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0; - for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) { aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1)); @@ -1959,7 +1450,7 @@ static enum dc_status configure_lttpr_mode_non_transparent( static void repeater_training_done(struct dc_link *link, uint32_t offset) { - union dpcd_training_pattern dpcd_pattern = {0}; + union dpcd_training_pattern dpcd_pattern = { {0} }; const uint32_t dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 + @@ -2014,17 +1505,6 @@ static void print_status_message( case LINK_RATE_HIGH3: link_rate = "HBR3"; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case LINK_RATE_UHBR10: - link_rate = "UHBR10"; - break; - case LINK_RATE_UHBR13_5: - link_rate = "UHBR13.5"; - break; - case LINK_RATE_UHBR20: - link_rate = "UHBR20"; - break; -#endif default: break; } @@ -2054,20 +1534,6 @@ static void print_status_message( case LINK_TRAINING_LINK_LOSS: lt_result = "Link loss"; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_128b_132b_LT_FAILED: - lt_result = "LT_FAILED received"; - break; - case DP_128b_132b_MAX_LOOP_COUNT_REACHED: - lt_result = "max loop count reached"; - break; - case DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT: - lt_result = "channel EQ timeout"; - break; - case DP_128b_132b_CDS_DONE_TIMEOUT: - lt_result = "CDS timeout"; - break; -#endif default: break; } @@ -2087,9 +1553,6 @@ static void print_status_message( } /* Connectivity log: link training */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* TODO - DP2.0 Log: add connectivity log for FFE PRESET */ -#endif CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s", link_rate, lt_settings->link_settings.lane_count, @@ -2101,14 +1564,10 @@ static void print_status_message( void dc_link_dp_set_drive_settings( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings) { /* program ASIC PHY settings*/ - dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); - - dp_hw_to_dpcd_lane_settings(lt_settings, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + dp_set_hw_lane_settings(link, lt_settings, DPRX); /* Notify DP sink the PHY settings from source */ dpcd_set_lane_settings(link, lt_settings, DPRX); @@ -2116,7 +1575,6 @@ void dc_link_dp_set_drive_settings( bool dc_link_dp_perform_link_training_skip_aux( struct dc_link *link, - const struct link_resource *link_res, const struct dc_link_settings *link_setting) { struct link_training_settings lt_settings = {0}; @@ -2133,10 +1591,10 @@ bool dc_link_dp_perform_link_training_skip_aux( /* 1. Perform_clock_recovery_sequence. */ /* transmit training pattern for clock recovery */ - dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_cr, DPRX); + dp_set_hw_training_pattern(link, lt_settings.pattern_for_cr, DPRX); /* call HWSS to set lane settings*/ - dp_set_hw_lane_settings(link, link_res, <_settings, DPRX); + dp_set_hw_lane_settings(link, <_settings, DPRX); /* wait receiver to lock-on*/ dp_wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time); @@ -2144,10 +1602,10 @@ bool dc_link_dp_perform_link_training_skip_aux( /* 2. Perform_channel_equalization_sequence. */ /* transmit training pattern for channel equalization. */ - dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_eq, DPRX); + dp_set_hw_training_pattern(link, lt_settings.pattern_for_eq, DPRX); /* call HWSS to set lane settings*/ - dp_set_hw_lane_settings(link, link_res, <_settings, DPRX); + dp_set_hw_lane_settings(link, <_settings, DPRX); /* wait receiver to lock-on. */ dp_wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time); @@ -2155,7 +1613,7 @@ bool dc_link_dp_perform_link_training_skip_aux( /* 3. Perform_link_training_int. */ /* Mainlink output idle pattern. */ - dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); + dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); print_status_message(link, <_settings, LINK_TRAINING_SUCCESS); @@ -2177,23 +1635,9 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train static void dpcd_exit_training_mode(struct dc_link *link) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t sink_status = 0; - uint8_t i; -#endif /* clear training pattern set */ dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* poll for intra-hop disable */ - for (i = 0; i < 10; i++) { - if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) && - (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0) - break; - udelay(1000); - } -#endif } enum dc_status dpcd_configure_channel_coding(struct dc_link *link, @@ -2217,142 +1661,8 @@ enum dc_status dpcd_configure_channel_coding(struct dc_link *link, return status; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static void dpcd_128b_132b_get_aux_rd_interval(struct dc_link *link, - uint32_t *interval_in_us) -{ - union dp_128b_132b_training_aux_rd_interval dpcd_interval; - uint32_t interval_unit = 0; - - dpcd_interval.raw = 0; - core_link_read_dpcd(link, DP_128b_132b_TRAINING_AUX_RD_INTERVAL, - &dpcd_interval.raw, sizeof(dpcd_interval.raw)); - interval_unit = dpcd_interval.bits.UNIT ? 1 : 2; /* 0b = 2 ms, 1b = 1 ms */ - /* (128b/132b_TRAINING_AUX_RD_INTERVAL value + 1) * - * INTERVAL_UNIT. The maximum is 256 ms - */ - *interval_in_us = (dpcd_interval.bits.VALUE + 1) * interval_unit * 1000; -} - -static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings) -{ - uint8_t loop_count; - uint32_t aux_rd_interval = 0; - uint32_t wait_time = 0; - union lane_align_status_updated dpcd_lane_status_updated = {0}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; - enum link_training_result status = LINK_TRAINING_SUCCESS; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - - /* Transmit 128b/132b_TPS1 over Main-Link */ - dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, DPRX); - /* Set TRAINING_PATTERN_SET to 01h */ - dpcd_set_training_pattern(link, lt_settings->pattern_for_cr); - - /* Adjust TX_FFE_PRESET_VALUE and Transmit 128b/132b_TPS2 over Main-Link */ - dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval); - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, - &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); - dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); - dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_eq, DPRX); - - /* Set loop counter to start from 1 */ - loop_count = 1; - - /* Set TRAINING_PATTERN_SET to 02h and TX_FFE_PRESET_VALUE in one AUX transaction */ - dpcd_set_lt_pattern_and_lane_settings(link, lt_settings, - lt_settings->pattern_for_eq, DPRX); - - /* poll for channel EQ done */ - while (status == LINK_TRAINING_SUCCESS) { - dp_wait_for_training_aux_rd_interval(link, aux_rd_interval); - wait_time += aux_rd_interval; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, - &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); - dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval); - if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count, - dpcd_lane_status)) { - /* pass */ - break; - } else if (loop_count >= lt_settings->eq_loop_count_limit) { - status = DP_128b_132b_MAX_LOOP_COUNT_REACHED; - } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; - } else { - dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); - dpcd_set_lane_settings(link, lt_settings, DPRX); - } - loop_count++; - } - - /* poll for EQ interlane align done */ - while (status == LINK_TRAINING_SUCCESS) { - if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) { - /* pass */ - break; - } else if (wait_time >= lt_settings->eq_wait_time_limit) { - status = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT; - } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; - } else { - dp_wait_for_training_aux_rd_interval(link, - lt_settings->eq_pattern_time); - wait_time += lt_settings->eq_pattern_time; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, - &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); - } - } - - return status; -} - -static enum link_training_result dp_perform_128b_132b_cds_done_sequence( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings) -{ - /* Assumption: assume hardware has transmitted eq pattern */ - enum link_training_result status = LINK_TRAINING_SUCCESS; - union lane_align_status_updated dpcd_lane_status_updated = {0}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; - uint32_t wait_time = 0; - - /* initiate CDS done sequence */ - dpcd_set_training_pattern(link, lt_settings->pattern_for_cds); - - /* poll for CDS interlane align done and symbol lock */ - while (status == LINK_TRAINING_SUCCESS) { - dp_wait_for_training_aux_rd_interval(link, - lt_settings->cds_pattern_time); - wait_time += lt_settings->cds_pattern_time; - dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status, - &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX); - if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) && - dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) { - /* pass */ - break; - } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) { - status = DP_128b_132b_LT_FAILED; - } else if (wait_time >= lt_settings->cds_wait_time_limit) { - status = DP_128b_132b_CDS_DONE_TIMEOUT; - } - } - - return status; -} -#endif - static enum link_training_result dp_perform_8b_10b_link_training( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings) { enum link_training_result status = LINK_TRAINING_SUCCESS; @@ -2362,7 +1672,7 @@ static enum link_training_result dp_perform_8b_10b_link_training( uint8_t lane = 0; if (link->ctx->dc->work_arounds.lt_early_cr_pattern) - start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX); + start_clock_recovery_pattern_early(link, lt_settings, DPRX); /* 1. set link rate, lane count and spread. */ dpcd_set_link_settings(link, lt_settings); @@ -2376,13 +1686,12 @@ static enum link_training_result dp_perform_8b_10b_link_training( for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS); repeater_id--) { - status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id); + status = perform_clock_recovery_sequence(link, lt_settings, repeater_id); if (status != LINK_TRAINING_SUCCESS) break; status = perform_channel_equalization_sequence(link, - link_res, lt_settings, repeater_id); @@ -2393,14 +1702,13 @@ static enum link_training_result dp_perform_8b_10b_link_training( } for (lane = 0; lane < (uint8_t)lt_settings->link_settings.lane_count; lane++) - lt_settings->dpcd_lane_settings[lane].raw = 0; + lt_settings->lane_settings[lane].VOLTAGE_SWING = VOLTAGE_SWING_LEVEL0; } if (status == LINK_TRAINING_SUCCESS) { - status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX); + status = perform_clock_recovery_sequence(link, lt_settings, DPRX); if (status == LINK_TRAINING_SUCCESS) { status = perform_channel_equalization_sequence(link, - link_res, lt_settings, DPRX); } @@ -2409,373 +1717,8 @@ static enum link_training_result dp_perform_8b_10b_link_training( return status; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static enum link_training_result dp_perform_128b_132b_link_training( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings) -{ - enum link_training_result result = LINK_TRAINING_SUCCESS; - - /* TODO - DP2.0 Link: remove legacy_dp2_lt logic */ - if (link->dc->debug.legacy_dp2_lt) { - struct link_training_settings legacy_settings; - - decide_8b_10b_training_settings(link, - <_settings->link_settings, - &legacy_settings); - return dp_perform_8b_10b_link_training(link, link_res, &legacy_settings); - } - - dpcd_set_link_settings(link, lt_settings); - - if (result == LINK_TRAINING_SUCCESS) - result = dp_perform_128b_132b_channel_eq_done_sequence(link, link_res, lt_settings); - - if (result == LINK_TRAINING_SUCCESS) - result = dp_perform_128b_132b_cds_done_sequence(link, link_res, lt_settings); - - return result; -} -#endif - -static enum link_training_result dc_link_dp_perform_fixed_vs_pe_training_sequence( - struct dc_link *link, - const struct link_resource *link_res, - struct link_training_settings *lt_settings) -{ - const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; - const uint8_t offset = dp_convert_to_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - const uint8_t vendor_lttpr_write_data_intercept_en[4] = {0x1, 0x55, 0x63, 0x0}; - const uint8_t vendor_lttpr_write_data_intercept_dis[4] = {0x1, 0x55, 0x63, 0x68}; - uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; - uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; - uint32_t vendor_lttpr_write_address = 0xF004F; - enum link_training_result status = LINK_TRAINING_SUCCESS; - uint8_t lane = 0; - union down_spread_ctrl downspread = {0}; - union lane_count_set lane_count_set = {0}; - uint8_t toggle_rate; - uint8_t rate; - - /* Only 8b/10b is supported */ - ASSERT(dp_get_link_encoding_format(<_settings->link_settings) == - DP_8b_10b_ENCODING); - - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - - /* Vendor specific: Reset lane settings */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - - /* Vendor specific: Enable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_en[0], - sizeof(vendor_lttpr_write_data_intercept_en)); - - /* 1. set link rate, lane count and spread. */ - - downspread.raw = (uint8_t)(lt_settings->link_settings.link_spread); - - lane_count_set.bits.LANE_COUNT_SET = - lt_settings->link_settings.lane_count; - - lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing; - lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0; - - - if (lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) { - lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = - link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED; - } - - core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL, - &downspread.raw, sizeof(downspread)); - - core_link_write_dpcd(link, DP_LANE_COUNT_SET, - &lane_count_set.raw, 1); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - rate = get_dpcd_link_rate(<_settings->link_settings); -#else - rate = (uint8_t) (lt_settings->link_settings.link_rate); -#endif - - /* Vendor specific: Toggle link rate */ - toggle_rate = (rate == 0x6) ? 0xA : 0x6; - - if (link->vendor_specific_lttpr_link_rate_wa == rate) { - core_link_write_dpcd( - link, - DP_LINK_BW_SET, - &toggle_rate, - 1); - } - - link->vendor_specific_lttpr_link_rate_wa = rate; - - core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); - - DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n", - __func__, - DP_LINK_BW_SET, - lt_settings->link_settings.link_rate, - DP_LANE_COUNT_SET, - lt_settings->link_settings.lane_count, - lt_settings->enhanced_framing, - DP_DOWNSPREAD_CTRL, - lt_settings->link_settings.link_spread); - - /* 2. Perform link training */ - - /* Perform Clock Recovery Sequence */ - if (status == LINK_TRAINING_SUCCESS) { - uint32_t retries_cr; - uint32_t retry_count; - uint32_t wait_time_microsec; - enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; - union lane_align_status_updated dpcd_lane_status_updated; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - - retries_cr = 0; - retry_count = 0; - - while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) && - (retry_count < LINK_TRAINING_MAX_CR_RETRY)) { - - memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status)); - memset(&dpcd_lane_status_updated, '\0', - sizeof(dpcd_lane_status_updated)); - - /* 1. call HWSS to set lane settings */ - dp_set_hw_lane_settings( - link, - link_res, - lt_settings, - 0); - - /* 2. update DPCD of the receiver */ - if (!retry_count) { - /* EPR #361076 - write as a 5-byte burst, - * but only for the 1-st iteration. - */ - dpcd_set_lt_pattern_and_lane_settings( - link, - lt_settings, - lt_settings->pattern_for_cr, - 0); - /* Vendor specific: Disable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_dis[0], - sizeof(vendor_lttpr_write_data_intercept_dis)); - } else { - vendor_lttpr_write_data_vs[3] = 0; - vendor_lttpr_write_data_pe[3] = 0; - - for (lane = 0; lane < lane_count; lane++) { - vendor_lttpr_write_data_vs[3] |= - lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane); - vendor_lttpr_write_data_pe[3] |= - lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane); - } - - /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - - dpcd_set_lane_settings( - link, - lt_settings, - 0); - } - - /* 3. wait receiver to lock-on*/ - wait_time_microsec = lt_settings->cr_pattern_time; - - dp_wait_for_training_aux_rd_interval( - link, - wait_time_microsec); - - /* 4. Read lane status and requested drive - * settings as set by the sink - */ - dp_get_lane_status_and_lane_adjust( - link, - lt_settings, - dpcd_lane_status, - &dpcd_lane_status_updated, - dpcd_lane_adjust, - 0); - - /* 5. check CR done*/ - if (dp_is_cr_done(lane_count, dpcd_lane_status)) { - status = LINK_TRAINING_SUCCESS; - break; - } - - /* 6. max VS reached*/ - if (dp_is_max_vs_reached(lt_settings)) - break; - - /* 7. same lane settings */ - /* Note: settings are the same for all lanes, - * so comparing first lane is sufficient - */ - if (lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET == - dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE) - retries_cr++; - else - retries_cr = 0; - - /* 8. update VS/PE/PC2 in lt_settings*/ - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); - retry_count++; - } - - if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) { - ASSERT(0); - DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue", - __func__, - LINK_TRAINING_MAX_CR_RETRY); - - } - - status = dp_get_cr_failure(lane_count, dpcd_lane_status); - } - - /* Perform Channel EQ Sequence */ - if (status == LINK_TRAINING_SUCCESS) { - enum dc_dp_training_pattern tr_pattern; - uint32_t retries_ch_eq; - uint32_t wait_time_microsec; - enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; - union lane_align_status_updated dpcd_lane_status_updated = {0}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - - /* Note: also check that TPS4 is a supported feature*/ - tr_pattern = lt_settings->pattern_for_eq; - - dp_set_hw_training_pattern(link, link_res, tr_pattern, 0); - - status = LINK_TRAINING_EQ_FAIL_EQ; - - for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT; - retries_ch_eq++) { - - dp_set_hw_lane_settings(link, link_res, lt_settings, 0); - - vendor_lttpr_write_data_vs[3] = 0; - vendor_lttpr_write_data_pe[3] = 0; - - for (lane = 0; lane < lane_count; lane++) { - vendor_lttpr_write_data_vs[3] |= - lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane); - vendor_lttpr_write_data_pe[3] |= - lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane); - } - - /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - - /* 2. update DPCD*/ - if (!retries_ch_eq) - /* EPR #361076 - write as a 5-byte burst, - * but only for the 1-st iteration - */ - - dpcd_set_lt_pattern_and_lane_settings( - link, - lt_settings, - tr_pattern, 0); - else - dpcd_set_lane_settings(link, lt_settings, 0); - - /* 3. wait for receiver to lock-on*/ - wait_time_microsec = lt_settings->eq_pattern_time; - - dp_wait_for_training_aux_rd_interval( - link, - wait_time_microsec); - - /* 4. Read lane status and requested - * drive settings as set by the sink - */ - dp_get_lane_status_and_lane_adjust( - link, - lt_settings, - dpcd_lane_status, - &dpcd_lane_status_updated, - dpcd_lane_adjust, - 0); - - /* 5. check CR done*/ - if (!dp_is_cr_done(lane_count, dpcd_lane_status)) { - status = LINK_TRAINING_EQ_FAIL_CR; - break; - } - - /* 6. check CHEQ done*/ - if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) && - dp_is_symbol_locked(lane_count, dpcd_lane_status) && - dp_is_interlane_aligned(dpcd_lane_status_updated)) { - status = LINK_TRAINING_SUCCESS; - break; - } - - /* 7. update VS/PE/PC2 in lt_settings*/ - dp_decide_lane_settings(lt_settings, dpcd_lane_adjust, - lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); - } - } - - return status; -} - - enum link_training_result dc_link_dp_perform_link_training( struct dc_link *link, - const struct link_resource *link_res, const struct dc_link_settings *link_settings, bool skip_video_pattern) { @@ -2795,51 +1738,26 @@ enum link_training_result dc_link_dp_perform_link_training( <_settings); /* reset previous training states */ - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - link->apply_vendor_specific_lttpr_link_rate_wa = true; - vendor_specific_lttpr_wa_four(link, true); - } else { - dpcd_exit_training_mode(link); - } + dpcd_exit_training_mode(link); /* configure link prior to entering training mode */ dpcd_configure_lttpr_mode(link, <_settings); - dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready); + dp_set_fec_ready(link, lt_settings.should_set_fec_ready); dpcd_configure_channel_coding(link, <_settings); /* enter training mode: * Per DP specs starting from here, DPTX device shall not issue * Non-LT AUX transactions inside training mode. */ - if (!link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) - status = dc_link_dp_perform_fixed_vs_pe_training_sequence(link, link_res, <_settings); - else if (encoding == DP_8b_10b_ENCODING) - status = dp_perform_8b_10b_link_training(link, link_res, <_settings); -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (encoding == DP_128b_132b_ENCODING) - status = dp_perform_128b_132b_link_training(link, link_res, <_settings); -#endif + if (encoding == DP_8b_10b_ENCODING) + status = dp_perform_8b_10b_link_training(link, <_settings); else ASSERT(0); - /* exit training mode */ - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - link->apply_vendor_specific_lttpr_link_rate_wa = false; - vendor_specific_lttpr_wa_four(link, (status != LINK_TRAINING_SUCCESS)); - } else { - dpcd_exit_training_mode(link); - } - - /* switch to video idle */ + /* exit training mode and switch to video idle */ + dpcd_exit_training_mode(link); if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) status = dp_transition_to_video_idle(link, - link_res, <_settings, status); @@ -2870,19 +1788,16 @@ bool perform_link_training_with_retries( /* Dynamically assigned link encoders associated with stream rather than * link. */ - if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream); + if (link->dc->res_pool->funcs->link_encs_assign) + link_enc = stream->link_enc; else link_enc = link->link_enc; /* We need to do this before the link training to ensure the idle pattern in SST * mode will be sent right after the link training */ - if (dp_get_link_encoding_format(¤t_setting) == DP_8b_10b_ENCODING) { - link_enc->funcs->connect_dig_be_to_fe(link_enc, + link_enc->funcs->connect_dig_be_to_fe(link_enc, pipe_ctx->stream_res.stream_enc->id, true); - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE); - } for (j = 0; j < attempts; ++j) { @@ -2891,7 +1806,6 @@ bool perform_link_training_with_retries( dp_enable_link_phy( link, - &pipe_ctx->link_res, signal, pipe_ctx->clock_source->id, ¤t_setting); @@ -2919,26 +1833,13 @@ bool perform_link_training_with_retries( dp_set_panel_mode(link, panel_mode); if (link->aux_access_disabled) { - dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, ¤t_setting); + dc_link_dp_perform_link_training_skip_aux(link, ¤t_setting); return true; } else { - /** @todo Consolidate USB4 DP and DPx.x training. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) { - status = dc_link_dpia_perform_link_training(link, - &pipe_ctx->link_res, - ¤t_setting, - skip_video_pattern); - - /* Transmit idle pattern once training successful. */ - if (status == LINK_TRAINING_SUCCESS) - dp_set_hw_test_pattern(link, &pipe_ctx->link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); - } else { - status = dc_link_dp_perform_link_training(link, - &pipe_ctx->link_res, - ¤t_setting, - skip_video_pattern); - } - + status = dc_link_dp_perform_link_training( + link, + ¤t_setting, + skip_video_pattern); if (status == LINK_TRAINING_SUCCESS) return true; } @@ -2951,7 +1852,7 @@ bool perform_link_training_with_retries( DC_LOG_WARNING("%s: Link training attempt %u of %d failed\n", __func__, (unsigned int)j + 1, attempts); - dp_disable_link_phy(link, &pipe_ctx->link_res, signal); + dp_disable_link_phy(link, signal); /* Abort link training if failure due to sink being unplugged. */ if (status == LINK_TRAINING_ABORT) { @@ -2961,16 +1862,12 @@ bool perform_link_training_with_retries( if (type == dc_connection_none) break; } else if (do_fallback) { - uint32_t req_bw; - uint32_t link_bw; - - decide_fallback_link_setting(link, *link_setting, ¤t_setting, status); + decide_fallback_link_setting(*link_setting, ¤t_setting, status); /* Fail link training if reduced link bandwidth no longer meets * stream requirements. */ - req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); - link_bw = dc_link_bandwidth_kbps(link, ¤t_setting); - if (req_bw > link_bw) + if (dc_bandwidth_in_kbps_from_timing(&stream->timing) < + dc_link_bandwidth_kbps(link, ¤t_setting)) break; } @@ -3000,13 +1897,12 @@ static enum clock_source_id get_clock_source_id(struct dc_link *link) return dp_cs_id; } -static void set_dp_mst_mode(struct dc_link *link, const struct link_resource *link_res, - bool mst_enable) +static void set_dp_mst_mode(struct dc_link *link, bool mst_enable) { if (mst_enable == false && link->type == dc_connection_mst_branch) { /* Disable MST on link. Use only local sink. */ - dp_disable_link_phy_mst(link, link_res, link->connector_signal); + dp_disable_link_phy_mst(link, link->connector_signal); link->type = dc_connection_single; link->local_sink = link->remote_sinks[0]; @@ -3017,7 +1913,7 @@ static void set_dp_mst_mode(struct dc_link *link, const struct link_resource *li link->type == dc_connection_single && link->remote_sinks[0] != NULL) { /* Re-enable MST on link. */ - dp_disable_link_phy(link, link_res, link->connector_signal); + dp_disable_link_phy(link, link->connector_signal); dp_enable_mst_on_sink(link, true); link->type = dc_connection_mst_branch; @@ -3043,7 +1939,6 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link) enum link_training_result dc_link_dp_sync_lt_attempt( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *link_settings, struct dc_link_training_overrides *lt_overrides) { @@ -3063,25 +1958,19 @@ enum link_training_result dc_link_dp_sync_lt_attempt( <_settings); /* Setup MST Mode */ if (lt_overrides->mst_enable) - set_dp_mst_mode(link, link_res, *lt_overrides->mst_enable); + set_dp_mst_mode(link, *lt_overrides->mst_enable); /* Disable link */ - dp_disable_link_phy(link, link_res, link->connector_signal); + dp_disable_link_phy(link, link->connector_signal); /* Enable link */ dp_cs_id = get_clock_source_id(link); - dp_enable_link_phy(link, link_res, link->connector_signal, + dp_enable_link_phy(link, link->connector_signal, dp_cs_id, link_settings); /* Set FEC enable */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { -#endif - fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable; - dp_set_fec_ready(link, NULL, fec_enable); -#if defined(CONFIG_DRM_AMD_DC_DCN) - } -#endif + fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable; + dp_set_fec_ready(link, fec_enable); if (lt_overrides->alternate_scrambler_reset) { if (*lt_overrides->alternate_scrambler_reset) @@ -3095,7 +1984,7 @@ enum link_training_result dc_link_dp_sync_lt_attempt( /* Attempt to train with given link training settings */ if (link->ctx->dc->work_arounds.lt_early_cr_pattern) - start_clock_recovery_pattern_early(link, link_res, <_settings, DPRX); + start_clock_recovery_pattern_early(link, <_settings, DPRX); /* Set link rate, lane count and spread. */ dpcd_set_link_settings(link, <_settings); @@ -3103,10 +1992,9 @@ enum link_training_result dc_link_dp_sync_lt_attempt( /* 2. perform link training (set link training done * to false is done as well) */ - lt_status = perform_clock_recovery_sequence(link, link_res, <_settings, DPRX); + lt_status = perform_clock_recovery_sequence(link, <_settings, DPRX); if (lt_status == LINK_TRAINING_SUCCESS) { lt_status = perform_channel_equalization_sequence(link, - link_res, <_settings, DPRX); } @@ -3124,59 +2012,23 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down) * Still shouldn't turn off dp_receiver (DPCD:600h) */ if (link_down == true) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dc_link_settings link_settings = link->cur_link_settings; -#endif - dp_disable_link_phy(link, NULL, link->connector_signal); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING) -#endif - dp_set_fec_ready(link, NULL, false); + dp_disable_link_phy(link, link->connector_signal); + dp_set_fec_ready(link, false); } link->sync_lt_in_progress = false; return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link) -{ - enum dc_link_rate lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate; - - if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20) - lttpr_max_link_rate = LINK_RATE_UHBR20; - else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5) - lttpr_max_link_rate = LINK_RATE_UHBR13_5; - else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR10) - lttpr_max_link_rate = LINK_RATE_UHBR10; - - return lttpr_max_link_rate; -} -#endif - bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap) { - struct link_encoder *link_enc = NULL; - if (!max_link_enc_cap) { DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__); return false; } - /* Links supporting dynamically assigned link encoder will be assigned next - * available encoder if one not already assigned. - */ - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) { - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); - if (link_enc == NULL) - link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc); - } else - link_enc = link->link_enc; - ASSERT(link_enc); - - if (link_enc && link_enc->funcs->get_max_link_cap) { - link_enc->funcs->get_max_link_cap(link_enc, max_link_enc_cap); + if (link->link_enc->funcs->get_max_link_cap) { + link->link_enc->funcs->get_max_link_cap(link->link_enc, max_link_enc_cap); return true; } @@ -3186,37 +2038,12 @@ bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_ return false; } -static struct dc_link_settings get_max_link_cap(struct dc_link *link, - const struct link_resource *link_res) +static struct dc_link_settings get_max_link_cap(struct dc_link *link) { struct dc_link_settings max_link_cap = {0}; -#if defined(CONFIG_DRM_AMD_DC_DCN) - enum dc_link_rate lttpr_max_link_rate; -#endif - struct link_encoder *link_enc = NULL; - - /* Links supporting dynamically assigned link encoder will be assigned next - * available encoder if one not already assigned. - */ - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) { - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); - if (link_enc == NULL) - link_enc = link_enc_cfg_get_next_avail_link_enc(link->ctx->dc); - } else - link_enc = link->link_enc; - ASSERT(link_enc); /* get max link encoder capability */ - if (link_enc) - link_enc->funcs->get_max_link_cap(link_enc, &max_link_cap); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (max_link_cap.link_rate >= LINK_RATE_UHBR10) { - if (!link_res->hpo_dp_link_enc || - link->dc->debug.disable_uhbr) - max_link_cap.link_rate = LINK_RATE_HIGH3; - } -#endif + link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap); /* Lower link settings based on sink's link cap */ if (link->reported_link_cap.lane_count < max_link_cap.lane_count) @@ -3233,19 +2060,12 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link, * account for lttpr repeaters cap * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3). */ - if (link->lttpr_mode != LTTPR_MODE_NON_LTTPR) { + if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; -#if defined(CONFIG_DRM_AMD_DC_DCN) - lttpr_max_link_rate = get_lttpr_max_link_rate(link); - - if (lttpr_max_link_rate < max_link_cap.link_rate) - max_link_cap.link_rate = lttpr_max_link_rate; -#else if (link->dpcd_caps.lttpr_caps.max_link_rate < max_link_cap.link_rate) max_link_cap.link_rate = link->dpcd_caps.lttpr_caps.max_link_rate; -#endif DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR, max_lane count %d max_link rate %d \n", __func__, @@ -3255,7 +2075,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link, return max_link_cap; } -static enum dc_status read_hpd_rx_irq_data( +enum dc_status read_hpd_rx_irq_data( struct dc_link *link, union hpd_irq_data *irq_data) { @@ -3372,7 +2192,6 @@ bool hpd_rx_irq_check_link_loss_status( bool dp_verify_link_cap( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *known_limit_link_setting, int *fail_count) { @@ -3387,32 +2206,17 @@ bool dp_verify_link_cap( enum link_training_result status; union hpd_irq_data irq_data; - /* link training starts with the maximum common settings - * supported by both sink and ASIC. - */ - max_link_cap = get_max_link_cap(link, link_res); - initial_link_settings = get_common_supported_link_settings( - *known_limit_link_setting, - max_link_cap); - - /* Accept reported capabilities if link supports flexible encoder mapping or encoder already in use. */ - if (link->dc->debug.skip_detection_link_training || - link->is_dig_mapping_flexible) { - /* TODO - should we check link encoder's max link caps here? - * How do we know which link encoder to check from? - */ + if (link->dc->debug.skip_detection_link_training) { link->verified_link_cap = *known_limit_link_setting; return true; - } else if (link->link_enc && link->dc->res_pool->funcs->link_encs_assign && - !link_enc_cfg_is_link_enc_avail(link->ctx->dc, link->link_enc->preferred_engine, link)) { - link->verified_link_cap = initial_link_settings; - return true; } memset(&irq_data, 0, sizeof(irq_data)); success = false; skip_link_training = false; + max_link_cap = get_max_link_cap(link); + /* Grant extended timeout request */ if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) { uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80; @@ -3420,30 +2224,32 @@ bool dp_verify_link_cap( core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant)); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING) - reset_dp_hpo_stream_encoders_for_link(link); -#endif /* TODO implement override and monitor patch later */ /* try to train the link from high to low to * find the physical link capability */ /* disable PHY done possible by BIOS, will be done by driver itself */ - dp_disable_link_phy(link, link_res, link->connector_signal); + dp_disable_link_phy(link, link->connector_signal); dp_cs_id = get_clock_source_id(link); + /* link training starts with the maximum common settings + * supported by both sink and ASIC. + */ + initial_link_settings = get_common_supported_link_settings( + *known_limit_link_setting, + max_link_cap); cur_link_setting = initial_link_settings; /* Temporary Renoir-specific workaround for SWDEV-215184; * PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle, * so add extra cycle of enabling and disabling the PHY before first link training. */ - if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C && + if (link->link_enc->features.flags.bits.DP_IS_USB_C && link->dc->debug.usbc_combo_phy_reset_wa) { - dp_enable_link_phy(link, link_res, link->connector_signal, dp_cs_id, cur); - dp_disable_link_phy(link, link_res, link->connector_signal); + dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur); + dp_disable_link_phy(link, link->connector_signal); } do { @@ -3454,7 +2260,6 @@ bool dp_verify_link_cap( dp_enable_link_phy( link, - link_res, link->connector_signal, dp_cs_id, cur); @@ -3465,7 +2270,6 @@ bool dp_verify_link_cap( else { status = dc_link_dp_perform_link_training( link, - link_res, cur, skip_video_pattern); if (status == LINK_TRAINING_SUCCESS) @@ -3487,8 +2291,8 @@ bool dp_verify_link_cap( * setting or before returning we'll enable it later * based on the actual mode we're driving */ - dp_disable_link_phy(link, link_res, link->connector_signal); - } while (!success && decide_fallback_link_setting(link, + dp_disable_link_phy(link, link->connector_signal); + } while (!success && decide_fallback_link_setting( initial_link_settings, cur, status)); /* Link Training failed for all Link Settings @@ -3511,7 +2315,6 @@ bool dp_verify_link_cap( bool dp_verify_link_cap_with_retries( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *known_limit_link_setting, int attempts) { @@ -3529,8 +2332,8 @@ bool dp_verify_link_cap_with_retries( link->verified_link_cap.link_rate = LINK_RATE_LOW; link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED; break; - } else if (dp_verify_link_cap(link, link_res, - known_limit_link_setting, + } else if (dp_verify_link_cap(link, + &link->reported_link_cap, &fail_count) && fail_count == 0) { success = true; break; @@ -3541,26 +2344,15 @@ bool dp_verify_link_cap_with_retries( } bool dp_verify_mst_link_cap( - struct dc_link *link, const struct link_resource *link_res) + struct dc_link *link) { struct dc_link_settings max_link_cap = {0}; - if (dp_get_link_encoding_format(&link->reported_link_cap) == - DP_8b_10b_ENCODING) { - max_link_cap = get_max_link_cap(link, link_res); - link->verified_link_cap = get_common_supported_link_settings( - link->reported_link_cap, - max_link_cap); - } -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (dp_get_link_encoding_format(&link->reported_link_cap) == - DP_128b_132b_ENCODING) { - dp_verify_link_cap_with_retries(link, - link_res, - &link->reported_link_cap, - LINK_TRAINING_MAX_VERIFY_RETRY); - } -#endif + max_link_cap = get_max_link_cap(link); + link->verified_link_cap = get_common_supported_link_settings( + link->reported_link_cap, + max_link_cap); + return true; } @@ -3587,17 +2379,7 @@ static struct dc_link_settings get_common_supported_link_settings( * We map it to the maximum supported link rate that * is smaller than MAX_LINK_BW in this case. */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (link_settings.link_rate > LINK_RATE_UHBR20) { - link_settings.link_rate = LINK_RATE_UHBR20; - } else if (link_settings.link_rate < LINK_RATE_UHBR20 && - link_settings.link_rate > LINK_RATE_UHBR13_5) { - link_settings.link_rate = LINK_RATE_UHBR13_5; - } else if (link_settings.link_rate < LINK_RATE_UHBR10 && - link_settings.link_rate > LINK_RATE_HIGH3) { -#else if (link_settings.link_rate > LINK_RATE_HIGH3) { -#endif link_settings.link_rate = LINK_RATE_HIGH3; } else if (link_settings.link_rate < LINK_RATE_HIGH3 && link_settings.link_rate > LINK_RATE_HIGH2) { @@ -3642,14 +2424,6 @@ static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count) static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate) { switch (link_rate) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - case LINK_RATE_UHBR20: - return LINK_RATE_UHBR13_5; - case LINK_RATE_UHBR13_5: - return LINK_RATE_UHBR10; - case LINK_RATE_UHBR10: - return LINK_RATE_HIGH3; -#endif case LINK_RATE_HIGH3: return LINK_RATE_HIGH2; case LINK_RATE_HIGH2: @@ -3684,55 +2458,11 @@ static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate) return LINK_RATE_HIGH2; case LINK_RATE_HIGH2: return LINK_RATE_HIGH3; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case LINK_RATE_HIGH3: - return LINK_RATE_UHBR10; - case LINK_RATE_UHBR10: - return LINK_RATE_UHBR13_5; - case LINK_RATE_UHBR13_5: - return LINK_RATE_UHBR20; -#endif default: return LINK_RATE_UNKNOWN; } } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static bool decide_fallback_link_setting_max_bw_policy( - const struct dc_link_settings *max, - struct dc_link_settings *cur) -{ - uint8_t cur_idx = 0, next_idx; - bool found = false; - - while (cur_idx < ARRAY_SIZE(dp_lt_fallbacks)) - /* find current index */ - if (dp_lt_fallbacks[cur_idx].lane_count == cur->lane_count && - dp_lt_fallbacks[cur_idx].link_rate == cur->link_rate) - break; - else - cur_idx++; - - next_idx = cur_idx + 1; - - while (next_idx < ARRAY_SIZE(dp_lt_fallbacks)) - /* find next index */ - if (dp_lt_fallbacks[next_idx].lane_count <= max->lane_count && - dp_lt_fallbacks[next_idx].link_rate <= max->link_rate) - break; - else - next_idx++; - - if (next_idx < ARRAY_SIZE(dp_lt_fallbacks)) { - cur->lane_count = dp_lt_fallbacks[next_idx].lane_count; - cur->link_rate = dp_lt_fallbacks[next_idx].link_rate; - found = true; - } - - return found; -} -#endif - /* * function: set link rate and lane count fallback based * on current link setting and last link training result @@ -3742,19 +2472,12 @@ static bool decide_fallback_link_setting_max_bw_policy( * and no further fallback could be done */ static bool decide_fallback_link_setting( - struct dc_link *link, struct dc_link_settings initial_link_settings, struct dc_link_settings *current_link_setting, enum link_training_result training_result) { if (!current_link_setting) return false; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING || - link->dc->debug.force_dp2_lt_fallback_method) - return decide_fallback_link_setting_max_bw_policy(&initial_link_settings, - current_link_setting); -#endif switch (training_result) { case LINK_TRAINING_CR_FAIL_LANE0: @@ -3974,148 +2697,6 @@ bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *lin return false; } -static bool decide_edp_link_settings_with_dsc(struct dc_link *link, - struct dc_link_settings *link_setting, - uint32_t req_bw, - enum dc_link_rate max_link_rate) -{ - struct dc_link_settings initial_link_setting; - struct dc_link_settings current_link_setting; - uint32_t link_bw; - - unsigned int policy = 0; - - policy = link->ctx->dc->debug.force_dsc_edp_policy; - if (max_link_rate == LINK_RATE_UNKNOWN) - max_link_rate = link->verified_link_cap.link_rate; - /* - * edp_supported_link_rates_count is only valid for eDP v1.4 or higher. - * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h" - */ - if ((link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 || - link->dpcd_caps.edp_supported_link_rates_count == 0)) { - /* for DSC enabled case, we search for minimum lane count */ - memset(&initial_link_setting, 0, sizeof(initial_link_setting)); - initial_link_setting.lane_count = LANE_COUNT_ONE; - initial_link_setting.link_rate = LINK_RATE_LOW; - initial_link_setting.link_spread = LINK_SPREAD_DISABLED; - initial_link_setting.use_link_rate_set = false; - initial_link_setting.link_rate_set = 0; - current_link_setting = initial_link_setting; - if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) - return false; - - /* search for the minimum link setting that: - * 1. is supported according to the link training result - * 2. could support the b/w requested by the timing - */ - while (current_link_setting.link_rate <= - max_link_rate) { - link_bw = dc_link_bandwidth_kbps( - link, - ¤t_link_setting); - if (req_bw <= link_bw) { - *link_setting = current_link_setting; - return true; - } - if (policy) { - /* minimize lane */ - if (current_link_setting.link_rate < max_link_rate) { - current_link_setting.link_rate = - increase_link_rate( - current_link_setting.link_rate); - } else { - if (current_link_setting.lane_count < - link->verified_link_cap.lane_count) { - current_link_setting.lane_count = - increase_lane_count( - current_link_setting.lane_count); - current_link_setting.link_rate = initial_link_setting.link_rate; - } else - break; - } - } else { - /* minimize link rate */ - if (current_link_setting.lane_count < - link->verified_link_cap.lane_count) { - current_link_setting.lane_count = - increase_lane_count( - current_link_setting.lane_count); - } else { - current_link_setting.link_rate = - increase_link_rate( - current_link_setting.link_rate); - current_link_setting.lane_count = - initial_link_setting.lane_count; - } - } - } - return false; - } - - /* if optimize edp link is supported */ - memset(&initial_link_setting, 0, sizeof(initial_link_setting)); - initial_link_setting.lane_count = LANE_COUNT_ONE; - initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0]; - initial_link_setting.link_spread = LINK_SPREAD_DISABLED; - initial_link_setting.use_link_rate_set = true; - initial_link_setting.link_rate_set = 0; - current_link_setting = initial_link_setting; - - /* search for the minimum link setting that: - * 1. is supported according to the link training result - * 2. could support the b/w requested by the timing - */ - while (current_link_setting.link_rate <= - max_link_rate) { - link_bw = dc_link_bandwidth_kbps( - link, - ¤t_link_setting); - if (req_bw <= link_bw) { - *link_setting = current_link_setting; - return true; - } - if (policy) { - /* minimize lane */ - if (current_link_setting.link_rate_set < - link->dpcd_caps.edp_supported_link_rates_count - && current_link_setting.link_rate < max_link_rate) { - current_link_setting.link_rate_set++; - current_link_setting.link_rate = - link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set]; - } else { - if (current_link_setting.lane_count < link->verified_link_cap.lane_count) { - current_link_setting.lane_count = - increase_lane_count( - current_link_setting.lane_count); - current_link_setting.link_rate_set = initial_link_setting.link_rate_set; - current_link_setting.link_rate = - link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set]; - } else - break; - } - } else { - /* minimize link rate */ - if (current_link_setting.lane_count < - link->verified_link_cap.lane_count) { - current_link_setting.lane_count = - increase_lane_count( - current_link_setting.lane_count); - } else { - if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { - current_link_setting.link_rate_set++; - current_link_setting.link_rate = - link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set]; - current_link_setting.lane_count = - initial_link_setting.lane_count; - } else - break; - } - } - } - return false; -} - static bool decide_mst_link_settings(const struct dc_link *link, struct dc_link_settings *link_setting) { *link_setting = link->verified_link_cap; @@ -4150,25 +2731,7 @@ void decide_link_settings(struct dc_stream_state *stream, if (decide_mst_link_settings(link, link_setting)) return; } else if (link->connector_signal == SIGNAL_TYPE_EDP) { - /* enable edp link optimization for DSC eDP case */ - if (stream->timing.flags.DSC) { - enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN; - - if (link->ctx->dc->debug.force_dsc_edp_policy) { - /* calculate link max link rate cap*/ - struct dc_link_settings tmp_link_setting; - struct dc_crtc_timing tmp_timing = stream->timing; - uint32_t orig_req_bw; - - tmp_link_setting.link_rate = LINK_RATE_UNKNOWN; - tmp_timing.flags.DSC = 0; - orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing); - decide_edp_link_settings(link, &tmp_link_setting, orig_req_bw); - max_link_rate = tmp_link_setting.link_rate; - } - if (decide_edp_link_settings_with_dsc(link, link_setting, req_bw, max_link_rate)) - return; - } else if (decide_edp_link_settings(link, link_setting, req_bw)) + if (decide_edp_link_settings(link, link_setting, req_bw)) return; } else if (decide_dp_link_settings(link, link_setting, req_bw)) return; @@ -4180,7 +2743,7 @@ void decide_link_settings(struct dc_stream_state *stream, } /*************************Short Pulse IRQ***************************/ -bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link) +static bool allow_hpd_rx_irq(const struct dc_link *link) { /* * Don't handle RX IRQ unless one of following is met: @@ -4209,6 +2772,7 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) &psr_configuration.raw, sizeof(psr_configuration.raw)); + if (psr_configuration.bits.ENABLE) { unsigned char dpcdbuf[3] = {0}; union psr_error_status psr_error_status; @@ -4229,8 +2793,6 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) if (psr_error_status.bits.LINK_CRC_ERROR || psr_error_status.bits.RFB_STORAGE_ERROR || psr_error_status.bits.VSC_SDP_ERROR) { - bool allow_active; - /* Acknowledge and clear error bits */ dm_helpers_dp_write_dpcd( link->ctx, @@ -4240,12 +2802,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) sizeof(psr_error_status.raw)); /* PSR error, disable and re-enable PSR */ - if (link->psr_settings.psr_allow_active) { - allow_active = false; - dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL); - allow_active = true; - dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL); - } + dc_link_set_psr_allow_active(link, false, true, false); + dc_link_set_psr_allow_active(link, true, true, false); return true; } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS == @@ -4292,24 +2850,20 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) union phy_test_pattern dpcd_test_pattern; union lane_adjust dpcd_lane_adjustment[2]; unsigned char dpcd_post_cursor_2_adjustment = 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) - unsigned char test_pattern_buffer[ - (DP_TEST_264BIT_CUSTOM_PATTERN_263_256 - - DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0}; -#else unsigned char test_pattern_buffer[ (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 - DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0}; -#endif unsigned int test_pattern_size = 0; enum dp_test_pattern test_pattern; + struct dc_link_training_settings link_settings; union lane_adjust dpcd_lane_adjust; unsigned int lane; struct link_training_settings link_training_settings; + int i = 0; dpcd_test_pattern.raw = 0; memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment)); - memset(&link_training_settings, 0, sizeof(link_training_settings)); + memset(&link_settings, 0, sizeof(link_settings)); /* get phy test pattern and pattern parameters from DP receiver */ core_link_read_dpcd( @@ -4323,13 +2877,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) &dpcd_lane_adjustment[0].raw, sizeof(dpcd_lane_adjustment)); - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) - vendor_specific_lttpr_wa_three_dpcd( - link, - link_training_settings.dpcd_lane_settings); - /*get post cursor 2 parameters * For DP 1.1a or eariler, this DPCD register's value is 0 * For DP 1.2 or later: @@ -4371,35 +2918,6 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) case PHY_TEST_PATTERN_CP2520_3: test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case PHY_TEST_PATTERN_128b_132b_TPS1: - test_pattern = DP_TEST_PATTERN_128b_132b_TPS1; - break; - case PHY_TEST_PATTERN_128b_132b_TPS2: - test_pattern = DP_TEST_PATTERN_128b_132b_TPS2; - break; - case PHY_TEST_PATTERN_PRBS9: - test_pattern = DP_TEST_PATTERN_PRBS9; - break; - case PHY_TEST_PATTERN_PRBS11: - test_pattern = DP_TEST_PATTERN_PRBS11; - break; - case PHY_TEST_PATTERN_PRBS15: - test_pattern = DP_TEST_PATTERN_PRBS15; - break; - case PHY_TEST_PATTERN_PRBS23: - test_pattern = DP_TEST_PATTERN_PRBS23; - break; - case PHY_TEST_PATTERN_PRBS31: - test_pattern = DP_TEST_PATTERN_PRBS31; - break; - case PHY_TEST_PATTERN_264BIT_CUSTOM: - test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM; - break; - case PHY_TEST_PATTERN_SQUARE_PULSE: - test_pattern = DP_TEST_PATTERN_SQUARE_PULSE; - break; -#endif default: test_pattern = DP_TEST_PATTERN_VIDEO_MODE; break; @@ -4415,59 +2933,30 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) test_pattern_size); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) { - test_pattern_size = 1; // Square pattern data is 1 byte (DP spec) - core_link_read_dpcd( - link, - DP_PHY_SQUARE_PATTERN, - test_pattern_buffer, - test_pattern_size); - } - - if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) { - test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256- - DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1; - core_link_read_dpcd( - link, - DP_TEST_264BIT_CUSTOM_PATTERN_7_0, - test_pattern_buffer, - test_pattern_size); - } -#endif - /* prepare link training settings */ - link_training_settings.link_settings = link->cur_link_settings; + link_settings.link = link->cur_link_settings; for (lane = 0; lane < (unsigned int)(link->cur_link_settings.lane_count); lane++) { dpcd_lane_adjust.raw = get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane); - if (dp_get_link_encoding_format(&link->cur_link_settings) == - DP_8b_10b_ENCODING) { - link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING = - (enum dc_voltage_swing) - (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE); - link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS = - (enum dc_pre_emphasis) - (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE); - link_training_settings.hw_lane_settings[lane].POST_CURSOR2 = - (enum dc_post_cursor2) - ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03); - } -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if (dp_get_link_encoding_format(&link->cur_link_settings) == - DP_128b_132b_ENCODING) { - link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw = - dpcd_lane_adjust.tx_ffe.PRESET_VALUE; - } -#endif + link_settings.lane_settings[lane].VOLTAGE_SWING = + (enum dc_voltage_swing) + (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE); + link_settings.lane_settings[lane].PRE_EMPHASIS = + (enum dc_pre_emphasis) + (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE); + link_settings.lane_settings[lane].POST_CURSOR2 = + (enum dc_post_cursor2) + ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03); } - dp_hw_to_dpcd_lane_settings(&link_training_settings, - link_training_settings.hw_lane_settings, - link_training_settings.dpcd_lane_settings); + for (i = 0; i < 4; i++) + link_training_settings.lane_settings[i] = + link_settings.lane_settings[i]; + link_training_settings.link_settings = link_settings.link; + link_training_settings.allow_invalid_msa_timing_param = false; /*Usage: Measure DP physical lane signal * by DP SI test equipment automatically. * PHY test pattern request is generated by equipment via HPD interrupt. @@ -4688,7 +3177,7 @@ static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video } } -void dc_link_dp_handle_automated_test(struct dc_link *link) +static void handle_automated_test(struct dc_link *link) { union test_request test_request; union test_response test_response; @@ -4737,50 +3226,17 @@ void dc_link_dp_handle_automated_test(struct dc_link *link) sizeof(test_response)); } -void dc_link_dp_handle_link_loss(struct dc_link *link) +bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss) { - int i; - struct pipe_ctx *pipe_ctx; - - for (i = 0; i < MAX_PIPES; i++) { - pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) - break; - } - - if (pipe_ctx == NULL || pipe_ctx->stream == NULL) - return; - - for (i = 0; i < MAX_PIPES; i++) { - pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && - pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) { - core_link_disable_stream(pipe_ctx); - } - } - - for (i = 0; i < MAX_PIPES; i++) { - pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; - if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && - pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) { - core_link_enable_stream(link->dc->current_state, pipe_ctx); - } - } -} - -bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss, - bool defer_handling, bool *has_left_work) -{ - union hpd_irq_data hpd_irq_dpcd_data = {0}; - union device_service_irq device_service_clear = {0}; + union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } }; + union device_service_irq device_service_clear = { { 0 } }; enum dc_status result; bool status = false; + struct pipe_ctx *pipe_ctx; + int i; if (out_link_loss) *out_link_loss = false; - - if (has_left_work) - *has_left_work = false; /* For use cases related to down stream connection status change, * PSR and device auto test, refer to function handle_sst_hpd_irq * in DAL2.1*/ @@ -4812,14 +3268,11 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd &device_service_clear.raw, sizeof(device_service_clear.raw)); device_service_clear.raw = 0; - if (defer_handling && has_left_work) - *has_left_work = true; - else - dc_link_dp_handle_automated_test(link); + handle_automated_test(link); return false; } - if (!dc_link_dp_allow_hpd_rx_irq(link)) { + if (!allow_hpd_rx_irq(link)) { DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n", __func__, link->link_index); return false; @@ -4833,18 +3286,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd * so do not handle as a normal sink status change interrupt. */ - if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) { - if (defer_handling && has_left_work) - *has_left_work = true; + if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) return true; - } /* check if we have MST msg and return since we poll for it */ - if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) { - if (defer_handling && has_left_work) - *has_left_work = true; + if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) return false; - } /* For now we only handle 'Downstream port status' case. * If we got sink count changed it means @@ -4861,10 +3308,29 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd sizeof(hpd_irq_dpcd_data), "Status: "); - if (defer_handling && has_left_work) - *has_left_work = true; - else - dc_link_dp_handle_link_loss(link); + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) + break; + } + + if (pipe_ctx == NULL || pipe_ctx->stream == NULL) + return false; + + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) + core_link_disable_stream(pipe_ctx); + } + + for (i = 0; i < MAX_PIPES; i++) { + pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; + if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off && + pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) + core_link_enable_stream(link->dc->current_state, pipe_ctx); + } status = false; if (out_link_loss) @@ -4949,56 +3415,6 @@ static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc) return -1; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw) -{ - switch (bw) { - case 0b001: - return 9000000; - case 0b010: - return 18000000; - case 0b011: - return 24000000; - case 0b100: - return 32000000; - case 0b101: - return 40000000; - case 0b110: - return 48000000; - } - - return 0; -} - -/** - * Return PCON's post FRL link training supported BW if its non-zero, otherwise return max_supported_frl_bw. - */ -static uint32_t intersect_frl_link_bw_support( - const uint32_t max_supported_frl_bw_in_kbps, - const union hdmi_encoded_link_bw hdmi_encoded_link_bw) -{ - uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps; - - // HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode) - if (hdmi_encoded_link_bw.bits.FRL_MODE) { - if (hdmi_encoded_link_bw.bits.BW_48Gbps) - supported_bw_in_kbps = 48000000; - else if (hdmi_encoded_link_bw.bits.BW_40Gbps) - supported_bw_in_kbps = 40000000; - else if (hdmi_encoded_link_bw.bits.BW_32Gbps) - supported_bw_in_kbps = 32000000; - else if (hdmi_encoded_link_bw.bits.BW_24Gbps) - supported_bw_in_kbps = 24000000; - else if (hdmi_encoded_link_bw.bits.BW_18Gbps) - supported_bw_in_kbps = 18000000; - else if (hdmi_encoded_link_bw.bits.BW_9Gbps) - supported_bw_in_kbps = 9000000; - } - - return supported_bw_in_kbps; -} -#endif - static void read_dp_device_vendor_id(struct dc_link *link) { struct dp_device_vendor_id dp_id; @@ -5110,27 +3526,6 @@ static void get_active_converter_info( translate_dpcd_max_bpc( hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (link->dc->caps.hdmi_frl_pcon_support) { - union hdmi_encoded_link_bw hdmi_encoded_link_bw; - - link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = - dc_link_bw_kbps_from_raw_frl_link_rate_data( - hdmi_color_caps.bits.MAX_ENCODED_LINK_BW_SUPPORT); - - // Intersect reported max link bw support with the supported link rate post FRL link training - if (core_link_read_dpcd(link, DP_PCON_HDMI_POST_FRL_STATUS, - &hdmi_encoded_link_bw.raw, sizeof(hdmi_encoded_link_bw)) == DC_OK) { - link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = intersect_frl_link_bw_support( - link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps, - hdmi_encoded_link_bw); - } - - if (link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps > 0) - link->dpcd_caps.dongle_caps.extendedCapValid = true; - } -#endif - if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0) link->dpcd_caps.dongle_caps.extendedCapValid = true; } @@ -5159,43 +3554,6 @@ static void get_active_converter_info( dp_hw_fw_revision.ieee_fw_rev, sizeof(dp_hw_fw_revision.ieee_fw_rev)); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && - link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) { - union dp_dfp_cap_ext dfp_cap_ext; - memset(&dfp_cap_ext, '\0', sizeof (dfp_cap_ext)); - core_link_read_dpcd( - link, - DP_DFP_CAPABILITY_EXTENSION_SUPPORT, - dfp_cap_ext.raw, - sizeof(dfp_cap_ext.raw)); - link->dpcd_caps.dongle_caps.dfp_cap_ext.supported = dfp_cap_ext.fields.supported; - link->dpcd_caps.dongle_caps.dfp_cap_ext.max_pixel_rate_in_mps = - dfp_cap_ext.fields.max_pixel_rate_in_mps[0] + - (dfp_cap_ext.fields.max_pixel_rate_in_mps[1] << 8); - link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width = - dfp_cap_ext.fields.max_video_h_active_width[0] + - (dfp_cap_ext.fields.max_video_h_active_width[1] << 8); - link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height = - dfp_cap_ext.fields.max_video_v_active_height[0] + - (dfp_cap_ext.fields.max_video_v_active_height[1] << 8); - link->dpcd_caps.dongle_caps.dfp_cap_ext.encoding_format_caps = - dfp_cap_ext.fields.encoding_format_caps; - link->dpcd_caps.dongle_caps.dfp_cap_ext.rgb_color_depth_caps = - dfp_cap_ext.fields.rgb_color_depth_caps; - link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr444_color_depth_caps = - dfp_cap_ext.fields.ycbcr444_color_depth_caps; - link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr422_color_depth_caps = - dfp_cap_ext.fields.ycbcr422_color_depth_caps; - link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr420_color_depth_caps = - dfp_cap_ext.fields.ycbcr420_color_depth_caps; - DC_LOG_DP2("DFP capability extension is read at link %d", link->link_index); - DC_LOG_DP2("\tdfp_cap_ext.supported = %s", link->dpcd_caps.dongle_caps.dfp_cap_ext.supported ? "true" : "false"); - DC_LOG_DP2("\tdfp_cap_ext.max_pixel_rate_in_mps = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_pixel_rate_in_mps); - DC_LOG_DP2("\tdfp_cap_ext.max_video_h_active_width = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width); - DC_LOG_DP2("\tdfp_cap_ext.max_video_v_active_height = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height); - } -#endif } static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data, @@ -5255,12 +3613,7 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link) bool dp_retrieve_lttpr_cap(struct dc_link *link) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t lttpr_dpcd_data[8]; - bool allow_lttpr_non_transparent_mode = 0; -#else uint8_t lttpr_dpcd_data[6]; -#endif bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable; bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware; enum dc_status status = DC_ERROR_UNEXPECTED; @@ -5268,16 +3621,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data)); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 && - link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) { - allow_lttpr_non_transparent_mode = 1; - } else if (link->dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A && - !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { - allow_lttpr_non_transparent_mode = 1; - } -#endif - /* * Logic to determine LTTPR mode */ @@ -5285,31 +3628,17 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) if (vbios_lttpr_enable && vbios_lttpr_interop) link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; else if (!vbios_lttpr_enable && vbios_lttpr_interop) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (allow_lttpr_non_transparent_mode) -#else if (link->dc->config.allow_lttpr_non_transparent_mode) -#endif link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; else link->lttpr_mode = LTTPR_MODE_TRANSPARENT; } else if (!vbios_lttpr_enable && !vbios_lttpr_interop) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (!allow_lttpr_non_transparent_mode || !link->dc->caps.extended_aux_timeout_support) -#else if (!link->dc->config.allow_lttpr_non_transparent_mode || !link->dc->caps.extended_aux_timeout_support) -#endif link->lttpr_mode = LTTPR_MODE_NON_LTTPR; else link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT; } -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* Check DP tunnel LTTPR mode debug option. */ - if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && - link->dc->debug.dpia_debug.bits.force_non_lttpr) - link->lttpr_mode = LTTPR_MODE_NON_LTTPR; -#endif if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { /* By reading LTTPR capability, RX assumes that we will enable @@ -5321,7 +3650,9 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) lttpr_dpcd_data, sizeof(lttpr_dpcd_data)); if (status != DC_OK) { +#if defined(CONFIG_DRM_AMD_DC_DCN) DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__); +#endif return false; } @@ -5349,19 +3680,8 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link) lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; -#if defined(CONFIG_DRM_AMD_DC_DCN) - link->dpcd_caps.lttpr_caps.main_link_channel_coding.raw = - lttpr_dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER - - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; - - link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw = - lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES - - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; -#endif - /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */ is_lttpr_present = (dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) != 0 && - link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff && link->dpcd_caps.lttpr_caps.max_lane_count > 0 && link->dpcd_caps.lttpr_caps.max_lane_count <= 4 && link->dpcd_caps.lttpr_caps.revision.raw >= 0x14); @@ -5410,8 +3730,6 @@ static bool retrieve_link_cap(struct dc_link *link) LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD); is_lttpr_present = dp_retrieve_lttpr_cap(link); - /* Read DP tunneling information. */ - status = dpcd_get_tunneling_device_data(link); status = core_link_read_dpcd(link, DP_SET_POWER, &dpcd_power_state, sizeof(dpcd_power_state)); @@ -5632,82 +3950,16 @@ static bool retrieve_link_cap(struct dc_link *link) DP_DSC_SUPPORT, link->dpcd_caps.dsc_caps.dsc_basic_caps.raw, sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw)); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) { - status = core_link_read_dpcd( - link, - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, - link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw, - sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw)); - DC_LOG_DSC("DSC branch decoder capability is read at link %d", link->link_index); - DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_0 = 0x%02x", - link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_0); - DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_1 = 0x%02x", - link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_1); - DC_LOG_DSC("\tBRANCH_MAX_LINE_WIDTH 0x%02x", - link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_MAX_LINE_WIDTH); - } -#else status = core_link_read_dpcd( link, DP_DSC_BRANCH_OVERALL_THROUGHPUT_0, link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw, sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw)); -#endif } if (!dpcd_read_sink_ext_caps(link)) link->dpcd_sink_ext_caps.raw = 0; -#if defined(CONFIG_DRM_AMD_DC_DCN) - link->dpcd_caps.channel_coding_cap.raw = dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_CAP - DP_DPCD_REV]; - - if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { - DC_LOG_DP2("128b/132b encoding is supported at link %d", link->link_index); - - core_link_read_dpcd(link, - DP_128b_132b_SUPPORTED_LINK_RATES, - &link->dpcd_caps.dp_128b_132b_supported_link_rates.raw, - sizeof(link->dpcd_caps.dp_128b_132b_supported_link_rates.raw)); - if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR20) - link->reported_link_cap.link_rate = LINK_RATE_UHBR20; - else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5) - link->reported_link_cap.link_rate = LINK_RATE_UHBR13_5; - else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR10) - link->reported_link_cap.link_rate = LINK_RATE_UHBR10; - else - dm_error("%s: Invalid RX 128b_132b_supported_link_rates\n", __func__); - DC_LOG_DP2("128b/132b supported link rates is read at link %d", link->link_index); - DC_LOG_DP2("\tmax 128b/132b link rate support is %d.%d GHz", - link->reported_link_cap.link_rate / 100, - link->reported_link_cap.link_rate % 100); - - core_link_read_dpcd(link, - DP_SINK_VIDEO_FALLBACK_FORMATS, - &link->dpcd_caps.fallback_formats.raw, - sizeof(link->dpcd_caps.fallback_formats.raw)); - DC_LOG_DP2("sink video fallback format is read at link %d", link->link_index); - if (link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support) - DC_LOG_DP2("\t1920x1080@60Hz 24bpp fallback format supported"); - if (link->dpcd_caps.fallback_formats.bits.dp_1280x720_60Hz_24bpp_support) - DC_LOG_DP2("\t1280x720@60Hz 24bpp fallback format supported"); - if (link->dpcd_caps.fallback_formats.bits.dp_1024x768_60Hz_24bpp_support) - DC_LOG_DP2("\t1024x768@60Hz 24bpp fallback format supported"); - if (link->dpcd_caps.fallback_formats.raw == 0) { - DC_LOG_DP2("\tno supported fallback formats, assume 1920x1080@60Hz 24bpp is supported"); - link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support = 1; - } - - core_link_read_dpcd(link, - DP_FEC_CAPABILITY_1, - &link->dpcd_caps.fec_cap1.raw, - sizeof(link->dpcd_caps.fec_cap1.raw)); - DC_LOG_DP2("FEC CAPABILITY 1 is read at link %d", link->link_index); - if (link->dpcd_caps.fec_cap1.bits.AGGREGATED_ERROR_COUNTERS_CAPABLE) - DC_LOG_DP2("\tFEC aggregated error counters are supported"); - } -#endif - /* Connectivity log: detection */ CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: "); @@ -6105,7 +4357,7 @@ bool dc_link_dp_set_test_pattern( DP_TEST_PATTERN_VIDEO_MODE) { /* Set CRTC Test Pattern */ set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space); - dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern, + dp_set_hw_test_pattern(link, test_pattern, (uint8_t *)p_custom_pattern, (uint32_t)cust_pattern_size); @@ -6127,18 +4379,8 @@ bool dc_link_dp_set_test_pattern( if (is_dp_phy_pattern(test_pattern)) { /* Set DPCD Lane Settings before running test pattern */ if (p_link_settings != NULL) { - if (link->dc->debug.apply_vendor_specific_lttpr_wa && - (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - link->lttpr_mode == LTTPR_MODE_TRANSPARENT) { - dpcd_set_lane_settings(link, p_link_settings, DPRX); - vendor_specific_lttpr_wa_five( - link, - p_link_settings->dpcd_lane_settings, - p_link_settings->link_settings.lane_count); - } else { - dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX); - dpcd_set_lane_settings(link, p_link_settings, DPRX); - } + dp_set_hw_lane_settings(link, p_link_settings, DPRX); + dpcd_set_lane_settings(link, p_link_settings, DPRX); } /* Blank stream if running test pattern */ @@ -6148,10 +4390,10 @@ bool dc_link_dp_set_test_pattern( * MuteAudioEndpoint(pPathMode->pDisplayPath, true); */ /* Blank stream */ - pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); + pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); } - dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern, + dp_set_hw_test_pattern(link, test_pattern, (uint8_t *)p_custom_pattern, (uint32_t)cust_pattern_size); @@ -6188,35 +4430,6 @@ bool dc_link_dp_set_test_pattern( case DP_TEST_PATTERN_CP2520_3: pattern = PHY_TEST_PATTERN_CP2520_3; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_TEST_PATTERN_128b_132b_TPS1: - pattern = PHY_TEST_PATTERN_128b_132b_TPS1; - break; - case DP_TEST_PATTERN_128b_132b_TPS2: - pattern = PHY_TEST_PATTERN_128b_132b_TPS2; - break; - case DP_TEST_PATTERN_PRBS9: - pattern = PHY_TEST_PATTERN_PRBS9; - break; - case DP_TEST_PATTERN_PRBS11: - pattern = PHY_TEST_PATTERN_PRBS11; - break; - case DP_TEST_PATTERN_PRBS15: - pattern = PHY_TEST_PATTERN_PRBS15; - break; - case DP_TEST_PATTERN_PRBS23: - pattern = PHY_TEST_PATTERN_PRBS23; - break; - case DP_TEST_PATTERN_PRBS31: - pattern = PHY_TEST_PATTERN_PRBS31; - break; - case DP_TEST_PATTERN_264BIT_CUSTOM: - pattern = PHY_TEST_PATTERN_264BIT_CUSTOM; - break; - case DP_TEST_PATTERN_SQUARE_PULSE: - pattern = PHY_TEST_PATTERN_SQUARE_PULSE; - break; -#endif default: return false; } @@ -6226,14 +4439,6 @@ bool dc_link_dp_set_test_pattern( return false; if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) - core_link_write_dpcd(link, - DP_LINK_SQUARE_PATTERN, - p_custom_pattern, - 1); - -#endif /* tell receiver that we are sending qualification * pattern DP 1.2 or later - DP receiver's link quality * pattern is set using DPCD LINK_QUAL_LANEx_SET @@ -6471,7 +4676,7 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link) return DP_PANEL_MODE_DEFAULT; } -enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready) +enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready) { /* FEC has to be "set ready" before the link training. * The policy is to always train with FEC @@ -6487,7 +4692,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource */ if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); else link_enc = link->link_enc; ASSERT(link_enc); @@ -6534,7 +4739,8 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) */ if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link( + link->dc->current_state, link); else link_enc = link->link_enc; ASSERT(link_enc); @@ -6562,23 +4768,6 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) } } -struct link_encoder *dp_get_link_enc(struct dc_link *link) -{ - struct link_encoder *link_enc; - - link_enc = link->link_enc; - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) { - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, - link); - if (!link->link_enc) - link_enc = link_enc_cfg_get_next_avail_link_enc( - link->ctx->dc); - } - - return link_enc; -} - void dpcd_set_source_specific_data(struct dc_link *link) { if (!link->dc->vendor_signature.is_valid) { @@ -6771,7 +4960,7 @@ bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timin uint8_t link_bw_set; uint8_t link_rate_set; uint32_t req_bw; - union lane_count_set lane_count_set = {0}; + union lane_count_set lane_count_set = { {0} }; ASSERT(link || crtc_timing); // invalid input @@ -6799,10 +4988,7 @@ bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timin req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing); - if (!crtc_timing->flags.DSC) - decide_edp_link_settings(link, &link_setting, req_bw); - else - decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN); + decide_edp_link_settings(link, &link_setting, req_bw); if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate || lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) { @@ -6819,240 +5005,6 @@ enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings if ((link_settings->link_rate >= LINK_RATE_LOW) && (link_settings->link_rate <= LINK_RATE_HIGH3)) return DP_8b_10b_ENCODING; -#if defined(CONFIG_DRM_AMD_DC_DCN) - else if ((link_settings->link_rate >= LINK_RATE_UHBR10) && - (link_settings->link_rate <= LINK_RATE_UHBR20)) - return DP_128b_132b_ENCODING; -#endif return DP_UNKNOWN_ENCODING; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link) -{ - struct dc_link_settings link_settings = {0}; - - if (!dc_is_dp_signal(link->connector_signal)) - return DP_UNKNOWN_ENCODING; - - if (link->preferred_link_setting.lane_count != - LANE_COUNT_UNKNOWN && - link->preferred_link_setting.link_rate != - LINK_RATE_UNKNOWN) { - link_settings = link->preferred_link_setting; - } else { - decide_mst_link_settings(link, &link_settings); - } - - return dp_get_link_encoding_format(&link_settings); -} - -// TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST) -static void get_lane_status( - struct dc_link *link, - uint32_t lane_count, - union lane_status *status, - union lane_align_status_updated *status_updated) -{ - unsigned int lane; - uint8_t dpcd_buf[3] = {0}; - - if (status == NULL || status_updated == NULL) { - return; - } - - core_link_read_dpcd( - link, - DP_LANE0_1_STATUS, - dpcd_buf, - sizeof(dpcd_buf)); - - for (lane = 0; lane < lane_count; lane++) { - status[lane].raw = get_nibble_at_index(&dpcd_buf[0], lane); - } - - status_updated->raw = dpcd_buf[2]; -} - -bool dpcd_write_128b_132b_sst_payload_allocation_table( - const struct dc_stream_state *stream, - struct dc_link *link, - struct link_mst_stream_allocation_table *proposed_table, - bool allocate) -{ - const uint8_t vc_id = 1; /// VC ID always 1 for SST - const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST - bool result = false; - uint8_t req_slot_count = 0; - struct fixed31_32 avg_time_slots_per_mtp = { 0 }; - union payload_table_update_status update_status = { 0 }; - const uint32_t max_retries = 30; - uint32_t retries = 0; - - if (allocate) { - avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link); - req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp); - } else { - /// Leave req_slot_count = 0 if allocate is false. - } - - /// Write DPCD 2C0 = 1 to start updating - update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1; - core_link_write_dpcd( - link, - DP_PAYLOAD_TABLE_UPDATE_STATUS, - &update_status.raw, - 1); - - /// Program the changes in DPCD 1C0 - 1C2 - ASSERT(vc_id == 1); - core_link_write_dpcd( - link, - DP_PAYLOAD_ALLOCATE_SET, - &vc_id, - 1); - - ASSERT(start_time_slot == 0); - core_link_write_dpcd( - link, - DP_PAYLOAD_ALLOCATE_START_TIME_SLOT, - &start_time_slot, - 1); - - ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT); /// Validation should filter out modes that exceed link BW - core_link_write_dpcd( - link, - DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT, - &req_slot_count, - 1); - - /// Poll till DPCD 2C0 read 1 - /// Try for at least 150ms (30 retries, with 5ms delay after each attempt) - - while (retries < max_retries) { - if (core_link_read_dpcd( - link, - DP_PAYLOAD_TABLE_UPDATE_STATUS, - &update_status.raw, - 1) == DC_OK) { - if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) { - DC_LOG_DP2("SST Update Payload: downstream payload table updated."); - result = true; - break; - } - } else { - union dpcd_rev dpcdRev; - - if (core_link_read_dpcd( - link, - DP_DPCD_REV, - &dpcdRev.raw, - 1) != DC_OK) { - DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision " - "of sink while polling payload table " - "updated status bit."); - break; - } - } - retries++; - msleep(5); - } - - if (!result && retries == max_retries) { - DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, " - "continue on. Something is wrong with the branch."); - // TODO - DP2.0 Payload: Read and log the payload table from downstream branch - } - - proposed_table->stream_count = 1; /// Always 1 stream for SST - proposed_table->stream_allocations[0].slot_count = req_slot_count; - proposed_table->stream_allocations[0].vcp_id = vc_id; - - return result; -} - -bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link) -{ - /* - * wait for ACT handled - */ - int i; - const int act_retries = 30; - enum act_return_status result = ACT_FAILED; - union payload_table_update_status update_status = {0}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; - union lane_align_status_updated lane_status_updated; - - for (i = 0; i < act_retries; i++) { - get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated); - - if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) || - !dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) || - !dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) || - !dp_is_interlane_aligned(lane_status_updated)) { - DC_LOG_ERROR("SST Update Payload: Link loss occurred while " - "polling for ACT handled."); - result = ACT_LINK_LOST; - break; - } - core_link_read_dpcd( - link, - DP_PAYLOAD_TABLE_UPDATE_STATUS, - &update_status.raw, - 1); - - if (update_status.bits.ACT_HANDLED == 1) { - DC_LOG_DP2("SST Update Payload: ACT handled by downstream."); - result = ACT_SUCCESS; - break; - } - - msleep(5); - } - - if (result == ACT_FAILED) { - DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, " - "continue on. Something is wrong with the branch."); - } - - return (result == ACT_SUCCESS); -} - -struct fixed31_32 calculate_sst_avg_time_slots_per_mtp( - const struct dc_stream_state *stream, - const struct dc_link *link) -{ - struct fixed31_32 link_bw_effective = - dc_fixpt_from_int( - dc_link_bandwidth_kbps(link, &link->cur_link_settings)); - struct fixed31_32 timeslot_bw_effective = - dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT); - struct fixed31_32 timing_bw = - dc_fixpt_from_int( - dc_bandwidth_in_kbps_from_timing(&stream->timing)); - struct fixed31_32 avg_time_slots_per_mtp = - dc_fixpt_div(timing_bw, timeslot_bw_effective); - - return avg_time_slots_per_mtp; -} - -bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx) -{ - /* If this assert is hit then we have a link encoder dynamic management issue */ - ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true); - return (pipe_ctx->stream_res.hpo_dp_stream_enc && - pipe_ctx->link_res.hpo_dp_link_enc && - dc_is_dp_signal(pipe_ctx->stream->signal)); -} -#endif - -void edp_panel_backlight_power_on(struct dc_link *link) -{ - if (link->connector_signal != SIGNAL_TYPE_EDP) - return; - - link->dc->hwss.edp_power_control(link, true); - link->dc->hwss.edp_wait_for_hpd_ready(link, true); - if (link->dc->hwss.edp_backlight_control) - link->dc->hwss.edp_backlight_control(link, true); -} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c index 7f25c11f42..72970e4980 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c @@ -176,15 +176,12 @@ static void dpcd_reduce_address_range( uint8_t * const reduced_data, const uint32_t reduced_size) { + const uint32_t reduced_end_address = END_ADDRESS(reduced_address, reduced_size); + const uint32_t extended_end_address = END_ADDRESS(extended_address, extended_size); const uint32_t offset = reduced_address - extended_address; - /* - * If the address is same, address was not extended. - * So we do not need to free any memory. - * The data is in original buffer(reduced_data). - */ - if (extended_data == reduced_data) - return; + if (extended_end_address == reduced_end_address && extended_address == reduced_address) + return; /* extended and reduced address ranges point to the same data */ memcpy(&extended_data[offset], reduced_data, reduced_size); kfree(extended_data); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c index a55944da8d..de80a9ea4c 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_enc_cfg.c @@ -1,4 +1,5 @@ -/* Copyright 2021 Advanced Micro Devices, Inc. All rights reserved. +/* + * Copyright 2021 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,132 +35,78 @@ static bool is_dig_link_enc_stream(struct dc_stream_state *stream) int i; /* Loop over created link encoder objects. */ - if (stream) { - for (i = 0; i < stream->ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { - link_enc = stream->ctx->dc->res_pool->link_encoders[i]; + for (i = 0; i < stream->ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { + link_enc = stream->ctx->dc->res_pool->link_encoders[i]; - /* Need to check link signal type rather than stream signal type which may not - * yet match. - */ - if (link_enc && ((uint32_t)stream->link->connector_signal & link_enc->output_signals)) { - if (dc_is_dp_signal(stream->signal)) { - /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ - struct dc_link_settings link_settings = {0}; + if (link_enc && + ((uint32_t)stream->signal & link_enc->output_signals)) { + if (dc_is_dp_signal(stream->signal)) { + /* DIGs do not support DP2.0 streams with 128b/132b encoding. */ + struct dc_link_settings link_settings = {0}; - decide_link_settings(stream, &link_settings); - if ((link_settings.link_rate >= LINK_RATE_LOW) && - link_settings.link_rate <= LINK_RATE_HIGH3) { - is_dig_stream = true; - break; - } - } else { + decide_link_settings(stream, &link_settings); + if ((link_settings.link_rate >= LINK_RATE_LOW) && + link_settings.link_rate <= LINK_RATE_HIGH3) { is_dig_stream = true; break; } - } - } - } - return is_dig_stream; -} - -static struct link_enc_assignment get_assignment(struct dc *dc, int i) -{ - struct link_enc_assignment assignment; - - if (dc->current_state->res_ctx.link_enc_cfg_ctx.mode == LINK_ENC_CFG_TRANSIENT) - assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.transient_assignments[i]; - else /* LINK_ENC_CFG_STEADY */ - assignment = dc->current_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - return assignment; -} - -/* Return stream using DIG link encoder resource. NULL if unused. */ -static struct dc_stream_state *get_stream_using_link_enc( - struct dc_state *state, - enum engine_id eng_id) -{ - struct dc_stream_state *stream = NULL; - int i; - - for (i = 0; i < state->stream_count; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if ((assignment.valid == true) && (assignment.eng_id == eng_id)) { - stream = state->streams[i]; - break; - } - } - - return stream; -} - -static void remove_link_enc_assignment( - struct dc_state *state, - struct dc_stream_state *stream, - enum engine_id eng_id) -{ - int eng_idx; - int i; - - if (eng_id != ENGINE_ID_UNKNOWN) { - eng_idx = eng_id - ENGINE_ID_DIGA; - - /* stream ptr of stream in dc_state used to update correct entry in - * link_enc_assignments table. - */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment.valid && assignment.stream == stream) { - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false; - /* Only add link encoder back to availability pool if not being - * used by any other stream (i.e. removing SST stream or last MST stream). - */ - if (get_stream_using_link_enc(state, eng_id) == NULL) - state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = eng_id; - - stream->link_enc = NULL; - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN; - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL; + } else { + is_dig_stream = true; break; } } } + + return is_dig_stream; } -static void add_link_enc_assignment( +/* Update DIG link encoder resource tracking variables in dc_state. */ +static void update_link_enc_assignment( struct dc_state *state, struct dc_stream_state *stream, - enum engine_id eng_id) + enum engine_id eng_id, + bool add_enc) { int eng_idx; + int stream_idx; int i; if (eng_id != ENGINE_ID_UNKNOWN) { eng_idx = eng_id - ENGINE_ID_DIGA; + stream_idx = -1; - /* stream ptr of stream in dc_state used to update correct entry in + /* Index of stream in dc_state used to update correct entry in * link_enc_assignments table. */ for (i = 0; i < state->stream_count; i++) { if (stream == state->streams[i]) { - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i] = (struct link_enc_assignment){ - .valid = true, - .ep_id = (struct display_endpoint_id) { - .link_id = stream->link->link_id, - .ep_type = stream->link->ep_type}, - .eng_id = eng_id, - .stream = stream}; - dc_stream_retain(stream); - state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN; - stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx]; + stream_idx = i; break; } } - /* Attempted to add an encoder assignment for a stream not in dc_state. */ - ASSERT(i != state->stream_count); + /* Update link encoder assignments table, link encoder availability + * pool and link encoder assigned to stream in state. + * Add/remove encoder resource to/from stream. + */ + if (stream_idx != -1) { + if (add_enc) { + state->res_ctx.link_enc_assignments[stream_idx] = (struct link_enc_assignment){ + .valid = true, + .ep_id = (struct display_endpoint_id) { + .link_id = stream->link->link_id, + .ep_type = stream->link->ep_type}, + .eng_id = eng_id}; + state->res_ctx.link_enc_avail[eng_idx] = ENGINE_ID_UNKNOWN; + stream->link_enc = stream->ctx->dc->res_pool->link_encoders[eng_idx]; + } else { + state->res_ctx.link_enc_assignments[stream_idx].valid = false; + state->res_ctx.link_enc_avail[eng_idx] = eng_id; + stream->link_enc = NULL; + } + } else { + dm_output_to_console("%s: Stream not found in dc_state.\n", __func__); + } } } @@ -172,7 +119,7 @@ static enum engine_id find_first_avail_link_enc( int i; for (i = 0; i < ctx->dc->res_pool->res_cap->num_dig_link_enc; i++) { - eng_id = state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i]; + eng_id = state->res_ctx.link_enc_avail[i]; if (eng_id != ENGINE_ID_UNKNOWN) break; } @@ -180,95 +127,44 @@ static enum engine_id find_first_avail_link_enc( return eng_id; } -/* Check for availability of link encoder eng_id. */ -static bool is_avail_link_enc(struct dc_state *state, enum engine_id eng_id, struct dc_stream_state *stream) -{ - bool is_avail = false; - int eng_idx = eng_id - ENGINE_ID_DIGA; - - /* An encoder is available if it is still in the availability pool. */ - if (eng_id != ENGINE_ID_UNKNOWN && state->res_ctx.link_enc_cfg_ctx.link_enc_avail[eng_idx] != ENGINE_ID_UNKNOWN) { - is_avail = true; - } else { - struct dc_stream_state *stream_assigned = NULL; - - /* MST streams share the same link and should share the same encoder. - * If a stream that has already been assigned a link encoder uses as the - * same link as the stream checking for availability, it is an MST stream - * and should use the same link encoder. - */ - stream_assigned = get_stream_using_link_enc(state, eng_id); - if (stream_assigned && stream != stream_assigned && stream->link == stream_assigned->link) - is_avail = true; - } - - return is_avail; -} - -/* Test for display_endpoint_id equality. */ -static bool are_ep_ids_equal(struct display_endpoint_id *lhs, struct display_endpoint_id *rhs) -{ - bool are_equal = false; - - if (lhs->link_id.id == rhs->link_id.id && - lhs->link_id.enum_id == rhs->link_id.enum_id && - lhs->link_id.type == rhs->link_id.type && - lhs->ep_type == rhs->ep_type) - are_equal = true; - - return are_equal; -} - -static struct link_encoder *get_link_enc_used_by_link( +/* Return stream using DIG link encoder resource. NULL if unused. */ +static struct dc_stream_state *get_stream_using_link_enc( struct dc_state *state, - const struct dc_link *link) + enum engine_id eng_id) { - struct link_encoder *link_enc = NULL; - struct display_endpoint_id ep_id; + struct dc_stream_state *stream = NULL; + int stream_idx = -1; int i; - ep_id = (struct display_endpoint_id) { - .link_id = link->link_id, - .ep_type = link->ep_type}; + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id)) - link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA]; - } - - return link_enc; -} -/* Clear all link encoder assignments. */ -static void clear_enc_assignments(const struct dc *dc, struct dc_state *state) -{ - int i; - - for (i = 0; i < MAX_PIPES; i++) { - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid = false; - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].eng_id = ENGINE_ID_UNKNOWN; - if (state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream != NULL) { - dc_stream_release(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream); - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].stream = NULL; + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; + break; } } - for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) { - if (dc->res_pool->link_encoders[i]) - state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = (enum engine_id) i; - else - state->res_ctx.link_enc_cfg_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN; - } + if (stream_idx != -1) + stream = state->streams[stream_idx]; + else + dm_output_to_console("%s: No stream using DIG(%d).\n", __func__, eng_id); + + return stream; } void link_enc_cfg_init( - const struct dc *dc, + struct dc *dc, struct dc_state *state) { - clear_enc_assignments(dc, state); + int i; - state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY; + for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) { + if (dc->res_pool->link_encoders[i]) + state->res_ctx.link_enc_avail[i] = (enum engine_id) i; + else + state->res_ctx.link_enc_avail[i] = ENGINE_ID_UNKNOWN; + } } void link_enc_cfg_link_encs_assign( @@ -279,16 +175,10 @@ void link_enc_cfg_link_encs_assign( { enum engine_id eng_id = ENGINE_ID_UNKNOWN; int i; - int j; - - ASSERT(state->stream_count == stream_count); /* Release DIG link encoder resources before running assignment algorithm. */ - for (i = 0; i < dc->current_state->stream_count; i++) - dc->res_pool->funcs->link_enc_unassign(state, dc->current_state->streams[i]); - - for (i = 0; i < MAX_PIPES; i++) - ASSERT(state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i].valid == false); + for (i = 0; i < stream_count; i++) + dc->res_pool->funcs->link_enc_unassign(state, streams[i]); /* (a) Assign DIG link encoders to physical (unmappable) endpoints first. */ for (i = 0; i < stream_count; i++) { @@ -301,82 +191,26 @@ void link_enc_cfg_link_encs_assign( /* Physical endpoints have a fixed mapping to DIG link encoders. */ if (!stream->link->is_dig_mapping_flexible) { eng_id = stream->link->eng_id; - add_link_enc_assignment(state, stream, eng_id); + update_link_enc_assignment(state, stream, eng_id, true); } } - /* (b) Retain previous assignments for mappable endpoints if encoders still available. */ - eng_id = ENGINE_ID_UNKNOWN; - - if (state != dc->current_state) { - struct dc_state *prev_state = dc->current_state; - - for (i = 0; i < stream_count; i++) { - struct dc_stream_state *stream = state->streams[i]; - - /* Skip stream if not supported by DIG link encoder. */ - if (!is_dig_link_enc_stream(stream)) - continue; - - if (!stream->link->is_dig_mapping_flexible) - continue; - - for (j = 0; j < prev_state->stream_count; j++) { - struct dc_stream_state *prev_stream = prev_state->streams[j]; - - if (stream == prev_stream && stream->link == prev_stream->link && - prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].valid) { - eng_id = prev_state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j].eng_id; - if (is_avail_link_enc(state, eng_id, stream)) - add_link_enc_assignment(state, stream, eng_id); - } - } - } - } - - /* (c) Then assign encoders to remaining mappable endpoints. */ + /* (b) Then assign encoders to mappable endpoints. */ eng_id = ENGINE_ID_UNKNOWN; for (i = 0; i < stream_count; i++) { struct dc_stream_state *stream = streams[i]; /* Skip stream if not supported by DIG link encoder. */ - if (!is_dig_link_enc_stream(stream)) { - ASSERT(stream->link->is_dig_mapping_flexible != true); + if (!is_dig_link_enc_stream(stream)) continue; - } /* Mappable endpoints have a flexible mapping to DIG link encoders. */ if (stream->link->is_dig_mapping_flexible) { - struct link_encoder *link_enc = NULL; - - /* Skip if encoder assignment retained in step (b) above. */ - if (stream->link_enc) - continue; - - /* For MST, multiple streams will share the same link / display - * endpoint. These streams should use the same link encoder - * assigned to that endpoint. - */ - link_enc = get_link_enc_used_by_link(state, stream->link); - if (link_enc == NULL) - eng_id = find_first_avail_link_enc(stream->ctx, state); - else - eng_id = link_enc->preferred_engine; - add_link_enc_assignment(state, stream, eng_id); + eng_id = find_first_avail_link_enc(stream->ctx, state); + update_link_enc_assignment(state, stream, eng_id, true); } } - - link_enc_cfg_validate(dc, state); - - /* Update transient assignments. */ - for (i = 0; i < MAX_PIPES; i++) { - dc->current_state->res_ctx.link_enc_cfg_ctx.transient_assignments[i] = - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - } - - /* Current state mode will be set to steady once this state committed. */ - state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY; } void link_enc_cfg_link_enc_unassign( @@ -392,16 +226,16 @@ void link_enc_cfg_link_enc_unassign( if (stream->link_enc) eng_id = stream->link_enc->preferred_engine; - remove_link_enc_assignment(state, stream, eng_id); + update_link_enc_assignment(state, stream, eng_id, false); } bool link_enc_cfg_is_transmitter_mappable( - struct dc *dc, + struct dc_state *state, struct link_encoder *link_enc) { bool is_mappable = false; enum engine_id eng_id = link_enc->preferred_engine; - struct dc_stream_state *stream = link_enc_cfg_get_stream_using_link_enc(dc, eng_id); + struct dc_stream_state *stream = get_stream_using_link_enc(state, eng_id); if (stream) is_mappable = stream->link->is_dig_mapping_flexible; @@ -409,228 +243,73 @@ bool link_enc_cfg_is_transmitter_mappable( return is_mappable; } -struct dc_stream_state *link_enc_cfg_get_stream_using_link_enc( - struct dc *dc, +struct dc_link *link_enc_cfg_get_link_using_link_enc( + struct dc_state *state, enum engine_id eng_id) { - struct dc_stream_state *stream = NULL; + struct dc_link *link = NULL; + int stream_idx = -1; int i; - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = get_assignment(dc, i); + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; - if ((assignment.valid == true) && (assignment.eng_id == eng_id)) { - stream = assignment.stream; + if (assignment.valid && (assignment.eng_id == eng_id)) { + stream_idx = i; break; } } - return stream; -} + if (stream_idx != -1) + link = state->streams[stream_idx]->link; + else + dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id); -struct dc_link *link_enc_cfg_get_link_using_link_enc( - struct dc *dc, - enum engine_id eng_id) -{ - struct dc_link *link = NULL; - struct dc_stream_state *stream = NULL; - - stream = link_enc_cfg_get_stream_using_link_enc(dc, eng_id); - - if (stream) - link = stream->link; - - // dm_output_to_console("%s: No link using DIG(%d).\n", __func__, eng_id); return link; } struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( - struct dc *dc, + struct dc_state *state, const struct dc_link *link) { struct link_encoder *link_enc = NULL; struct display_endpoint_id ep_id; + int stream_idx = -1; int i; ep_id = (struct display_endpoint_id) { .link_id = link->link_id, .ep_type = link->ep_type}; - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = get_assignment(dc, i); + for (i = 0; i < state->stream_count; i++) { + struct link_enc_assignment assignment = state->res_ctx.link_enc_assignments[i]; - if (assignment.valid == true && are_ep_ids_equal(&assignment.ep_id, &ep_id)) { - link_enc = link->dc->res_pool->link_encoders[assignment.eng_id - ENGINE_ID_DIGA]; + if (assignment.valid && + assignment.ep_id.link_id.id == ep_id.link_id.id && + assignment.ep_id.link_id.enum_id == ep_id.link_id.enum_id && + assignment.ep_id.link_id.type == ep_id.link_id.type && + assignment.ep_id.ep_type == ep_id.ep_type) { + stream_idx = i; break; } } + if (stream_idx != -1) + link_enc = state->streams[stream_idx]->link_enc; + return link_enc; } -struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc) +struct link_encoder *link_enc_cfg_get_next_avail_link_enc( + const struct dc *dc, + const struct dc_state *state) { struct link_encoder *link_enc = NULL; - enum engine_id encs_assigned[MAX_DIG_LINK_ENCODERS]; - int i; + enum engine_id eng_id; - for (i = 0; i < MAX_DIG_LINK_ENCODERS; i++) - encs_assigned[i] = ENGINE_ID_UNKNOWN; - - /* Add assigned encoders to list. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = get_assignment(dc, i); - - if (assignment.valid) - encs_assigned[assignment.eng_id - ENGINE_ID_DIGA] = assignment.eng_id; - } - - for (i = 0; i < dc->res_pool->res_cap->num_dig_link_enc; i++) { - if (encs_assigned[i] == ENGINE_ID_UNKNOWN) { - link_enc = dc->res_pool->link_encoders[i]; - break; - } - } + eng_id = find_first_avail_link_enc(dc->ctx, state); + if (eng_id != ENGINE_ID_UNKNOWN) + link_enc = dc->res_pool->link_encoders[eng_id - ENGINE_ID_DIGA]; return link_enc; } - -struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( - struct dc *dc, - const struct dc_stream_state *stream) -{ - struct link_encoder *link_enc; - - link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, stream->link); - - return link_enc; -} - -bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link) -{ - bool is_avail = true; - int i; - - /* An encoder is not available if it has already been assigned to a different endpoint. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = get_assignment(dc, i); - struct display_endpoint_id ep_id = (struct display_endpoint_id) { - .link_id = link->link_id, - .ep_type = link->ep_type}; - - if (assignment.valid && assignment.eng_id == eng_id && !are_ep_ids_equal(&ep_id, &assignment.ep_id)) { - is_avail = false; - break; - } - } - - return is_avail; -} - -bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state) -{ - bool is_valid = false; - bool valid_entries = true; - bool valid_stream_ptrs = true; - bool valid_uniqueness = true; - bool valid_avail = true; - bool valid_streams = true; - int i, j; - uint8_t valid_count = 0; - uint8_t dig_stream_count = 0; - int matching_stream_ptrs = 0; - int eng_ids_per_ep_id[MAX_PIPES] = {0}; - int valid_bitmap = 0; - - /* (1) No. valid entries same as stream count. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment.valid) - valid_count++; - - if (is_dig_link_enc_stream(state->streams[i])) - dig_stream_count++; - } - if (valid_count != dig_stream_count) - valid_entries = false; - - /* (2) Matching stream ptrs. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment.valid) { - if (assignment.stream == state->streams[i]) - matching_stream_ptrs++; - else - valid_stream_ptrs = false; - } - } - - /* (3) Each endpoint assigned unique encoder. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment_i = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment_i.valid) { - struct display_endpoint_id ep_id_i = assignment_i.ep_id; - - eng_ids_per_ep_id[i]++; - for (j = 0; j < MAX_PIPES; j++) { - struct link_enc_assignment assignment_j = - state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[j]; - - if (j == i) - continue; - - if (assignment_j.valid) { - struct display_endpoint_id ep_id_j = assignment_j.ep_id; - - if (are_ep_ids_equal(&ep_id_i, &ep_id_j) && - assignment_i.eng_id != assignment_j.eng_id) { - valid_uniqueness = false; - eng_ids_per_ep_id[i]++; - } - } - } - } - } - - /* (4) Assigned encoders not in available pool. */ - for (i = 0; i < MAX_PIPES; i++) { - struct link_enc_assignment assignment = state->res_ctx.link_enc_cfg_ctx.link_enc_assignments[i]; - - if (assignment.valid) { - for (j = 0; j < dc->res_pool->res_cap->num_dig_link_enc; j++) { - if (state->res_ctx.link_enc_cfg_ctx.link_enc_avail[j] == assignment.eng_id) { - valid_avail = false; - break; - } - } - } - } - - /* (5) All streams have valid link encoders. */ - for (i = 0; i < state->stream_count; i++) { - struct dc_stream_state *stream = state->streams[i]; - - if (is_dig_link_enc_stream(stream) && stream->link_enc == NULL) { - valid_streams = false; - break; - } - } - - is_valid = valid_entries && valid_stream_ptrs && valid_uniqueness && valid_avail && valid_streams; - ASSERT(is_valid); - - if (is_valid == false) { - valid_bitmap = - (valid_entries & 0x1) | - ((valid_stream_ptrs & 0x1) << 1) | - ((valid_uniqueness & 0x1) << 2) | - ((valid_avail & 0x1) << 3) | - ((valid_streams & 0x1) << 4); - dm_error("Invalid link encoder assignments: 0x%x\n", valid_bitmap); - } - - return is_valid; -} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 45d03d3a95..9c51cd09dc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -17,7 +17,6 @@ #include "link_enc_cfg.h" #include "clk_mgr.h" #include "inc/link_dpcd.h" -#include "dccg.h" static uint8_t convert_to_count(uint8_t lttpr_repeater_count) { @@ -62,16 +61,8 @@ void dp_receiver_power_ctrl(struct dc_link *link, bool on) sizeof(state)); } -void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode) -{ - if (link != NULL && link->dc->debug.enable_driver_sequence_debug) - core_link_write_dpcd(link, DP_SOURCE_SEQUENCE, - &dp_test_mode, sizeof(dp_test_mode)); -} - void dp_enable_link_phy( struct dc_link *link, - const struct link_resource *link_res, enum signal_type signal, enum clock_source_id clock_source, const struct dc_link_settings *link_settings) @@ -88,7 +79,7 @@ void dp_enable_link_phy( /* Link should always be assigned encoder when en-/disabling. */ if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); else link_enc = link->link_enc; ASSERT(link_enc); @@ -120,37 +111,12 @@ void dp_enable_link_phy( link->cur_link_settings = *link_settings; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { - /* TODO - DP2.0 HW: notify link rate change here */ - } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { - if (dc->clk_mgr->funcs->notify_link_rate_change) - dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); - } -#else if (dc->clk_mgr->funcs->notify_link_rate_change) dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); -#endif + if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) { - enable_dp_hpo_output(link, link_res, link_settings); - } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) { - if (dc_is_dp_sst_signal(signal)) { - link_enc->funcs->enable_dp_output( - link_enc, - link_settings, - clock_source); - } else { - link_enc->funcs->enable_dp_mst_output( - link_enc, - link_settings, - clock_source); - } - } -#else if (dc_is_dp_sst_signal(signal)) { link_enc->funcs->enable_dp_output( link_enc, @@ -162,11 +128,10 @@ void dp_enable_link_phy( link_settings, clock_source); } -#endif + if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); dp_receiver_power_ctrl(link, true); } @@ -237,19 +202,15 @@ bool edp_receiver_ready_T7(struct dc_link *link) return result; } -void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res, - enum signal_type signal) +void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { struct dc *dc = link->ctx->dc; struct dmcu *dmcu = dc->res_pool->dmcu; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_link_encoder *hpo_link_enc = link_res->hpo_dp_link_enc; -#endif struct link_encoder *link_enc; /* Link should always be assigned encoder when en-/disabling. */ if (link->is_dig_mapping_flexible && dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(dc, link); + link_enc = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); else link_enc = link->link_enc; ASSERT(link_enc); @@ -260,34 +221,18 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_ if (signal == SIGNAL_TYPE_EDP) { if (link->dc->hwss.edp_backlight_control) link->dc->hwss.edp_backlight_control(link, false); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING) - disable_dp_hpo_output(link, link_res, signal); - else - link_enc->funcs->disable_output(link_enc, signal); -#else link_enc->funcs->disable_output(link_enc, signal); -#endif link->dc->hwss.edp_power_control(link, false); } else { if (dmcu != NULL && dmcu->funcs->lock_phy) dmcu->funcs->lock_phy(dmcu); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link->cur_link_settings) == DP_128b_132b_ENCODING && - hpo_link_enc) - disable_dp_hpo_output(link, link_res, signal); - else - link_enc->funcs->disable_output(link_enc, signal); -#else link_enc->funcs->disable_output(link_enc, signal); -#endif + if (dmcu != NULL && dmcu->funcs->unlock_phy) dmcu->funcs->unlock_phy(dmcu); } - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); - /* Clear current link setting.*/ memset(&link->cur_link_settings, 0, sizeof(link->cur_link_settings)); @@ -296,14 +241,13 @@ void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_ dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); } -void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res, - enum signal_type signal) +void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal) { /* MST disable link only when no stream use the link */ if (link->mst_stream_alloc_table.stream_count > 0) return; - dp_disable_link_phy(link, link_res, signal); + dp_disable_link_phy(link, signal); /* set the sink to SST mode after disabling the link */ dp_enable_mst_on_sink(link, false); @@ -311,7 +255,6 @@ void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *l bool dp_set_hw_training_pattern( struct dc_link *link, - const struct link_resource *link_res, enum dc_dp_training_pattern pattern, uint32_t offset) { @@ -330,30 +273,17 @@ bool dp_set_hw_training_pattern( case DP_TRAINING_PATTERN_SEQUENCE_4: test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4; break; -#if defined(CONFIG_DRM_AMD_DC_DCN) - case DP_128b_132b_TPS1: - test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE; - break; - case DP_128b_132b_TPS2: - test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE; - break; -#endif default: break; } - dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0); + dp_set_hw_test_pattern(link, test_pattern, NULL, 0); return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -#define DC_LOGGER \ - link->ctx->logger -#endif void dp_set_hw_lane_settings( struct dc_link *link, - const struct link_resource *link_res, const struct link_training_settings *link_settings, uint32_t offset) { @@ -363,44 +293,24 @@ void dp_set_hw_lane_settings( return; /* call Encoder to set lane settings */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dp_get_link_encoding_format(&link_settings->link_settings) == - DP_128b_132b_ENCODING) { - link_res->hpo_dp_link_enc->funcs->set_ffe( - link_res->hpo_dp_link_enc, - &link_settings->link_settings, - link_settings->lane_settings[0].FFE_PRESET.raw); - } else if (dp_get_link_encoding_format(&link_settings->link_settings) - == DP_8b_10b_ENCODING) { - encoder->funcs->dp_set_lane_settings(encoder, link_settings); - } -#else encoder->funcs->dp_set_lane_settings(encoder, link_settings); -#endif - memmove(link->cur_lane_setting, - link_settings->lane_settings, - sizeof(link->cur_lane_setting)); } void dp_set_hw_test_pattern( struct dc_link *link, - const struct link_resource *link_res, enum dp_test_pattern test_pattern, uint8_t *custom_pattern, uint32_t custom_pattern_size) { struct encoder_set_dp_phy_pattern_param pattern_param = {0}; struct link_encoder *encoder; -#if defined(CONFIG_DRM_AMD_DC_DCN) - enum dp_link_encoding link_encoding_format = dp_get_link_encoding_format(&link->cur_link_settings); -#endif /* Access link encoder based on whether it is statically * or dynamically assigned to a link. */ if (link->is_dig_mapping_flexible && link->dc->res_pool->funcs->link_encs_assign) - encoder = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); + encoder = link_enc_cfg_get_link_enc_used_by_link(link->dc->current_state, link); else encoder = link->link_enc; @@ -409,28 +319,8 @@ void dp_set_hw_test_pattern( pattern_param.custom_pattern_size = custom_pattern_size; pattern_param.dp_panel_mode = dp_get_panel_mode(link); -#if defined(CONFIG_DRM_AMD_DC_DCN) - switch (link_encoding_format) { - case DP_128b_132b_ENCODING: - link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( - link_res->hpo_dp_link_enc, &pattern_param); - break; - case DP_8b_10b_ENCODING: - ASSERT(encoder); - encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param); - break; - default: - DC_LOG_ERROR("%s: Unknown link encoding format.", __func__); - break; - } -#else encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param); -#endif - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); } -#if defined(CONFIG_DRM_AMD_DC_DCN) -#undef DC_LOGGER -#endif void dp_retrain_link_dp_test(struct dc_link *link, struct dc_link_settings *link_setting, @@ -448,11 +338,11 @@ void dp_retrain_link_dp_test(struct dc_link *link, pipes[i].stream->link == link) { udelay(100); - pipes[i].stream_res.stream_enc->funcs->dp_blank(link, + pipes[i].stream_res.stream_enc->funcs->dp_blank( pipes[i].stream_res.stream_enc); /* disable any test pattern that might be active */ - dp_set_hw_test_pattern(link, &pipes[i].link_res, + dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0); dp_receiver_power_ctrl(link, false); @@ -461,10 +351,9 @@ void dp_retrain_link_dp_test(struct dc_link *link, if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only) (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio); - if (link->link_enc) - link->link_enc->funcs->disable_output( - link->link_enc, - SIGNAL_TYPE_DISPLAY_PORT); + link->link_enc->funcs->disable_output( + link->link_enc, + SIGNAL_TYPE_DISPLAY_PORT); /* Clear current link setting. */ memset(&link->cur_link_settings, 0, @@ -579,12 +468,7 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED; /* Enable DSC in encoder */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) - && !is_dp_128b_132b_signal(pipe_ctx)) { -#else if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { -#endif DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id); dsc_optc_config_log(dsc, &dsc_optc_cfg); pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc, @@ -611,22 +495,13 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) /* disable DSC in stream encoder */ if (dc_is_dp_signal(stream->signal)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.hpo_dp_stream_enc, - false, - NULL, - true); - else -#endif - if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config( - pipe_ctx->stream_res.stream_enc, - OPTC_DSC_DISABLED, 0, 0); - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, false, NULL, true); - } + if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config( + pipe_ctx->stream_res.stream_enc, + OPTC_DSC_DISABLED, 0, 0); + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, false, NULL); + } } /* disable DSC block */ @@ -660,16 +535,7 @@ bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable) return result; } -/* - * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled; - * hence PPS info packet update need to use frame update instead of immediate update. - * Added parameter immediate_update for this purpose. - * The decision to use frame update is hard-coded in function dp_update_dsc_config(), - * which is the only place where a "false" would be passed in for param immediate_update. - * - * immediate_update is only applicable when DSC is enabled. - */ -bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update) +bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable) { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; struct dc_stream_state *stream = pipe_ctx->stream; @@ -696,35 +562,16 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_u dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]); if (dc_is_dp_signal(stream->signal)) { DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.hpo_dp_stream_enc, - true, - &dsc_packed_pps[0], - immediate_update); - else -#endif - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, - true, - &dsc_packed_pps[0], - immediate_update); + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, + true, + &dsc_packed_pps[0]); } } else { /* disable DSC PPS in stream encoder */ if (dc_is_dp_signal(stream->signal)) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.hpo_dp_stream_enc, - false, - NULL, - true); - else -#endif - pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( - pipe_ctx->stream_res.stream_enc, false, NULL, true); + pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet( + pipe_ctx->stream_res.stream_enc, false, NULL); } } @@ -742,176 +589,7 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx) return false; dp_set_dsc_on_stream(pipe_ctx, true); - dp_set_dsc_pps_sdp(pipe_ctx, true, false); + dp_set_dsc_pps_sdp(pipe_ctx, true); return true; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -#undef DC_LOGGER -#define DC_LOGGER \ - link->ctx->logger - -static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) -{ - switch (link->link_enc->transmitter) { - case TRANSMITTER_UNIPHY_A: - return PHYD32CLKA; - case TRANSMITTER_UNIPHY_B: - return PHYD32CLKB; - case TRANSMITTER_UNIPHY_C: - return PHYD32CLKC; - case TRANSMITTER_UNIPHY_D: - return PHYD32CLKD; - case TRANSMITTER_UNIPHY_E: - return PHYD32CLKE; - default: - return PHYD32CLKA; - } -} - -void enable_dp_hpo_output(struct dc_link *link, - const struct link_resource *link_res, - const struct dc_link_settings *link_settings) -{ - const struct dc *dc = link->dc; - enum phyd32clk_clock_source phyd32clk; - - /* Enable PHY PLL at target bit rate - * UHBR10 = 10Gbps (SYMCLK32 = 312.5MHz) - * UBR13.5 = 13.5Gbps (SYMCLK32 = 421.875MHz) - * UHBR20 = 20Gbps (SYMCLK32 = 625MHz) - */ - if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { - switch (link_settings->link_rate) { - case LINK_RATE_UHBR10: - dm_set_phyd32clk(dc->ctx, 312500); - break; - case LINK_RATE_UHBR13_5: - dm_set_phyd32clk(dc->ctx, 412875); - break; - case LINK_RATE_UHBR20: - dm_set_phyd32clk(dc->ctx, 625000); - break; - default: - return; - } - } else { - /* DP2.0 HW: call transmitter control to enable PHY */ - link_res->hpo_dp_link_enc->funcs->enable_link_phy( - link_res->hpo_dp_link_enc, - link_settings, - link->link_enc->transmitter, - link->link_enc->hpd_source); - } - - /* DCCG muxing and DTBCLK DTO */ - if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { - dc->res_pool->dccg->funcs->set_physymclk( - dc->res_pool->dccg, - link->link_enc_hw_inst, - PHYSYMCLK_FORCE_SRC_PHYD32CLK, - true); - - phyd32clk = get_phyd32clk_src(link); - dc->res_pool->dccg->funcs->enable_symclk32_le( - dc->res_pool->dccg, - link_res->hpo_dp_link_enc->inst, - phyd32clk); - link_res->hpo_dp_link_enc->funcs->link_enable( - link_res->hpo_dp_link_enc, - link_settings->lane_count); - } -} - -void disable_dp_hpo_output(struct dc_link *link, - const struct link_resource *link_res, - enum signal_type signal) -{ - const struct dc *dc = link->dc; - - link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc); - - if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { - dc->res_pool->dccg->funcs->disable_symclk32_le( - dc->res_pool->dccg, - link_res->hpo_dp_link_enc->inst); - - dc->res_pool->dccg->funcs->set_physymclk( - dc->res_pool->dccg, - link->link_enc_hw_inst, - PHYSYMCLK_FORCE_SRC_SYMCLK, - false); - - dm_set_phyd32clk(dc->ctx, 0); - } else { - /* DP2.0 HW: call transmitter control to disable PHY */ - link_res->hpo_dp_link_enc->funcs->disable_link_phy( - link_res->hpo_dp_link_enc, - signal); - } -} - -void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable) -{ - struct dc_stream_state *stream = pipe_ctx->stream; - struct dc *dc = pipe_ctx->stream->ctx->dc; - struct pipe_ctx *odm_pipe; - int odm_combine_num_segments = 1; - enum phyd32clk_clock_source phyd32clk; - - if (enable) { - for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) - odm_combine_num_segments++; - - dc->res_pool->dccg->funcs->set_dpstreamclk( - dc->res_pool->dccg, - DTBCLK0, - pipe_ctx->stream_res.tg->inst); - - phyd32clk = get_phyd32clk_src(stream->link); - dc->res_pool->dccg->funcs->enable_symclk32_se( - dc->res_pool->dccg, - pipe_ctx->stream_res.hpo_dp_stream_enc->inst, - phyd32clk); - - dc->res_pool->dccg->funcs->set_dtbclk_dto( - dc->res_pool->dccg, - pipe_ctx->stream_res.tg->inst, - stream->phy_pix_clk, - odm_combine_num_segments, - &stream->timing); - } else { - dc->res_pool->dccg->funcs->set_dtbclk_dto( - dc->res_pool->dccg, - pipe_ctx->stream_res.tg->inst, - 0, - 0, - &stream->timing); - dc->res_pool->dccg->funcs->disable_symclk32_se( - dc->res_pool->dccg, - pipe_ctx->stream_res.hpo_dp_stream_enc->inst); - dc->res_pool->dccg->funcs->set_dpstreamclk( - dc->res_pool->dccg, - REFCLK, - pipe_ctx->stream_res.tg->inst); - } -} - -void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link) -{ - const struct dc *dc = link->dc; - struct dc_state *state = dc->current_state; - uint8_t i; - - for (i = 0; i < MAX_PIPES; i++) { - if (state->res_ctx.pipe_ctx[i].stream_res.hpo_dp_stream_enc && - state->res_ctx.pipe_ctx[i].stream && - state->res_ctx.pipe_ctx[i].stream->link == link && - !state->res_ctx.pipe_ctx[i].stream->dpms_off) { - setup_dp_hpo_stream(&state->res_ctx.pipe_ctx[i], false); - } - } -} - -#undef DC_LOGGER -#endif diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 18757c1585..7ae409f7dc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -41,8 +41,6 @@ #include "set_mode_types.h" #include "virtual/virtual_stream_encoder.h" #include "dpcd_defs.h" -#include "link_enc_cfg.h" -#include "dc_link_dp.h" #if defined(CONFIG_DRM_AMD_DC_SI) #include "dce60/dce60_resource.h" @@ -56,7 +54,6 @@ #include "dcn10/dcn10_resource.h" #include "dcn20/dcn20_resource.h" #include "dcn21/dcn21_resource.h" -#include "dcn201/dcn201_resource.h" #include "dcn30/dcn30_resource.h" #include "dcn301/dcn301_resource.h" #include "dcn302/dcn302_resource.h" @@ -131,10 +128,6 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id) case FAMILY_NV: dc_version = DCN_VERSION_2_0; - if (asic_id.chip_id == DEVICE_ID_NV_13FE) { - dc_version = DCN_VERSION_2_01; - break; - } if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) dc_version = DCN_VERSION_3_0; if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id.hw_internal_rev)) @@ -224,9 +217,6 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, case DCN_VERSION_2_1: res_pool = dcn21_create_resource_pool(init_data, dc); break; - case DCN_VERSION_2_01: - res_pool = dcn201_create_resource_pool(init_data, dc); - break; case DCN_VERSION_3_0: res_pool = dcn30_create_resource_pool(init_data, dc); break; @@ -356,29 +346,6 @@ bool resource_construct( } } -#if defined(CONFIG_DRM_AMD_DC_DCN) - pool->hpo_dp_stream_enc_count = 0; - if (create_funcs->create_hpo_dp_stream_encoder) { - for (i = 0; i < caps->num_hpo_dp_stream_encoder; i++) { - pool->hpo_dp_stream_enc[i] = create_funcs->create_hpo_dp_stream_encoder(i+ENGINE_ID_HPO_DP_0, ctx); - if (pool->hpo_dp_stream_enc[i] == NULL) - DC_ERR("DC: failed to create HPO DP stream encoder!\n"); - pool->hpo_dp_stream_enc_count++; - - } - } - - pool->hpo_dp_link_enc_count = 0; - if (create_funcs->create_hpo_dp_link_encoder) { - for (i = 0; i < caps->num_hpo_dp_link_encoder; i++) { - pool->hpo_dp_link_enc[i] = create_funcs->create_hpo_dp_link_encoder(i, ctx); - if (pool->hpo_dp_link_enc[i] == NULL) - DC_ERR("DC: failed to create HPO DP link encoder!\n"); - pool->hpo_dp_link_enc_count++; - } - } -#endif - #if defined(CONFIG_DRM_AMD_DC_DCN) for (i = 0; i < caps->num_mpc_3dlut; i++) { pool->mpc_lut[i] = dc_create_3dlut_func(); @@ -1155,17 +1122,9 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) pipe_ctx->plane_res.scl_data.recout.x += pipe_ctx->plane_res.scl_data.recout.width; } - if (!pipe_ctx->stream->ctx->dc->config.enable_windowed_mpo_odm) { - if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE || - pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) - res = false; - } else { - /* Clamp minimum viewport size */ - if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE) - pipe_ctx->plane_res.scl_data.viewport.height = MIN_VIEWPORT_SIZE; - if (pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) - pipe_ctx->plane_res.scl_data.viewport.width = MIN_VIEWPORT_SIZE; - } + if (pipe_ctx->plane_res.scl_data.viewport.height < MIN_VIEWPORT_SIZE || + pipe_ctx->plane_res.scl_data.viewport.width < MIN_VIEWPORT_SIZE) + res = false; DC_LOG_SCALER("%s pipe %d:\nViewport: height:%d width:%d x:%d y:%d Recout: height:%d width:%d x:%d y:%d HACTIVE:%d VACTIVE:%d\n" "src_rect: height:%d width:%d x:%d y:%d dst_rect: height:%d width:%d x:%d y:%d clip_rect: height:%d width:%d x:%d y:%d\n", @@ -1710,110 +1669,6 @@ static void update_stream_engine_usage( } } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static void update_hpo_dp_stream_engine_usage( - struct resource_context *res_ctx, - const struct resource_pool *pool, - struct hpo_dp_stream_encoder *hpo_dp_stream_enc, - bool acquired) -{ - int i; - - for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) { - if (pool->hpo_dp_stream_enc[i] == hpo_dp_stream_enc) - res_ctx->is_hpo_dp_stream_enc_acquired[i] = acquired; - } -} - -static inline int find_acquired_hpo_dp_link_enc_for_link( - const struct resource_context *res_ctx, - const struct dc_link *link) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(res_ctx->hpo_dp_link_enc_to_link_idx); i++) - if (res_ctx->hpo_dp_link_enc_ref_cnts[i] > 0 && - res_ctx->hpo_dp_link_enc_to_link_idx[i] == link->link_index) - return i; - - return -1; -} - -static inline int find_free_hpo_dp_link_enc(const struct resource_context *res_ctx, - const struct resource_pool *pool) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(res_ctx->hpo_dp_link_enc_ref_cnts); i++) - if (res_ctx->hpo_dp_link_enc_ref_cnts[i] == 0) - break; - - return (i < ARRAY_SIZE(res_ctx->hpo_dp_link_enc_ref_cnts) && - i < pool->hpo_dp_link_enc_count) ? i : -1; -} - -static inline void acquire_hpo_dp_link_enc( - struct resource_context *res_ctx, - unsigned int link_index, - int enc_index) -{ - res_ctx->hpo_dp_link_enc_to_link_idx[enc_index] = link_index; - res_ctx->hpo_dp_link_enc_ref_cnts[enc_index] = 1; -} - -static inline void retain_hpo_dp_link_enc( - struct resource_context *res_ctx, - int enc_index) -{ - res_ctx->hpo_dp_link_enc_ref_cnts[enc_index]++; -} - -static inline void release_hpo_dp_link_enc( - struct resource_context *res_ctx, - int enc_index) -{ - ASSERT(res_ctx->hpo_dp_link_enc_ref_cnts[enc_index] > 0); - res_ctx->hpo_dp_link_enc_ref_cnts[enc_index]--; -} - -static bool add_hpo_dp_link_enc_to_ctx(struct resource_context *res_ctx, - const struct resource_pool *pool, - struct pipe_ctx *pipe_ctx, - struct dc_stream_state *stream) -{ - int enc_index; - - enc_index = find_acquired_hpo_dp_link_enc_for_link(res_ctx, stream->link); - - if (enc_index >= 0) { - retain_hpo_dp_link_enc(res_ctx, enc_index); - } else { - enc_index = find_free_hpo_dp_link_enc(res_ctx, pool); - if (enc_index >= 0) - acquire_hpo_dp_link_enc(res_ctx, stream->link->link_index, enc_index); - } - - if (enc_index >= 0) - pipe_ctx->link_res.hpo_dp_link_enc = pool->hpo_dp_link_enc[enc_index]; - - return pipe_ctx->link_res.hpo_dp_link_enc != NULL; -} - -static void remove_hpo_dp_link_enc_from_ctx(struct resource_context *res_ctx, - struct pipe_ctx *pipe_ctx, - struct dc_stream_state *stream) -{ - int enc_index; - - enc_index = find_acquired_hpo_dp_link_enc_for_link(res_ctx, stream->link); - - if (enc_index >= 0) { - release_hpo_dp_link_enc(res_ctx, enc_index); - pipe_ctx->link_res.hpo_dp_link_enc = NULL; - } -} -#endif - /* TODO: release audio object */ void update_audio_usage( struct resource_context *res_ctx, @@ -1858,26 +1713,6 @@ static int acquire_first_free_pipe( return -1; } -#if defined(CONFIG_DRM_AMD_DC_DCN) -static struct hpo_dp_stream_encoder *find_first_free_match_hpo_dp_stream_enc_for_link( - struct resource_context *res_ctx, - const struct resource_pool *pool, - struct dc_stream_state *stream) -{ - int i; - - for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) { - if (!res_ctx->is_hpo_dp_stream_enc_acquired[i] && - pool->hpo_dp_stream_enc[i]) { - - return pool->hpo_dp_stream_enc[i]; - } - } - - return NULL; -} -#endif - static struct audio *find_first_free_audio( struct resource_context *res_ctx, const struct resource_pool *pool, @@ -1964,15 +1799,6 @@ enum dc_status dc_remove_stream_from_ctx( dc->res_pool, del_pipe->stream_res.stream_enc, false); -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(del_pipe)) { - update_hpo_dp_stream_engine_usage( - &new_ctx->res_ctx, dc->res_pool, - del_pipe->stream_res.hpo_dp_stream_enc, - false); - remove_hpo_dp_link_enc_from_ctx(&new_ctx->res_ctx, del_pipe, del_pipe->stream); - } -#endif if (del_pipe->stream_res.audio) update_audio_usage( @@ -2167,6 +1993,7 @@ static void mark_seamless_boot_stream( { struct dc_bios *dcb = dc->ctx->dc_bios; + /* TODO: Check Linux */ if (dc->config.allow_seamless_boot_optimization && !dcb->funcs->is_accelerated_mode(dcb)) { if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing)) @@ -2225,33 +2052,6 @@ enum dc_status resource_map_pool_resources( pipe_ctx->stream_res.stream_enc, true); -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* Allocate DP HPO Stream Encoder based on signal, hw capabilities - * and link settings - */ - if (dc_is_dp_signal(stream->signal) && - dc->caps.dp_hpo) { - struct dc_link_settings link_settings = {0}; - - decide_link_settings(stream, &link_settings); - if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) { - pipe_ctx->stream_res.hpo_dp_stream_enc = - find_first_free_match_hpo_dp_stream_enc_for_link( - &context->res_ctx, pool, stream); - - if (!pipe_ctx->stream_res.hpo_dp_stream_enc) - return DC_NO_STREAM_ENC_RESOURCE; - - update_hpo_dp_stream_engine_usage( - &context->res_ctx, pool, - pipe_ctx->stream_res.hpo_dp_stream_enc, - true); - if (!add_hpo_dp_link_enc_to_ctx(&context->res_ctx, pool, pipe_ctx, stream)) - return DC_NO_LINK_ENC_RESOURCE; - } - } -#endif - /* TODO: Add check if ASIC support and EDID audio */ if (!stream->converter_disable_audio && dc_is_audio_capable_signal(pipe_ctx->stream->signal) && @@ -2314,9 +2114,6 @@ void dc_resource_state_construct( struct dc_state *dst_ctx) { dst_ctx->clk_mgr = dc->clk_mgr; - - /* Initialise DIG link encoder resource tracking variables. */ - link_enc_cfg_init(dc, dst_ctx); } @@ -2345,6 +2142,16 @@ enum dc_status dc_validate_global_state( if (!new_ctx) return DC_ERROR_UNEXPECTED; +#if defined(CONFIG_DRM_AMD_DC_DCN) + + /* + * Update link encoder to stream assignment. + * TODO: Split out reason allocation from validation. + */ + if (dc->res_pool->funcs->link_encs_assign) + dc->res_pool->funcs->link_encs_assign( + dc, new_ctx, new_ctx->streams, new_ctx->stream_count); +#endif if (dc->res_pool->funcs->validate_global) { result = dc->res_pool->funcs->validate_global(dc, new_ctx); @@ -2396,16 +2203,6 @@ enum dc_status dc_validate_global_state( if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) result = DC_FAIL_BANDWIDTH_VALIDATE; -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* - * Only update link encoder to stream assignment after bandwidth validation passed. - * TODO: Split out assignment and validation. - */ - if (result == DC_OK && dc->res_pool->funcs->link_encs_assign && fast_validate == false) - dc->res_pool->funcs->link_encs_assign( - dc, new_ctx, new_ctx->streams, new_ctx->stream_count); -#endif - return result; } @@ -2599,7 +2396,17 @@ static void set_avi_info_frame( /* TODO : We should handle YCC quantization */ /* but we do not have matrix calculation */ - hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; + if (stream->qy_bit == 1) { + if (color_space == COLOR_SPACE_SRGB || + color_space == COLOR_SPACE_2020_RGB_FULLRANGE) + hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; + else if (color_space == COLOR_SPACE_SRGB_LIMITED || + color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) + hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; + else + hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; + } else + hdmi_info.bits.YQ0_YQ1 = YYC_QUANTIZATION_LIMITED_RANGE; ///VIC format = stream->timing.timing_3d_format; @@ -2920,26 +2727,9 @@ bool pipe_need_reprogram( if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc) return true; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (pipe_ctx_old->stream_res.hpo_dp_stream_enc != pipe_ctx->stream_res.hpo_dp_stream_enc) - return true; - if (pipe_ctx_old->link_res.hpo_dp_link_enc != pipe_ctx->link_res.hpo_dp_link_enc) - return true; -#endif - /* DIG link encoder resource assignment for stream changed. */ - if (pipe_ctx_old->stream->ctx->dc->res_pool->funcs->link_encs_assign) { - bool need_reprogram = false; - struct dc *dc = pipe_ctx_old->stream->ctx->dc; - enum link_enc_cfg_mode mode = dc->current_state->res_ctx.link_enc_cfg_ctx.mode; - - dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY; - if (link_enc_cfg_get_link_enc_used_by_stream(dc, pipe_ctx_old->stream) != pipe_ctx->stream->link_enc) - need_reprogram = true; - dc->current_state->res_ctx.link_enc_cfg_ctx.mode = mode; - - return need_reprogram; - } + if (pipe_ctx_old->stream->link_enc != pipe_ctx->stream->link_enc) + return true; return false; } @@ -3082,8 +2872,7 @@ enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) res = DC_FAIL_CONTROLLER_VALIDATE; if (res == DC_OK) { - if (link->ep_type == DISPLAY_ENDPOINT_PHY && - !link->link_enc->funcs->validate_output_with_stream( + if (!link->link_enc->funcs->validate_output_with_stream( link->link_enc, stream)) res = DC_FAIL_ENC_VALIDATE; } @@ -3102,11 +2891,6 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla { enum dc_status res = DC_OK; - /* check if surface has invalid dimensions */ - if (plane_state->src_rect.width == 0 || plane_state->src_rect.height == 0 || - plane_state->dst_rect.width == 0 || plane_state->dst_rect.height == 0) - return DC_FAIL_SURFACE_VALIDATE; - /* TODO For now validates pixel format only */ if (dc->res_pool->funcs->validate_plane) return dc->res_pool->funcs->validate_plane(plane_state, &dc->caps); @@ -3192,110 +2976,3 @@ void get_audio_check(struct audio_info *aud_modes, } } -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt( - const struct resource_context *res_ctx, - const struct resource_pool *pool, - const struct dc_link *link) -{ - struct hpo_dp_link_encoder *hpo_dp_link_enc = NULL; - int enc_index; - - enc_index = find_acquired_hpo_dp_link_enc_for_link(res_ctx, link); - - if (enc_index < 0) - enc_index = find_free_hpo_dp_link_enc(res_ctx, pool); - - if (enc_index >= 0) - hpo_dp_link_enc = pool->hpo_dp_link_enc[enc_index]; - - return hpo_dp_link_enc; -} -#endif - -void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, - struct dc_state *context) -{ - int i, j; - struct pipe_ctx *pipe_ctx_old, *pipe_ctx, *pipe_ctx_syncd; - - /* If pipe backend is reset, need to reset pipe syncd status */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe_ctx_old = &dc->current_state->res_ctx.pipe_ctx[i]; - pipe_ctx = &context->res_ctx.pipe_ctx[i]; - - if (!pipe_ctx_old->stream) - continue; - - if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe) - continue; - - if (!pipe_ctx->stream || - pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { - - /* Reset all the syncd pipes from the disabled pipe */ - for (j = 0; j < dc->res_pool->pipe_count; j++) { - pipe_ctx_syncd = &context->res_ctx.pipe_ctx[j]; - if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_syncd) == pipe_ctx_old->pipe_idx) || - !IS_PIPE_SYNCD_VALID(pipe_ctx_syncd)) - SET_PIPE_SYNCD_TO_PIPE(pipe_ctx_syncd, j); - } - } - } -} - -void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, - struct dc_state *context, - uint8_t disabled_master_pipe_idx) -{ - int i; - struct pipe_ctx *pipe_ctx, *pipe_ctx_check; - - pipe_ctx = &context->res_ctx.pipe_ctx[disabled_master_pipe_idx]; - if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx) != disabled_master_pipe_idx) || - !IS_PIPE_SYNCD_VALID(pipe_ctx)) - SET_PIPE_SYNCD_TO_PIPE(pipe_ctx, disabled_master_pipe_idx); - - /* for the pipe disabled, check if any slave pipe exists and assert */ - for (i = 0; i < dc->res_pool->pipe_count; i++) { - pipe_ctx_check = &context->res_ctx.pipe_ctx[i]; - - if ((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_check) == disabled_master_pipe_idx) && - IS_PIPE_SYNCD_VALID(pipe_ctx_check) && (i != disabled_master_pipe_idx)) - DC_ERR("DC: Failure: pipe_idx[%d] syncd with disabled master pipe_idx[%d]\n", - i, disabled_master_pipe_idx); - } -} - -uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter) -{ - /* TODO - get transmitter to phy idx mapping from DMUB */ - uint8_t phy_idx = transmitter - TRANSMITTER_UNIPHY_A; - -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dc->ctx->dce_version == DCN_VERSION_3_1 && - dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { - switch (transmitter) { - case TRANSMITTER_UNIPHY_A: - phy_idx = 0; - break; - case TRANSMITTER_UNIPHY_B: - phy_idx = 1; - break; - case TRANSMITTER_UNIPHY_C: - phy_idx = 5; - break; - case TRANSMITTER_UNIPHY_D: - phy_idx = 6; - break; - case TRANSMITTER_UNIPHY_E: - phy_idx = 4; - break; - default: - phy_idx = 0; - break; - } - } -#endif - return phy_idx; -} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c index 4b5e4d8e77..a249a0e5ed 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c @@ -33,6 +33,14 @@ * Private functions ******************************************************************************/ +static void dc_sink_destruct(struct dc_sink *sink) +{ + if (sink->dc_container_id) { + kfree(sink->dc_container_id); + sink->dc_container_id = NULL; + } +} + static bool dc_sink_construct(struct dc_sink *sink, const struct dc_sink_init_data *init_params) { @@ -67,7 +75,7 @@ void dc_sink_retain(struct dc_sink *sink) static void dc_sink_free(struct kref *kref) { struct dc_sink *sink = container_of(kref, struct dc_sink, refcount); - kfree(sink->dc_container_id); + dc_sink_destruct(sink); kfree(sink); } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c index 4b372aa528..28ef9760fa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stat.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stat.c @@ -61,14 +61,6 @@ void dc_stat_get_dmub_notification(const struct dc *dc, struct dmub_notification status = dmub_srv_stat_get_notification(dmub, notify); ASSERT(status == DMUB_STATUS_OK); - - /* For HPD/HPD RX, convert dpia port index into link index */ - if (notify->type == DMUB_NOTIFICATION_HPD || - notify->type == DMUB_NOTIFICATION_HPD_IRQ || - notify->type == DMUB_NOTIFICATION_SET_CONFIG_REPLY) { - notify->link_index = - get_link_index_from_dpia_port_index(dc, notify->link_index); - } } /** diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 57cf4cb823..f0f54f4d3d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -202,10 +202,6 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream) new_stream->stream_id = new_stream->ctx->dc_stream_id_count; new_stream->ctx->dc_stream_id_count++; - /* If using dynamic encoder assignment, wait till stream committed to assign encoder. */ - if (new_stream->ctx->dc->res_pool->funcs->link_encs_assign) - new_stream->link_enc = NULL; - kref_init(&new_stream->refcount); return new_stream; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index b518648906..e0f58fab5e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -44,10 +44,8 @@ /* forward declaration */ struct aux_payload; -struct set_config_cmd_payload; -struct dmub_notification; -#define DC_VER "3.2.167" +#define DC_VER "3.2.149" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -75,16 +73,6 @@ enum dc_plane_type { DC_PLANE_TYPE_DCN_UNIVERSAL, }; -// Sizes defined as multiples of 64KB -enum det_size { - DET_SIZE_DEFAULT = 0, - DET_SIZE_192KB = 3, - DET_SIZE_256KB = 4, - DET_SIZE_320KB = 5, - DET_SIZE_384KB = 6 -}; - - struct dc_plane_cap { enum dc_plane_type type; uint32_t blends_with_above : 1; @@ -195,11 +183,6 @@ struct dc_caps { unsigned int cursor_cache_size; struct dc_plane_cap planes[MAX_PLANES]; struct dc_color_caps color; -#if defined(CONFIG_DRM_AMD_DC_DCN) - bool dp_hpo; - bool hdmi_frl_pcon_support; -#endif - bool edp_dsc_support; bool vbios_lttpr_aware; bool vbios_lttpr_enable; uint32_t max_otg_num; @@ -224,12 +207,12 @@ struct dc_dcc_setting { unsigned int max_uncompressed_blk_size; bool independent_64b_blks; #if defined(CONFIG_DRM_AMD_DC_DCN) - //These bitfields to be used starting with DCN + //These bitfields to be used starting with DCN 3.0 struct { - uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN (the worst compression case) - uint32_t dcc_128_128_uncontrained : 1; //available in ASICs before DCN - uint32_t dcc_256_128_128 : 1; //available starting with DCN - uint32_t dcc_256_256_unconstrained : 1; //available in ASICs before DCN (the best compression case) + uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN 3.0 (the worst compression case) + uint32_t dcc_128_128_uncontrained : 1; //available in ASICs before DCN 3.0 + uint32_t dcc_256_128_128 : 1; //available starting with DCN 3.0 + uint32_t dcc_256_256_unconstrained : 1; //available in ASICs before DCN 3.0 (the best compression case) } dcc_controls; #endif }; @@ -307,15 +290,7 @@ struct dc_cap_funcs { struct link_training_settings; -#if defined(CONFIG_DRM_AMD_DC_DCN) -union allow_lttpr_non_transparent_mode { - struct { - bool DP1_4A : 1; - bool DP2_0 : 1; - } bits; - unsigned char raw; -}; -#endif + /* Structure to hold configuration flags set by dm at dc creation. */ struct dc_config { bool gpu_vm_support; @@ -328,15 +303,10 @@ struct dc_config { bool edp_no_power_sequencing; bool force_enum_edp; bool forced_clocks; -#if defined(CONFIG_DRM_AMD_DC_DCN) - union allow_lttpr_non_transparent_mode allow_lttpr_non_transparent_mode; -#else bool allow_lttpr_non_transparent_mode; -#endif bool multi_mon_pp_mclk_switch; bool disable_dmcu; bool enable_4to1MPC; - bool enable_windowed_mpo_odm; bool allow_edp_hotplug_detection; #if defined(CONFIG_DRM_AMD_DC_DCN) bool clamp_min_dcfclk; @@ -345,7 +315,6 @@ struct dc_config { uint8_t vblank_alignment_max_frame_time_diff; bool is_asymmetric_memory; bool is_single_rank_dimm; - bool use_pipe_ctx_sync_logic; }; enum visual_confirm { @@ -357,12 +326,6 @@ enum visual_confirm { VISUAL_CONFIRM_SWIZZLE = 9, }; -enum dc_psr_power_opts { - psr_power_opt_invalid = 0x0, - psr_power_opt_smu_opt_static_screen = 0x1, - psr_power_opt_z10_static_screen = 0x10, -}; - enum dcc_option { DCC_ENABLE = 0, DCC_DISABLE = 1, @@ -494,41 +457,10 @@ union mem_low_power_enable_options { bool cm: 1; bool mpc: 1; bool optc: 1; - bool vpg: 1; - bool afmt: 1; } bits; uint32_t u32All; }; -union root_clock_optimization_options { - struct { - bool dpp: 1; - bool dsc: 1; - bool hdmistream: 1; - bool hdmichar: 1; - bool dpstream: 1; - bool symclk32_se: 1; - bool symclk32_le: 1; - bool symclk_fe: 1; - bool physymclk: 1; - bool dpiasymclk: 1; - uint32_t reserved: 22; - } bits; - uint32_t u32All; -}; - -union dpia_debug_options { - struct { - uint32_t disable_dpia:1; - uint32_t force_non_lttpr:1; - uint32_t extend_aux_rd_interval:1; - uint32_t disable_mst_dsc_work_around:1; - uint32_t hpd_delay_in_ms:12; - uint32_t reserved:16; - } bits; - uint32_t raw; -}; - struct dc_debug_data { uint32_t ltFailCount; uint32_t i2cErrorCount; @@ -589,8 +521,6 @@ struct dc_debug_options { bool native422_support; bool disable_dsc; enum visual_confirm visual_confirm; - int visual_confirm_rect_height; - bool sanity_checks; bool max_disp_clk; bool surface_trace; @@ -619,7 +549,6 @@ struct dc_debug_options { enum wm_report_mode pplib_wm_report_mode; unsigned int min_disp_clk_khz; unsigned int min_dpp_clk_khz; - unsigned int min_dram_clk_khz; int sr_exit_time_dpm0_ns; int sr_enter_plus_exit_time_dpm0_ns; int sr_exit_time_ns; @@ -685,35 +614,21 @@ struct dc_debug_options { bool validate_dml_output; bool enable_dmcub_surface_flip; bool usbc_combo_phy_reset_wa; - bool disable_dsc_edp; - unsigned int force_dsc_edp_policy; bool enable_dram_clock_change_one_display_vactive; -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* TODO - remove once tested */ - bool legacy_dp2_lt; - bool set_mst_en_for_sst; - bool disable_uhbr; - bool force_dp2_lt_fallback_method; -#endif union mem_low_power_enable_options enable_mem_low_power; - union root_clock_optimization_options root_clock_optimization; - bool hpo_optimization; bool force_vblank_alignment; /* Enable dmub aux for legacy ddc */ bool enable_dmub_aux_for_legacy_ddc; bool optimize_edp_link_rate; /* eDP ILR */ + /* force enable edp FEC */ + bool force_enable_edp_fec; /* FEC/PSR1 sequence enable delay in 100us */ uint8_t fec_enable_delay_in100us; - bool enable_driver_sequence_debug; - enum det_size crb_alloc_policy; - int crb_alloc_policy_min_disp_count; #if defined(CONFIG_DRM_AMD_DC_DCN) bool disable_z10; bool enable_sw_cntl_psr; - union dpia_debug_options dpia_debug; #endif - bool apply_vendor_specific_lttpr_wa; }; struct gpu_info_soc_bounding_box_v1_0; @@ -758,9 +673,6 @@ struct dc { #if defined(CONFIG_DRM_AMD_DC_DCN) bool idle_optimizations_allowed; #endif -#if defined(CONFIG_DRM_AMD_DC_DCN) - bool enable_c20_dtm_b0; -#endif /* Require to maintain clocks and bandwidth for UEFI enabled HW */ @@ -967,7 +879,6 @@ union surface_update_flags { uint32_t bandwidth_change:1; uint32_t clock_change:1; uint32_t stereo_format_change:1; - uint32_t lut_3d:1; uint32_t full_update:1; } bits; @@ -1235,14 +1146,7 @@ struct dpcd_caps { struct dpcd_dsc_capabilities dsc_caps; struct dc_lttpr_caps lttpr_caps; struct psr_caps psr_caps; - struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info; -#if defined(CONFIG_DRM_AMD_DC_DCN) - union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates; - union dp_main_line_channel_coding_cap channel_coding_cap; - union dp_sink_video_fallback_formats fallback_formats; - union dp_fec_capability1 fec_cap1; -#endif }; union dpcd_sink_ext_caps { @@ -1314,11 +1218,6 @@ struct dc_sink_dsc_caps { // 'true' if these are virtual DPCD's DSC caps (immediately upstream of sink in MST topology), // 'false' if they are sink's DSC caps bool is_virtual_dpcd_dsc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - // 'true' if MST topology supports DSC passthrough for sink - // 'false' if MST topology does not support DSC passthrough - bool is_dsc_passthrough_supported; -#endif struct dsc_dec_dpcd_caps dsc_dec_caps; }; @@ -1389,8 +1288,6 @@ void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); enum dc_irq_source dc_get_hpd_irq_source_at_index( struct dc *dc, uint32_t link_index); -void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable); - /******************************************************************************* * Power Interfaces ******************************************************************************/ @@ -1434,9 +1331,6 @@ void dc_unlock_memory_clock_frequency(struct dc *dc); */ void dc_lock_memory_clock_frequency(struct dc *dc); -/* set soft max for memclk, to be used for AC/DC switching clock limitations */ -void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable); - /* cleanup on driver unload */ void dc_hardware_release(struct dc *dc); @@ -1444,7 +1338,7 @@ void dc_hardware_release(struct dc *dc); bool dc_set_psr_allow_active(struct dc *dc, bool enable); #if defined(CONFIG_DRM_AMD_DC_DCN) -void dc_z10_restore(const struct dc *dc); +void dc_z10_restore(struct dc *dc); void dc_z10_save_init(struct dc *dc); #endif @@ -1454,20 +1348,6 @@ bool dc_process_dmub_aux_transfer_async(struct dc *dc, uint32_t link_index, struct aux_payload *payload); -/* Get dc link index from dpia port index */ -uint8_t get_link_index_from_dpia_port_index(const struct dc *dc, - uint8_t dpia_port_index); - -bool dc_process_dmub_set_config_async(struct dc *dc, - uint32_t link_index, - struct set_config_cmd_payload *payload, - struct dmub_notification *notify); - -enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, - uint32_t link_index, - uint8_t mst_alloc_slots, - uint8_t *mst_slots_in_use); - /******************************************************************************* * DSC Interfaces ******************************************************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 541376fabb..360f3199ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -115,44 +115,13 @@ void dc_dmub_srv_wait_idle(struct dc_dmub_srv *dc_dmub_srv) } } -void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv) -{ - struct dmub_srv *dmub = dmub_srv->dmub; - struct dc_context *dc_ctx = dmub_srv->ctx; - enum dmub_status status = DMUB_STATUS_OK; - - status = dmub_srv_clear_inbox0_ack(dmub); - if (status != DMUB_STATUS_OK) { - DC_ERROR("Error clearing INBOX0 ack: status=%d\n", status); - dc_dmub_srv_log_diagnostic_data(dmub_srv); - } -} - -void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv) -{ - struct dmub_srv *dmub = dmub_srv->dmub; - struct dc_context *dc_ctx = dmub_srv->ctx; - enum dmub_status status = DMUB_STATUS_OK; - - status = dmub_srv_wait_for_inbox0_ack(dmub, 100000); - if (status != DMUB_STATUS_OK) { - DC_ERROR("Error waiting for INBOX0 HW Lock Ack\n"); - dc_dmub_srv_log_diagnostic_data(dmub_srv); - } -} - void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data) { struct dmub_srv *dmub = dmub_srv->dmub; - struct dc_context *dc_ctx = dmub_srv->ctx; - enum dmub_status status = DMUB_STATUS_OK; - - status = dmub_srv_send_inbox0_cmd(dmub, data); - if (status != DMUB_STATUS_OK) { - DC_ERROR("Error sending INBOX0 cmd\n"); - dc_dmub_srv_log_diagnostic_data(dmub_srv); - } + if (dmub->hw_funcs.send_inbox0_cmd) + dmub->hw_funcs.send_inbox0_cmd(dmub, data); + // TODO: Add wait command -- poll register for ACK } bool dc_dmub_srv_cmd_with_reply_data(struct dc_dmub_srv *dc_dmub_srv, union dmub_rb_cmd *cmd) diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h index 7e4e2ec591..3e35eee718 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h @@ -68,8 +68,6 @@ bool dc_dmub_srv_get_dmub_outbox0_msg(const struct dc *dc, struct dmcub_trace_bu void dc_dmub_trace_event_control(struct dc *dc, bool enable); -void dc_dmub_srv_clear_inbox0_ack(struct dc_dmub_srv *dmub_srv); -void dc_dmub_srv_wait_for_inbox0_ack(struct dc_dmub_srv *dmub_srv); void dc_dmub_srv_send_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_data_register data); bool dc_dmub_srv_get_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv, struct dmub_diagnostic_data *dmub_oca); diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 353dac420f..4f54bde1bb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -53,17 +53,7 @@ enum dc_link_rate { LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane -#if defined(CONFIG_DRM_AMD_DC_DCN) - LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane - /* Starting from DP2.0 link rate enum directly represents actual - * link rate value in unit of 10 mbps - */ - LINK_RATE_UHBR10 = 1000, // UHBR10 - 10.0 Gbps/Lane - LINK_RATE_UHBR13_5 = 1350, // UHBR13.5 - 13.5 Gbps/Lane - LINK_RATE_UHBR20 = 2000, // UHBR10 - 20.0 Gbps/Lane -#else LINK_RATE_HIGH3 = 0x1E // Rate_8 (HBR3)- 8.10 Gbps/Lane -#endif }; enum dc_link_spread { @@ -100,47 +90,17 @@ enum dc_post_cursor2 { POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3, }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum dc_dp_ffe_preset_level { - DP_FFE_PRESET_LEVEL0 = 0, - DP_FFE_PRESET_LEVEL1, - DP_FFE_PRESET_LEVEL2, - DP_FFE_PRESET_LEVEL3, - DP_FFE_PRESET_LEVEL4, - DP_FFE_PRESET_LEVEL5, - DP_FFE_PRESET_LEVEL6, - DP_FFE_PRESET_LEVEL7, - DP_FFE_PRESET_LEVEL8, - DP_FFE_PRESET_LEVEL9, - DP_FFE_PRESET_LEVEL10, - DP_FFE_PRESET_LEVEL11, - DP_FFE_PRESET_LEVEL12, - DP_FFE_PRESET_LEVEL13, - DP_FFE_PRESET_LEVEL14, - DP_FFE_PRESET_LEVEL15, - DP_FFE_PRESET_MAX_LEVEL = DP_FFE_PRESET_LEVEL15, -}; -#endif - enum dc_dp_training_pattern { DP_TRAINING_PATTERN_SEQUENCE_1 = 0, DP_TRAINING_PATTERN_SEQUENCE_2, DP_TRAINING_PATTERN_SEQUENCE_3, DP_TRAINING_PATTERN_SEQUENCE_4, DP_TRAINING_PATTERN_VIDEOIDLE, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DP_128b_132b_TPS1, - DP_128b_132b_TPS2, - DP_128b_132b_TPS2_CDS, -#endif }; enum dp_link_encoding { DP_UNKNOWN_ENCODING = 0, DP_8b_10b_ENCODING = 1, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DP_128b_132b_ENCODING = 2, -#endif }; struct dc_link_settings { @@ -152,35 +112,21 @@ struct dc_link_settings { bool dpcd_source_device_specific_field_support; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -union dc_dp_ffe_preset { - struct { - uint8_t level : 4; - uint8_t reserved : 1; - uint8_t no_preshoot : 1; - uint8_t no_deemphasis : 1; - uint8_t method2 : 1; - } settings; - uint8_t raw; -}; -#endif - struct dc_lane_settings { enum dc_voltage_swing VOLTAGE_SWING; enum dc_pre_emphasis PRE_EMPHASIS; enum dc_post_cursor2 POST_CURSOR2; -#if defined(CONFIG_DRM_AMD_DC_DCN) - union dc_dp_ffe_preset FFE_PRESET; -#endif +}; + +struct dc_link_training_settings { + struct dc_link_settings link; + struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]; }; struct dc_link_training_overrides { enum dc_voltage_swing *voltage_swing; enum dc_pre_emphasis *pre_emphasis; enum dc_post_cursor2 *post_cursor2; -#if defined(CONFIG_DRM_AMD_DC_DCN) - union dc_dp_ffe_preset *ffe_preset; -#endif uint16_t *cr_pattern_time; uint16_t *eq_pattern_time; @@ -194,16 +140,6 @@ struct dc_link_training_overrides { bool *fec_enable; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -union payload_table_update_status { - struct { - uint8_t VC_PAYLOAD_TABLE_UPDATED:1; - uint8_t ACT_HANDLED:1; - } bits; - uint8_t raw; -}; -#endif - union dpcd_rev { struct { uint8_t MINOR:4; @@ -291,14 +227,7 @@ union lane_align_status_updated { struct { uint8_t INTERLANE_ALIGN_DONE:1; uint8_t POST_LT_ADJ_REQ_IN_PROGRESS:1; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t EQ_INTERLANE_ALIGN_DONE_128b_132b:1; - uint8_t CDS_INTERLANE_ALIGN_DONE_128b_132b:1; - uint8_t LT_FAILED_128b_132b:1; - uint8_t RESERVED:1; -#else uint8_t RESERVED:4; -#endif uint8_t DOWNSTREAM_PORT_STATUS_CHANGED:1; uint8_t LINK_STATUS_UPDATED:1; } bits; @@ -311,12 +240,6 @@ union lane_adjust { uint8_t PRE_EMPHASIS_LANE:2; uint8_t RESERVED:4; } bits; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct { - uint8_t PRESET_VALUE :4; - uint8_t RESERVED :4; - } tx_ffe; -#endif uint8_t raw; }; @@ -346,12 +269,6 @@ union dpcd_training_lane { uint8_t MAX_PRE_EMPHASIS_REACHED:1; uint8_t RESERVED:2; } bits; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct { - uint8_t PRESET_VALUE :4; - uint8_t RESERVED :4; - } tx_ffe; -#endif uint8_t raw; }; @@ -378,14 +295,7 @@ enum dpcd_downstream_port_detailed_type { union dwnstream_port_caps_byte2 { struct { uint8_t MAX_BITS_PER_COLOR_COMPONENT:2; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t MAX_ENCODED_LINK_BW_SUPPORT:3; - uint8_t SOURCE_CONTROL_MODE_SUPPORT:1; - uint8_t CONCURRENT_LINK_BRING_UP_SEQ_SUPPORT:1; - uint8_t RESERVED:1; -#else uint8_t RESERVED:6; -#endif } bits; uint8_t raw; }; @@ -423,30 +333,6 @@ union dwnstream_port_caps_byte3_hdmi { uint8_t raw; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -union hdmi_sink_encoded_link_bw_support { - struct { - uint8_t HDMI_SINK_ENCODED_LINK_BW_SUPPORT:3; - uint8_t RESERVED:5; - } bits; - uint8_t raw; -}; - -union hdmi_encoded_link_bw { - struct { - uint8_t FRL_MODE:1; // Bit 0 - uint8_t BW_9Gbps:1; - uint8_t BW_18Gbps:1; - uint8_t BW_24Gbps:1; - uint8_t BW_32Gbps:1; - uint8_t BW_40Gbps:1; - uint8_t BW_48Gbps:1; - uint8_t RESERVED:1; // Bit 7 - } bits; - uint8_t raw; -}; -#endif - /*4-byte structure for detailed capabilities of a down-stream port (DP-to-TMDS converter).*/ union dwnstream_portxcaps { @@ -665,18 +551,12 @@ union test_response { union phy_test_pattern { struct { -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* This field is 7 bits for DP2.0 */ - uint8_t PATTERN :7; - uint8_t RESERVED :1; -#else /* DpcdPhyTestPatterns. This field is 2 bits for DP1.1 * and 3 bits for DP1.2. */ uint8_t PATTERN :3; /* BY speci, bit7:2 is 0 for DP1.1. */ uint8_t RESERVED :5; -#endif } bits; uint8_t raw; }; @@ -754,14 +634,7 @@ union dpcd_fec_capability { uint8_t UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1; uint8_t CORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1; uint8_t BIT_ERROR_COUNT_CAPABLE:1; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint8_t PARITY_BLOCK_ERROR_COUNT_CAPABLE:1; - uint8_t ARITY_BIT_ERROR_COUNT_CAPABLE:1; - uint8_t FEC_RUNNING_INDICATOR_SUPPORTED:1; - uint8_t FEC_ERROR_REPORTING_POLICY_SUPPORTED:1; -#else uint8_t RESERVED:4; -#endif } bits; uint8_t raw; }; @@ -883,214 +756,6 @@ struct psr_caps { unsigned char psr_version; unsigned int psr_rfb_setup_time; bool psr_exit_link_training_required; - unsigned char edp_revision; - unsigned char support_ver; - bool su_granularity_required; - bool y_coordinate_required; - uint8_t su_y_granularity; - bool alpm_cap; - bool standby_support; - uint8_t rate_control_caps; - unsigned int psr_power_opt_flag; }; -/* Length of router topology ID read from DPCD in bytes. */ -#define DPCD_USB4_TOPOLOGY_ID_LEN 5 - -/* DPCD[0xE000D] DP_TUNNELING_CAPABILITIES SUPPORT register. */ -union dp_tun_cap_support { - struct { - uint8_t dp_tunneling :1; - uint8_t rsvd :5; - uint8_t panel_replay_tun_opt :1; - uint8_t dpia_bw_alloc :1; - } bits; - uint8_t raw; -}; - -/* DPCD[0xE000E] DP_IN_ADAPTER_INFO register. */ -union dpia_info { - struct { - uint8_t dpia_num :5; - uint8_t rsvd :3; - } bits; - uint8_t raw; -}; - -/* DP Tunneling over USB4 */ -struct dpcd_usb4_dp_tunneling_info { - union dp_tun_cap_support dp_tun_cap; - union dpia_info dpia_info; - uint8_t usb4_driver_id; - uint8_t usb4_topology_id[DPCD_USB4_TOPOLOGY_ID_LEN]; -}; - -#if defined(CONFIG_DRM_AMD_DC_DCN) -#ifndef DP_MAIN_LINK_CHANNEL_CODING_CAP -#define DP_MAIN_LINK_CHANNEL_CODING_CAP 0x006 -#endif -#ifndef DP_SINK_VIDEO_FALLBACK_FORMATS -#define DP_SINK_VIDEO_FALLBACK_FORMATS 0x020 -#endif -#ifndef DP_FEC_CAPABILITY_1 -#define DP_FEC_CAPABILITY_1 0x091 -#endif -#ifndef DP_DFP_CAPABILITY_EXTENSION_SUPPORT -#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3 -#endif -#ifndef DP_LINK_SQUARE_PATTERN -#define DP_LINK_SQUARE_PATTERN 0x10F -#endif -#ifndef DP_DSC_CONFIGURATION -#define DP_DSC_CONFIGURATION 0x161 -#endif -#ifndef DP_PHY_SQUARE_PATTERN -#define DP_PHY_SQUARE_PATTERN 0x249 -#endif -#ifndef DP_128b_132b_SUPPORTED_LINK_RATES -#define DP_128b_132b_SUPPORTED_LINK_RATES 0x2215 -#endif -#ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL -#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216 -#endif -#ifndef DP_TEST_264BIT_CUSTOM_PATTERN_7_0 -#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230 -#endif -#ifndef DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -#define DP_TEST_264BIT_CUSTOM_PATTERN_263_256 0X2250 -#endif -#ifndef DP_DSC_SUPPORT_AND_DECODER_COUNT -#define DP_DSC_SUPPORT_AND_DECODER_COUNT 0x2260 -#endif -#ifndef DP_DSC_MAX_SLICE_COUNT_AND_AGGREGATION_0 -#define DP_DSC_MAX_SLICE_COUNT_AND_AGGREGATION_0 0x2270 -#endif -#ifndef DP_DSC_DECODER_0_MAXIMUM_SLICE_COUNT_MASK -#define DP_DSC_DECODER_0_MAXIMUM_SLICE_COUNT_MASK (1 << 0) -#endif -#ifndef DP_DSC_DECODER_0_AGGREGATION_SUPPORT_MASK -#define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_MASK (0b111 << 1) -#endif -#ifndef DP_DSC_DECODER_0_AGGREGATION_SUPPORT_SHIFT -#define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_SHIFT 1 -#endif -#ifndef DP_DSC_DECODER_COUNT_MASK -#define DP_DSC_DECODER_COUNT_MASK (0b111 << 5) -#endif -#ifndef DP_DSC_DECODER_COUNT_SHIFT -#define DP_DSC_DECODER_COUNT_SHIFT 5 -#endif -#ifndef DP_MAIN_LINK_CHANNEL_CODING_SET -#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 -#endif -#ifndef DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER -#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER 0xF0006 -#endif -#ifndef DP_PHY_REPEATER_128b_132b_RATES -#define DP_PHY_REPEATER_128b_132b_RATES 0xF0007 -#endif -#ifndef DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 -#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 0xF0022 -#endif -#ifndef DP_INTRA_HOP_AUX_REPLY_INDICATION -#define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3) -#endif -/* TODO - Use DRM header to replace above once available */ - -union dp_main_line_channel_coding_cap { - struct { - uint8_t DP_8b_10b_SUPPORTED :1; - uint8_t DP_128b_132b_SUPPORTED :1; - uint8_t RESERVED :6; - } bits; - uint8_t raw; -}; - -union dp_main_link_channel_coding_lttpr_cap { - struct { - uint8_t DP_128b_132b_SUPPORTED :1; - uint8_t RESERVED :7; - } bits; - uint8_t raw; -}; - -union dp_128b_132b_supported_link_rates { - struct { - uint8_t UHBR10 :1; - uint8_t UHBR20 :1; - uint8_t UHBR13_5:1; - uint8_t RESERVED:5; - } bits; - uint8_t raw; -}; - -union dp_128b_132b_supported_lttpr_link_rates { - struct { - uint8_t UHBR10 :1; - uint8_t UHBR13_5:1; - uint8_t UHBR20 :1; - uint8_t RESERVED:5; - } bits; - uint8_t raw; -}; - -union dp_sink_video_fallback_formats { - struct { - uint8_t dp_1024x768_60Hz_24bpp_support :1; - uint8_t dp_1280x720_60Hz_24bpp_support :1; - uint8_t dp_1920x1080_60Hz_24bpp_support :1; - uint8_t RESERVED :5; - } bits; - uint8_t raw; -}; - -union dp_fec_capability1 { - struct { - uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1; - uint8_t RESERVED :7; - } bits; - uint8_t raw; -}; - -struct dp_color_depth_caps { - uint8_t support_6bpc :1; - uint8_t support_8bpc :1; - uint8_t support_10bpc :1; - uint8_t support_12bpc :1; - uint8_t support_16bpc :1; - uint8_t RESERVED :3; -}; - -struct dp_encoding_format_caps { - uint8_t support_rgb :1; - uint8_t support_ycbcr444:1; - uint8_t support_ycbcr422:1; - uint8_t support_ycbcr420:1; - uint8_t RESERVED :4; -}; - -union dp_dfp_cap_ext { - struct { - uint8_t supported; - uint8_t max_pixel_rate_in_mps[2]; - uint8_t max_video_h_active_width[2]; - uint8_t max_video_v_active_height[2]; - struct dp_encoding_format_caps encoding_format_caps; - struct dp_color_depth_caps rgb_color_depth_caps; - struct dp_color_depth_caps ycbcr444_color_depth_caps; - struct dp_color_depth_caps ycbcr422_color_depth_caps; - struct dp_color_depth_caps ycbcr420_color_depth_caps; - } fields; - uint8_t raw[12]; -}; - -union dp_128b_132b_training_aux_rd_interval { - struct { - uint8_t VALUE :7; - uint8_t UNIT :1; - } bits; - uint8_t raw; -}; -#endif - #endif /* DC_DP_TYPES_H */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h index 684713b2cf..16cc76ce37 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h @@ -51,6 +51,7 @@ struct dc_dsc_policy { int min_slice_height; // Must not be less than 8 uint32_t max_target_bpp; uint32_t min_target_bpp; + uint32_t preferred_bpp_x16; bool enable_dsc_when_not_needed; }; @@ -80,16 +81,6 @@ bool dc_dsc_compute_config( uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing, uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp); -uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps( - const struct dc_crtc_timing *timing, - const int num_slices_h, - const bool is_dp); - -/* TODO - Hardware/specs limitation should be owned by dc dsc and returned to DM, - * and DM can choose to OVERRIDE the limitation on CASE BY CASE basis. - * Hardware/specs limitation should not be writable by DM. - * It should be decoupled from DM specific policy and named differently. - */ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy); diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h index eac34f591a..52355fe699 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -741,9 +741,6 @@ struct dc_dsc_config { uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */ bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */ int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - bool is_frl; /* indicate if DSC is applied based on HDMI FRL sink's capability */ -#endif bool is_dp; /* indicate if DSC is applied based on DP's capability */ }; struct dc_crtc_timing { diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index c0e37ad0e2..83845d006c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -30,8 +30,6 @@ #include "dc_types.h" #include "grph_object_defs.h" -struct link_resource; - enum dc_link_fec_state { dc_link_fec_not_ready, dc_link_fec_ready, @@ -47,10 +45,6 @@ struct dc_link_status { struct link_mst_stream_allocation { /* DIG front */ const struct stream_encoder *stream_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* HPO DP Stream Encoder */ - const struct hpo_dp_stream_encoder *hpo_dp_stream_enc; -#endif /* associate DRM payload table with DC stream encoder */ uint8_t vcp_id; /* number of slots required for the DP stream in transport packet */ @@ -87,7 +81,6 @@ struct psr_settings { */ bool psr_frame_capture_indication_req; unsigned int psr_sdp_transmit_line_num_deadline; - unsigned int psr_power_opt; }; /* @@ -115,7 +108,6 @@ struct dc_link { * DIG encoder. */ bool is_dig_mapping_flexible; bool hpd_status; /* HPD status of link without physical HPD pin. */ - bool is_hpd_pending; /* Indicates a new received hpd */ bool edp_sink_present; @@ -125,12 +117,8 @@ struct dc_link { struct dc_link_settings reported_link_cap; struct dc_link_settings verified_link_cap; struct dc_link_settings cur_link_settings; - struct dc_lane_settings cur_lane_setting[LANE_COUNT_DP_MAX]; + struct dc_lane_settings cur_lane_setting; struct dc_link_settings preferred_link_setting; - /* preferred_training_settings are override values that - * come from DM. DM is responsible for the memory - * management of the override pointers. - */ struct dc_link_training_overrides preferred_training_settings; struct dp_audio_test_data audio_test_data; @@ -182,21 +170,11 @@ struct dc_link { struct psr_settings psr_settings; - /* Drive settings read from integrated info table */ - struct dc_lane_settings bios_forced_drive_settings; - - /* Vendor specific LTTPR workaround variables */ - uint8_t vendor_specific_lttpr_link_rate_wa; - bool apply_vendor_specific_lttpr_link_rate_wa; - /* MST record stream using this link */ struct link_flags { bool dp_keep_receiver_powered; bool dp_skip_DID2; bool dp_skip_reset_segment; - bool dp_mot_reset_segment; - /* Some USB4 docks do not handle turning off MST DSC once it has been enabled. */ - bool dpia_mst_dsc_always_on; } wa_flags; struct link_mst_stream_allocation_table mst_stream_alloc_table; @@ -230,8 +208,6 @@ static inline void get_edp_links(const struct dc *dc, *edp_num = 0; for (i = 0; i < dc->link_count; i++) { // report any eDP links, even unconnected DDI's - if (!dc->links[i]) - continue; if (dc->links[i]->connector_signal == SIGNAL_TYPE_EDP) { edp_links[*edp_num] = dc->links[i]; if (++(*edp_num) == MAX_NUM_EDP) @@ -284,8 +260,8 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link); int dc_link_get_target_backlight_pwm(const struct dc_link *link); -bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable, - bool wait, bool force_static, const unsigned int *power_opts); +bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable, + bool wait, bool force_static); bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state); @@ -295,10 +271,6 @@ bool dc_link_setup_psr(struct dc_link *dc_link, void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency); -void dc_link_blank_all_dp_displays(struct dc *dc); - -void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init); - /* Request DC to detect if there is a Panel connected. * boot - If this call is during initial boot. * Return false for any type of detection failure or MST detection @@ -310,16 +282,12 @@ enum dc_detect_reason { DETECT_REASON_HPD, DETECT_REASON_HPDRX, DETECT_REASON_FALLBACK, - DETECT_REASON_RETRAIN, + DETECT_REASON_RETRAIN }; bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason); bool dc_link_get_hpd_state(struct dc_link *dc_link); enum dc_status dc_link_allocate_mst_payload(struct pipe_ctx *pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum dc_status dc_link_reduce_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); -enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t req_pbn); -#endif /* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt). * Return: @@ -328,8 +296,7 @@ enum dc_status dc_link_increase_mst_payload(struct pipe_ctx *pipe_ctx, uint32_t * false - no change in Downstream port status. No further action required * from DM. */ bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, - union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss, - bool defer_handling, bool *has_left_work); + union hpd_irq_data *hpd_irq_dpcd_data, bool *out_link_loss); /* * On eDP links this function call will stall until T12 has elapsed. @@ -338,9 +305,9 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link, */ bool dc_link_wait_for_t12(struct dc_link *link); -void dc_link_dp_handle_automated_test(struct dc_link *link); -void dc_link_dp_handle_link_loss(struct dc_link *link); -bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link); +enum dc_status read_hpd_rx_irq_data( + struct dc_link *link, + union hpd_irq_data *irq_data); struct dc_sink_init_data; @@ -358,17 +325,14 @@ void dc_link_remove_remote_sink( void dc_link_dp_set_drive_settings( struct dc_link *link, - const struct link_resource *link_res, struct link_training_settings *lt_settings); bool dc_link_dp_perform_link_training_skip_aux( struct dc_link *link, - const struct link_resource *link_res, const struct dc_link_settings *link_setting); enum link_training_result dc_link_dp_perform_link_training( struct dc_link *link, - const struct link_resource *link_res, const struct dc_link_settings *link_settings, bool skip_video_pattern); @@ -376,7 +340,6 @@ bool dc_link_dp_sync_lt_begin(struct dc_link *link); enum link_training_result dc_link_dp_sync_lt_attempt( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *link_setting, struct dc_link_training_overrides *lt_settings); @@ -453,14 +416,4 @@ uint32_t dc_bandwidth_in_kbps_from_timing( bool dc_link_is_fec_supported(const struct dc_link *link); bool dc_link_should_enable_fec(const struct dc_link *link); -#if defined(CONFIG_DRM_AMD_DC_DCN) -uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw); -enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link); -#endif - -const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link); -/* take a snapshot of current link resource allocation state */ -void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map); -/* restore link resource allocation state from a snapshot */ -void dc_restore_link_res_map(const struct dc *dc, uint32_t *map); #endif /* DC_LINK_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index e37c4a10bf..b8ebc1f095 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -115,13 +115,6 @@ struct periodic_interrupt_config { int lines_offset; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct dc_mst_stream_bw_update { - bool is_increase; // is bandwidth reduced or increased - uint32_t mst_stream_bw; // new mst bandwidth in kbps -}; -#endif - union stream_update_flags { struct { uint32_t scaling:1; @@ -132,9 +125,6 @@ union stream_update_flags { uint32_t gamut_remap:1; uint32_t wb_update:1; uint32_t dsc_changed : 1; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint32_t mst_bw : 1; -#endif } bits; uint32_t raw; @@ -288,9 +278,6 @@ struct dc_stream_update { struct dc_writeback_update *wb_update; struct dc_dsc_config *dsc_config; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct dc_mst_stream_bw_update *mst_bw_update; -#endif struct dc_transfer_func *func_shaper; struct dc_3dlut *lut3d_func; diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0285a4b38d..c153293016 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -395,27 +395,9 @@ struct dc_lttpr_caps { uint8_t max_link_rate; uint8_t phy_repeater_cnt; uint8_t max_ext_timeout; -#if defined(CONFIG_DRM_AMD_DC_DCN) - union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding; - union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates; -#endif uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1]; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct dc_dongle_dfp_cap_ext { - bool supported; - uint16_t max_pixel_rate_in_mps; - uint16_t max_video_h_active_width; - uint16_t max_video_v_active_height; - struct dp_encoding_format_caps encoding_format_caps; - struct dp_color_depth_caps rgb_color_depth_caps; - struct dp_color_depth_caps ycbcr444_color_depth_caps; - struct dp_color_depth_caps ycbcr422_color_depth_caps; - struct dp_color_depth_caps ycbcr420_color_depth_caps; -}; -#endif - struct dc_dongle_caps { /* dongle type (DP converter, CV smart dongle) */ enum display_dongle_type dongle_type; @@ -429,10 +411,6 @@ struct dc_dongle_caps { bool is_dp_hdmi_ycbcr420_converter; uint32_t dp_hdmi_max_bpc; uint32_t dp_hdmi_max_pixel_clk_in_khz; -#if defined(CONFIG_DRM_AMD_DC_DCN) - uint32_t dp_hdmi_frl_max_link_bw_in_kbps; - struct dc_dongle_dfp_cap_ext dfp_cap_ext; -#endif }; /* Scaling format */ enum scaling_transformation { @@ -654,7 +632,6 @@ enum dc_psr_state { PSR_STATE1a, PSR_STATE2, PSR_STATE2a, - PSR_STATE2b, PSR_STATE3, PSR_STATE3Init, PSR_STATE4, @@ -951,14 +928,12 @@ enum dc_gpu_mem_alloc_type { enum dc_psr_version { DC_PSR_VERSION_1 = 0, - DC_PSR_VERSION_SU_1 = 1, DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, }; /* Possible values of display_endpoint_id.endpoint */ enum display_endpoint_type { DISPLAY_ENDPOINT_PHY = 0, /* Physical connector. */ - DISPLAY_ENDPOINT_USB4_DPIA, /* USB4 DisplayPort tunnel. */ DISPLAY_ENDPOINT_UNKNOWN = -1 }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h index b699d1b2ba..456fadbbfa 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.h @@ -96,22 +96,6 @@ SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ NBIO_SR(BIOS_SCRATCH_2) -#define ABM_DCN302_REG_LIST(id)\ - ABM_COMMON_REG_LIST_DCE_BASE(), \ - SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ - SRI(DC_ABM1_LS_SAMPLE_RATE, ABM, id), \ - SRI(BL1_PWM_BL_UPDATE_SAMPLE_RATE, ABM, id), \ - SRI(DC_ABM1_HG_MISC_CTRL, ABM, id), \ - SRI(DC_ABM1_IPCSC_COEFF_SEL, ABM, id), \ - SRI(BL1_PWM_CURRENT_ABM_LEVEL, ABM, id), \ - SRI(BL1_PWM_TARGET_ABM_LEVEL, ABM, id), \ - SRI(BL1_PWM_USER_LEVEL, ABM, id), \ - SRI(DC_ABM1_LS_MIN_MAX_PIXEL_VALUE_THRES, ABM, id), \ - SRI(DC_ABM1_HGLS_REG_READ_PROGRESS, ABM, id), \ - SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \ - SRI(DC_ABM1_ACE_THRES_12, ABM, id), \ - NBIO_SR(BIOS_SCRATCH_2) - #define ABM_DCN30_REG_LIST(id)\ ABM_COMMON_REG_LIST_DCE_BASE(), \ SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index 70eaac0176..7866cf2a66 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -67,6 +67,9 @@ static void write_indirect_azalia_reg(struct audio *audio, /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */ REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0, AZALIA_ENDPOINT_REG_DATA, reg_data); + + DC_LOG_HW_AUDIO("AUDIO:write_indirect_azalia_reg: index: %u data: %u\n", + reg_index, reg_data); } static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index) @@ -82,6 +85,9 @@ static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */ value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA); + DC_LOG_HW_AUDIO("AUDIO:read_indirect_azalia_reg: index: %u data: %u\n", + reg_index, value); + return value; } @@ -508,15 +514,13 @@ void dce_aud_az_configure( union audio_sample_rates sample_rates = audio_mode->sample_rates; uint8_t byte2 = audio_mode->max_bit_rate; - uint8_t channel_count = audio_mode->channel_count; /* adjust specific properties */ switch (audio_format_code) { case AUDIO_FORMAT_CODE_LINEARPCM: { - check_audio_bandwidth( crtc_info, - channel_count, + audio_mode->channel_count, signal, &sample_rates); @@ -544,7 +548,7 @@ void dce_aud_az_configure( /* fill audio format data */ set_reg_field_value(value, - channel_count - 1, + audio_mode->channel_count - 1, AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0, MAX_CHANNELS); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h index dbd2cfed06..5622d5e32d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.h @@ -113,7 +113,6 @@ struct dce_audio_shift { uint8_t DCCG_AUDIO_DTO2_USE_512FBR_DTO; uint32_t DCCG_AUDIO_DTO0_USE_512FBR_DTO; uint32_t DCCG_AUDIO_DTO1_USE_512FBR_DTO; - uint32_t CLOCK_GATING_DISABLE; }; struct dce_audio_mask { @@ -133,7 +132,6 @@ struct dce_audio_mask { uint32_t DCCG_AUDIO_DTO2_USE_512FBR_DTO; uint32_t DCCG_AUDIO_DTO0_USE_512FBR_DTO; uint32_t DCCG_AUDIO_DTO1_USE_512FBR_DTO; - uint32_t CLOCK_GATING_DISABLE; }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c index 6d42a9cc99..3c33473411 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -534,26 +534,17 @@ struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload) { if (payload->i2c_over_aux) { - if (payload->write_status_update) { - if (payload->mot) - return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT; - else - return I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST; - } if (payload->write) { if (payload->mot) return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT; - else - return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; + return I2CAUX_TRANSACTION_ACTION_I2C_WRITE; } if (payload->mot) return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT; - return I2CAUX_TRANSACTION_ACTION_I2C_READ; } if (payload->write) return I2CAUX_TRANSACTION_ACTION_DP_WRITE; - return I2CAUX_TRANSACTION_ACTION_DP_READ; } @@ -636,7 +627,6 @@ int dce_aux_transfer_dmub_raw(struct ddc_service *ddc, #define AUX_MAX_I2C_DEFER_RETRIES 7 #define AUX_MAX_INVALID_REPLY_RETRIES 2 #define AUX_MAX_TIMEOUT_RETRIES 3 -#define AUX_DEFER_DELAY_FOR_DPIA 4 /*ms*/ static void dce_aux_log_payload(const char *payload_name, unsigned char *payload, uint32_t length, uint32_t max_length_to_log) @@ -699,21 +689,15 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, enum aux_return_code_type operation_result; bool retry_on_defer = false; struct ddc *ddc_pin = ddc->ddc_pin; - struct dce_aux *aux_engine = NULL; - struct aux_engine_dce110 *aux110 = NULL; + struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; + struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine); uint32_t defer_time_in_ms = 0; int aux_ack_retries = 0, aux_defer_retries = 0, aux_i2c_defer_retries = 0, aux_timeout_retries = 0, - aux_invalid_reply_retries = 0, - aux_ack_m_retries = 0; - - if (ddc_pin) { - aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]; - aux110 = FROM_AUX_ENGINE(aux_engine); - } + aux_invalid_reply_retries = 0; if (!payload->reply) { payload_reply = false; @@ -768,27 +752,9 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, aux_defer_retries, AUX_MAX_RETRIES); goto fail; - } else + } else { udelay(300); - } else if (payload->write && ret > 0) { - /* sink requested more time to complete the write via AUX_ACKM */ - if (++aux_ack_m_retries >= AUX_MAX_RETRIES) { - DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, - LOG_FLAG_Error_I2cAux, - "dce_aux_transfer_with_retries: FAILURE: aux_ack_m_retries=%d >= AUX_MAX_RETRIES=%d", - aux_ack_m_retries, - AUX_MAX_RETRIES); - goto fail; } - - /* retry reading the write status until complete - * NOTE: payload is modified here - */ - payload->write = false; - payload->write_status_update = true; - payload->length = 0; - udelay(300); - } else return true; break; @@ -799,10 +765,7 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc, "dce_aux_transfer_with_retries: AUX_RET_SUCCESS: AUX_TRANSACTION_REPLY_AUX_DEFER"); /* polling_timeout_period is in us */ - if (aux110) - defer_time_in_ms += aux110->polling_timeout_period / 1000; - else - defer_time_in_ms += AUX_DEFER_DELAY_FOR_DPIA; + defer_time_in_ms += aux110->polling_timeout_period / 1000; ++aux_defer_retries; fallthrough; case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER: diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h index 692fa23ca0..3139285bd4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h @@ -76,15 +76,6 @@ SRII(PIXEL_RATE_CNTL, OTG, 4),\ SRII(PIXEL_RATE_CNTL, OTG, 5) -#define CS_COMMON_REG_LIST_DCN201(index, pllid) \ - SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ - SRII(PHASE, DP_DTO, 0),\ - SRII(PHASE, DP_DTO, 1),\ - SRII(MODULO, DP_DTO, 0),\ - SRII(MODULO, DP_DTO, 1),\ - SRII(PIXEL_RATE_CNTL, OTG, 0),\ - SRII(PIXEL_RATE_CNTL, OTG, 1) - #define CS_COMMON_REG_LIST_DCN2_1(index, pllid) \ SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ SRII(PHASE, DP_DTO, 0),\ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h index a3fee929cd..0464a8f3db 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.h @@ -70,10 +70,6 @@ SRII(PIXEL_RATE_CNTL, blk, 4), \ SRII(PIXEL_RATE_CNTL, blk, 5) -#define HWSEQ_PIXEL_RATE_REG_LIST_201(blk) \ - SRII(PIXEL_RATE_CNTL, blk, 0), \ - SRII(PIXEL_RATE_CNTL, blk, 1) - #define HWSEQ_PHYPLL_REG_LIST(blk) \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1), \ @@ -98,10 +94,6 @@ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) -#define HWSEQ_PHYPLL_REG_LIST_201(blk) \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 0), \ - SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 1) - #define HWSEQ_DCE11_REG_LIST_BASE() \ SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ SR(DCFEV_CLOCK_CONTROL), \ @@ -345,29 +337,6 @@ SR(D6VGA_CONTROL), \ SR(DC_IP_REQUEST_CNTL) -#define HWSEQ_DCN201_REG_LIST()\ - HWSEQ_DCN_REG_LIST(), \ - HWSEQ_PIXEL_RATE_REG_LIST_201(OTG), \ - HWSEQ_PHYPLL_REG_LIST_201(OTG), \ - SR(MICROSECOND_TIME_BASE_DIV), \ - SR(MILLISECOND_TIME_BASE_DIV), \ - SR(DISPCLK_FREQ_CHANGE_CNTL), \ - SR(RBBMIF_TIMEOUT_DIS), \ - SR(RBBMIF_TIMEOUT_DIS_2), \ - SR(DCHUBBUB_CRC_CTRL), \ - SR(DPP_TOP0_DPP_CRC_CTRL), \ - SR(DPP_TOP0_DPP_CRC_VAL_B_A), \ - SR(DPP_TOP0_DPP_CRC_VAL_R_G), \ - SR(MPC_CRC_CTRL), \ - SR(MPC_CRC_RESULT_GB), \ - SR(MPC_CRC_RESULT_C), \ - SR(MPC_CRC_RESULT_AR), \ - SR(AZALIA_AUDIO_DTO), \ - SR(AZALIA_CONTROLLER_CLOCK_GATING), \ - MMHUB_SR(MC_VM_FB_LOCATION_BASE), \ - MMHUB_SR(MC_VM_FB_LOCATION_TOP), \ - MMHUB_SR(MC_VM_FB_OFFSET) - #define HWSEQ_DCN30_REG_LIST()\ HWSEQ_DCN2_REG_LIST(),\ HWSEQ_DCN_REG_LIST(), \ @@ -668,10 +637,6 @@ struct dce_hwseq_registers { uint32_t DMU_MEM_PWR_CNTL; uint32_t MMHUBBUB_MEM_PWR_CNTL; uint32_t DCHUBBUB_ARB_HOSTVM_CNTL; - uint32_t MC_VM_FB_LOCATION_BASE; - uint32_t MC_VM_FB_LOCATION_TOP; - uint32_t MC_VM_FB_OFFSET; - uint32_t HPO_TOP_HW_CONTROL; }; /* set field name */ #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ @@ -907,11 +872,6 @@ struct dce_hwseq_registers { HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) -#define HWSEQ_DCN201_MASK_SH_LIST(mask_sh)\ - HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ - HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ - HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh) - #define HWSEQ_DCN30_MASK_SH_LIST(mask_sh)\ HWSEQ_DCN2_MASK_SH_LIST(mask_sh), \ HWS_SF(, AZALIA_AUDIO_DTO, AZALIA_AUDIO_DTO_MODULE, mask_sh), \ @@ -1152,9 +1112,7 @@ struct dce_hwseq_registers { type DOMAIN_POWER_GATE;\ type DOMAIN_PGFSM_PWR_STATUS;\ type HPO_HDMISTREAMCLK_G_GATE_DIS;\ - type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE;\ - type I2C_LIGHT_SLEEP_FORCE;\ - type HPO_IO_EN; + type DISABLE_HOSTVM_FORCE_ALLOW_PSTATE; struct dce_hwseq_shift { HWSEQ_REG_FIELD_LIST(uint8_t) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index f1c61d5aee..1e77ffee71 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -788,9 +788,8 @@ static bool dce110_link_encoder_validate_hdmi_output( crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) return false; - if ((!enc110->base.features.flags.bits.HDMI_6GB_EN || - enc110->base.ctx->dc->debug.hdmi20_disable) && - adjusted_pix_clk_khz >= 300000) + if (!enc110->base.features.flags.bits.HDMI_6GB_EN && + adjusted_pix_clk_khz >= 300000) return false; if (enc110->base.ctx->dc->debug.hdmi20_disable && crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 779bc92a29..8d4263da59 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -919,7 +919,6 @@ static void dce110_stream_encoder_stop_dp_info_packets( } static void dce110_stream_encoder_dp_blank( - struct dc_link *link, struct stream_encoder *enc) { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); @@ -968,7 +967,6 @@ static void dce110_stream_encoder_dp_blank( /* output video stream to link encoder */ static void dce110_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param) { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index fb0dec4ed3..54a1408c80 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -203,33 +203,12 @@ static bool dmub_abm_init_config(struct abm *abm, return true; } -static bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst) -{ - union dmub_rb_cmd cmd; - struct dc_context *dc = abm->ctx; - uint8_t panel_mask = 0x01 << panel_inst; - - memset(&cmd, 0, sizeof(cmd)); - cmd.abm_pause.header.type = DMUB_CMD__ABM; - cmd.abm_pause.header.sub_type = DMUB_CMD__ABM_PAUSE; - cmd.abm_pause.abm_pause_data.enable = pause; - cmd.abm_pause.abm_pause_data.panel_mask = panel_mask; - cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_pause_data); - - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); - dc_dmub_srv_cmd_execute(dc->dmub_srv); - dc_dmub_srv_wait_idle(dc->dmub_srv); - - return true; -} - static const struct abm_funcs abm_funcs = { .abm_init = dmub_abm_init, .set_abm_level = dmub_abm_set_level, .get_current_backlight = dmub_abm_get_current_backlight, .get_target_backlight = dmub_abm_get_target_backlight, .init_abm_config = dmub_abm_init_config, - .set_abm_pause = dmub_abm_set_pause, }; static void dmub_abm_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c index b1b2e3c6f3..9baf8ca0a9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c @@ -56,11 +56,8 @@ void dmub_hw_lock_mgr_inbox0_cmd(struct dc_dmub_srv *dmub_srv, union dmub_inbox0_cmd_lock_hw hw_lock_cmd) { union dmub_inbox0_data_register data = { 0 }; - data.inbox0_cmd_lock_hw = hw_lock_cmd; - dc_dmub_srv_clear_inbox0_ack(dmub_srv); dc_dmub_srv_send_inbox0_cmd(dmub_srv, data); - dc_dmub_srv_wait_for_inbox0_ack(dmub_srv); } bool should_use_dmub_lock(struct dc_link *link) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 87ed48d553..aa8403bc4c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -50,8 +50,6 @@ static enum dc_psr_state convert_psr_state(uint32_t raw_state) state = PSR_STATE2; else if (raw_state == 0x21) state = PSR_STATE2a; - else if (raw_state == 0x22) - state = PSR_STATE2b; else if (raw_state == 0x30) state = PSR_STATE3; else if (raw_state == 0x31) @@ -227,27 +225,6 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_ dc_dmub_srv_wait_idle(dc->dmub_srv); } -/** - * Set PSR power optimization flags. - */ -static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst) -{ - union dmub_rb_cmd cmd; - struct dc_context *dc = dmub->ctx; - - memset(&cmd, 0, sizeof(cmd)); - cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR; - cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT; - cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data); - cmd.psr_set_power_opt.psr_set_power_opt_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; - cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt; - cmd.psr_set_power_opt.psr_set_power_opt_data.panel_inst = panel_inst; - - dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); - dc_dmub_srv_cmd_execute(dc->dmub_srv); - dc_dmub_srv_wait_idle(dc->dmub_srv); -} - /* * Setup PSR by programming phy registers and sending psr hw context values to firmware. */ @@ -329,16 +306,6 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub, copy_settings_data->fec_enable_delay_in100us = link->dc->debug.fec_enable_delay_in100us; copy_settings_data->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; copy_settings_data->panel_inst = panel_inst; - copy_settings_data->dsc_enable_status = (pipe_ctx->stream->timing.flags.DSC == 1); - - if (link->fec_state == dc_link_fec_enabled && - (!memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_1, - sizeof(link->dpcd_caps.sink_dev_id_str)) || - !memcmp(link->dpcd_caps.sink_dev_id_str, DP_SINK_DEVICE_STR_ID_2, - sizeof(link->dpcd_caps.sink_dev_id_str)))) - copy_settings_data->debug.bitfields.force_wakeup_by_tps3 = 1; - else - copy_settings_data->debug.bitfields.force_wakeup_by_tps3 = 0; dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); dc_dmub_srv_cmd_execute(dc->dmub_srv); @@ -389,7 +356,6 @@ static const struct dmub_psr_funcs psr_funcs = { .psr_set_level = dmub_psr_set_level, .psr_force_static = dmub_psr_force_static, .psr_get_residency = dmub_psr_get_residency, - .psr_set_power_opt = dmub_psr_set_power_opt, }; /* diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h index 01acc01cc1..9675c269e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h @@ -46,7 +46,6 @@ struct dmub_psr_funcs { void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst); void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency, uint8_t panel_inst); - void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst); }; struct dmub_psr *dmub_psr_create(struct dc_context *ctx); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index eb2755bdb3..62d595ded8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -46,7 +46,6 @@ #include "transform.h" #include "stream_encoder.h" #include "link_encoder.h" -#include "link_enc_cfg.h" #include "link_hwss.h" #include "dc_link_dp.h" #if defined(CONFIG_DRM_AMD_DC_DCN) @@ -58,8 +57,7 @@ #include "audio.h" #include "reg_helper.h" #include "panel_cntl.h" -#include "inc/link_dpcd.h" -#include "dpcd_defs.h" + /* include DCE11 register header files */ #include "dce/dce_11_0_d.h" #include "dce/dce_11_0_sh_mask.h" @@ -69,8 +67,6 @@ #include "dcn10/dcn10_hw_sequencer.h" -#include "dce110_hw_sequencer.h" - #define GAMMA_HW_POINTS_NUM 256 /* @@ -1112,23 +1108,11 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) clk_mgr->funcs->enable_pme_wa(clk_mgr); /* un-mute audio */ /* TODO: audio should be per stream rather than per link */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control( - pipe_ctx->stream_res.hpo_dp_stream_enc, false); - else - pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( - pipe_ctx->stream_res.stream_enc, false); -#else pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( - pipe_ctx->stream_res.stream_enc, false); -#endif + pipe_ctx->stream_res.stream_enc, false); if (pipe_ctx->stream_res.audio) pipe_ctx->stream_res.audio->enabled = true; } - - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM); } void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) @@ -1145,32 +1129,14 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false) return; -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control( - pipe_ctx->stream_res.hpo_dp_stream_enc, true); - else - pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( - pipe_ctx->stream_res.stream_enc, true); -#else pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control( pipe_ctx->stream_res.stream_enc, true); -#endif if (pipe_ctx->stream_res.audio) { pipe_ctx->stream_res.audio->enabled = false; if (dc_is_dp_signal(pipe_ctx->stream->signal)) -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable( - pipe_ctx->stream_res.hpo_dp_stream_enc); - else - pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( - pipe_ctx->stream_res.stream_enc); -#else pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable( pipe_ctx->stream_res.stream_enc); -#endif else pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable( pipe_ctx->stream_res.stream_enc); @@ -1185,9 +1151,6 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) * stream->stream_engine_id); */ } - - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM); } void dce110_disable_stream(struct pipe_ctx *pipe_ctx) @@ -1195,7 +1158,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; struct dc *dc = pipe_ctx->stream->ctx->dc; - struct link_encoder *link_enc = NULL; if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( @@ -1204,53 +1166,16 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) pipe_ctx->stream_res.stream_enc); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets( - pipe_ctx->stream_res.hpo_dp_stream_enc); - } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) -#else if (dc_is_dp_signal(pipe_ctx->stream->signal)) -#endif pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( pipe_ctx->stream_res.stream_enc); dc->hwss.disable_audio_stream(pipe_ctx); - /* Link encoder may have been dynamically assigned to non-physical display endpoint. */ - if (link->ep_type == DISPLAY_ENDPOINT_PHY) - link_enc = link->link_enc; - else if (dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_link(link->ctx->dc, link); - ASSERT(link_enc); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable( - pipe_ctx->stream_res.hpo_dp_stream_enc); - setup_dp_hpo_stream(pipe_ctx, false); - /* TODO - DP2.0 HW: unmap stream from link encoder here */ - } else { - if (link_enc) - link_enc->funcs->connect_dig_be_to_fe( - link_enc, - pipe_ctx->stream_res.stream_enc->id, - false); - } -#else - if (link_enc) - link_enc->funcs->connect_dig_be_to_fe( + link->link_enc->funcs->connect_dig_be_to_fe( link->link_enc, pipe_ctx->stream_res.stream_enc->id, false); -#endif - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (dc->hwseq->funcs.setup_hpo_hw_control && is_dp_128b_132b_signal(pipe_ctx)) - dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, false); -#endif } @@ -1267,7 +1192,7 @@ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; if (dc_is_dp_signal(pipe_ctx->stream->signal)) - pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { hws->funcs.edp_backlight_control(link, true); @@ -1285,16 +1210,8 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) link->dc->hwss.set_abm_immediate_disable(pipe_ctx); } -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) { - /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank( - pipe_ctx->stream_res.hpo_dp_stream_enc); - } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { -#else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { -#endif - pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); + pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { /* @@ -1519,7 +1436,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( struct dc *dc) { struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->link; struct drr_params params = {0}; unsigned int event_triggers = 0; struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; @@ -1535,23 +1451,10 @@ static enum dc_status apply_single_controller_ctx_to_hw( build_audio_output(context, pipe_ctx, &audio_output); if (dc_is_dp_signal(pipe_ctx->stream->signal)) -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup( - pipe_ctx->stream_res.hpo_dp_stream_enc, - pipe_ctx->stream_res.audio->inst, - &pipe_ctx->stream->audio_info); - else - pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( - pipe_ctx->stream_res.stream_enc, - pipe_ctx->stream_res.audio->inst, - &pipe_ctx->stream->audio_info); -#else pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup( pipe_ctx->stream_res.stream_enc, pipe_ctx->stream_res.audio->inst, &pipe_ctx->stream->audio_info); -#endif else pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup( pipe_ctx->stream_res.stream_enc, @@ -1566,22 +1469,10 @@ static enum dc_status apply_single_controller_ctx_to_hw( &pipe_ctx->stream->audio_info); } - /* make sure no pipes syncd to the pipe being enabled */ - if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic) - check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx); - -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* DCN3.1 FPGA Workaround - * Need to enable HPO DP Stream Encoder before setting OTG master enable. - * To do so, move calling function enable_stream_timing to only be done AFTER calling - * function core_link_enable_stream - */ - if (!(hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx))) -#endif - /* */ - /* Do not touch stream timing on seamless boot optimization. */ - if (!pipe_ctx->stream->apply_seamless_boot_optimization) - hws->funcs.enable_stream_timing(pipe_ctx, context, dc); + /* */ + /* Do not touch stream timing on seamless boot optimization. */ + if (!pipe_ctx->stream->apply_seamless_boot_optimization) + hws->funcs.enable_stream_timing(pipe_ctx, context, dc); if (hws->funcs.setup_vupdate_interrupt) hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); @@ -1608,9 +1499,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( pipe_ctx->stream_res.stream_enc, pipe_ctx->stream_res.tg->inst); - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); - pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( pipe_ctx->stream_res.opp, COLOR_SPACE_YCBCR601, @@ -1638,18 +1526,6 @@ static enum dc_status apply_single_controller_ctx_to_hw( if (!stream->dpms_off) core_link_enable_stream(context, pipe_ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* DCN3.1 FPGA Workaround - * Need to enable HPO DP Stream Encoder before setting OTG master enable. - * To do so, move calling function enable_stream_timing to only be done AFTER calling - * function core_link_enable_stream - */ - if (hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)) { - if (!pipe_ctx->stream->apply_seamless_boot_optimization) - hws->funcs.enable_stream_timing(pipe_ctx, context, dc); - } -#endif - pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; @@ -1663,17 +1539,27 @@ static void power_down_encoders(struct dc *dc) { int i; + /* do not know BIOS back-front mapping, simply blank all. It will not + * hurt for non-DP + */ + for (i = 0; i < dc->res_pool->stream_enc_count; i++) { + dc->res_pool->stream_enc[i]->funcs->dp_blank( + dc->res_pool->stream_enc[i]); + } + for (i = 0; i < dc->link_count; i++) { enum signal_type signal = dc->links[i]->connector_signal; - dc_link_blank_dp_stream(dc->links[i], false); + if ((signal == SIGNAL_TYPE_EDP) || + (signal == SIGNAL_TYPE_DISPLAY_PORT)) + if (!dc->links[i]->wa_flags.dp_keep_receiver_powered) + dp_receiver_power_ctrl(dc->links[i], false); if (signal != SIGNAL_TYPE_EDP) signal = SIGNAL_TYPE_NONE; - if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY) - dc->links[i]->link_enc->funcs->disable_output( - dc->links[i]->link_enc, signal); + dc->links[i]->link_enc->funcs->disable_output( + dc->links[i]->link_enc, signal); dc->links[i]->link_status.link_active = false; memset(&dc->links[i]->cur_link_settings, 0, @@ -1793,6 +1679,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) struct dc_stream_state *edp_streams[MAX_NUM_EDP]; struct dc_link *edp_link_with_sink = NULL; struct dc_link *edp_link = NULL; + struct dc_stream_state *edp_stream = NULL; struct dce_hwseq *hws = dc->hwseq; int edp_with_sink_num; int edp_num; @@ -1813,50 +1700,28 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) get_edp_streams(context, edp_streams, &edp_stream_num); // Check fastboot support, disable on DCE8 because of blank screens - if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 && + if (edp_num && dc->ctx->dce_version != DCE_VERSION_8_0 && dc->ctx->dce_version != DCE_VERSION_8_1 && dc->ctx->dce_version != DCE_VERSION_8_3) { for (i = 0; i < edp_num; i++) { edp_link = edp_links[i]; - if (edp_link != edp_streams[0]->link) - continue; // enable fastboot if backend is enabled on eDP - if (edp_link->link_enc->funcs->is_dig_enabled && - edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && - edp_link->link_status.link_active) { - struct dc_stream_state *edp_stream = edp_streams[0]; + if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) { + /* Set optimization flag on eDP stream*/ + if (edp_stream_num && edp_link->link_status.link_active) { + edp_stream = edp_streams[0]; + can_apply_edp_fast_boot = !is_edp_ilr_optimization_required(edp_stream->link, &edp_stream->timing); + edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot; + if (can_apply_edp_fast_boot) + DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n"); - can_apply_edp_fast_boot = !is_edp_ilr_optimization_required(edp_stream->link, &edp_stream->timing); - edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot; - if (can_apply_edp_fast_boot) - DC_LOG_EVENT_LINK_TRAINING("eDP fast boot disabled to optimize link rate\n"); - - break; + break; + } } } - - /* - * TO-DO: So far the code logic below only addresses single eDP case. - * For dual eDP case, there are a few things that need to be - * implemented first: - * - * 1. Change the fastboot logic above, so eDP link[0 or 1]'s - * stream[0 or 1] will all be checked. - * - * 2. Change keep_edp_vdd_on to an array, and maintain keep_edp_vdd_on - * for each eDP. - * - * Once above 2 things are completed, we can then change the logic below - * correspondingly, so dual eDP case will be fully covered. - */ - - // We are trying to enable eDP, don't power down VDD if eDP stream is existing - if ((edp_stream_num == 1 && edp_streams[0] != NULL) || can_apply_edp_fast_boot) { + // We are trying to enable eDP, don't power down VDD + if (edp_stream_num) keep_edp_vdd_on = true; - DC_LOG_EVENT_LINK_TRAINING("Keep eDP Vdd on\n"); - } else { - DC_LOG_EVENT_LINK_TRAINING("No eDP stream enabled, turn eDP Vdd off\n"); - } } // Check seamless boot support @@ -2316,10 +2181,6 @@ enum dc_status dce110_apply_ctx_to_hw( enum dc_status status; int i; - /* reset syncd pipes from disabled pipes */ - if (dc->config.use_pipe_ctx_sync_logic) - reset_syncd_pipes_from_disabled_pipes(dc, context); - /* Reset old context */ /* look up the targets that have been removed since last commit */ hws->funcs.reset_hw_ctx_wrap(dc, context); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index db7ca4b0cd..91fdfcd8a1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -119,6 +119,14 @@ void dpp_read_state(struct dpp *dpp_base, } } +/* Program gamut remap in bypass mode */ +void dpp_set_gamut_remap_bypass(struct dcn10_dpp *dpp) +{ + REG_SET(CM_GAMUT_REMAP_CONTROL, 0, + CM_GAMUT_REMAP_MODE, 0); + /* Gamut remap in bypass */ +} + #define IDENTITY_RATIO(ratio) (dc_fixpt_u2d19(ratio) == (1 << 19)) bool dpp1_get_optimal_number_of_taps( diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index f607a0e28f..cb9767ddf9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -39,10 +39,6 @@ #define BLACK_OFFSET_RGB_Y 0x0 #define BLACK_OFFSET_CBCR 0x8000 -#define VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT 3 -#define VISUAL_CONFIRM_RECT_HEIGHT_MIN 1 -#define VISUAL_CONFIRM_RECT_HEIGHT_MAX 10 - #define REG(reg)\ dpp->tf_regs->reg @@ -89,6 +85,51 @@ enum dscl_mode_sel { DSCL_MODE_DSCL_BYPASS = 6 }; +static void dpp1_dscl_set_overscan( + struct dcn10_dpp *dpp, + const struct scaler_data *data) +{ + uint32_t left = data->recout.x; + uint32_t top = data->recout.y; + + int right = data->h_active - data->recout.x - data->recout.width; + int bottom = data->v_active - data->recout.y - data->recout.height; + + if (right < 0) { + BREAK_TO_DEBUGGER(); + right = 0; + } + if (bottom < 0) { + BREAK_TO_DEBUGGER(); + bottom = 0; + } + + REG_SET_2(DSCL_EXT_OVERSCAN_LEFT_RIGHT, 0, + EXT_OVERSCAN_LEFT, left, + EXT_OVERSCAN_RIGHT, right); + + REG_SET_2(DSCL_EXT_OVERSCAN_TOP_BOTTOM, 0, + EXT_OVERSCAN_BOTTOM, bottom, + EXT_OVERSCAN_TOP, top); +} + +static void dpp1_dscl_set_otg_blank( + struct dcn10_dpp *dpp, const struct scaler_data *data) +{ + uint32_t h_blank_start = data->h_active; + uint32_t h_blank_end = 0; + uint32_t v_blank_start = data->v_active; + uint32_t v_blank_end = 0; + + REG_SET_2(OTG_H_BLANK, 0, + OTG_H_BLANK_START, h_blank_start, + OTG_H_BLANK_END, h_blank_end); + + REG_SET_2(OTG_V_BLANK, 0, + OTG_V_BLANK_START, v_blank_start, + OTG_V_BLANK_END, v_blank_end); +} + static int dpp1_dscl_get_pixel_depth_val(enum lb_pixel_depth depth) { if (depth == LB_PIXEL_DEPTH_30BPP) @@ -164,17 +205,9 @@ static void dpp1_power_on_dscl( struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); if (dpp->tf_regs->DSCL_MEM_PWR_CTRL) { - if (power_on) { - REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 0); + REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, power_on ? 0 : 3); + if (power_on) REG_WAIT(DSCL_MEM_PWR_STATUS, LUT_MEM_PWR_STATE, 0, 1, 5); - } else { - if (dpp->base.ctx->dc->debug.enable_mem_low_power.bits.dscl) { - dpp->base.ctx->dc->optimized_required = true; - dpp->base.deferred_reg_writes.bits.disable_dscl = true; - } else { - REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); - } - } } } @@ -510,6 +543,58 @@ static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *d return LB_MEMORY_CONFIG_0; } +void dpp1_dscl_set_scaler_auto_scale( + struct dpp *dpp_base, + const struct scaler_data *scl_data) +{ + enum lb_memory_config lb_config; + struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); + enum dscl_mode_sel dscl_mode = dpp1_dscl_get_dscl_mode( + dpp_base, scl_data, dpp_base->ctx->dc->debug.always_scale); + bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN + && scl_data->format <= PIXEL_FORMAT_VIDEO_END; + + dpp1_dscl_set_overscan(dpp, scl_data); + + dpp1_dscl_set_otg_blank(dpp, scl_data); + + REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); + + if (dscl_mode == DSCL_MODE_DSCL_BYPASS) + return; + + lb_config = dpp1_dscl_find_lb_memory_config(dpp, scl_data); + dpp1_dscl_set_lb(dpp, &scl_data->lb_params, lb_config); + + if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) + return; + + /* TODO: v_min */ + REG_SET_3(DSCL_AUTOCAL, 0, + AUTOCAL_MODE, AUTOCAL_MODE_AUTOSCALE, + AUTOCAL_NUM_PIPE, 0, + AUTOCAL_PIPE_ID, 0); + + /* Black offsets */ + if (ycbcr) + REG_SET_2(SCL_BLACK_OFFSET, 0, + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); + else + + REG_SET_2(SCL_BLACK_OFFSET, 0, + SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, + SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); + + REG_SET_4(SCL_TAP_CONTROL, 0, + SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, + SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, + SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, + SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); + + dpp1_dscl_set_scl_filter(dpp, scl_data, ycbcr); +} + static void dpp1_dscl_set_manual_ratio_init( struct dcn10_dpp *dpp, const struct scaler_data *data) @@ -592,17 +677,9 @@ static void dpp1_dscl_set_recout(struct dcn10_dpp *dpp, const struct rect *recout) { int visual_confirm_on = 0; - unsigned short visual_confirm_rect_height = VISUAL_CONFIRM_RECT_HEIGHT_DEFAULT; - if (dpp->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) visual_confirm_on = 1; - /* Check bounds to ensure the VC bar height was set to a sane value */ - if ((dpp->base.ctx->dc->debug.visual_confirm_rect_height >= VISUAL_CONFIRM_RECT_HEIGHT_MIN) && - (dpp->base.ctx->dc->debug.visual_confirm_rect_height <= VISUAL_CONFIRM_RECT_HEIGHT_MAX)) { - visual_confirm_rect_height = dpp->base.ctx->dc->debug.visual_confirm_rect_height; - } - REG_SET_2(RECOUT_START, 0, /* First pixel of RECOUT in the active OTG area */ RECOUT_START_X, recout->x, @@ -614,7 +691,7 @@ static void dpp1_dscl_set_recout(struct dcn10_dpp *dpp, RECOUT_WIDTH, recout->width, /* Number of RECOUT vertical lines */ RECOUT_HEIGHT, recout->height - - visual_confirm_on * 2 * (dpp->base.inst + visual_confirm_rect_height)); + - visual_confirm_on * 2 * (dpp->base.inst + 1)); } /** diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 530a72e3ee..3af49cdf89 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -77,9 +77,9 @@ #define PGFSM_POWER_ON 0 #define PGFSM_POWER_OFF 2 -static void print_microsec(struct dc_context *dc_ctx, - struct dc_log_buffer_ctx *log_ctx, - uint32_t ref_cycle) +void print_microsec(struct dc_context *dc_ctx, + struct dc_log_buffer_ctx *log_ctx, + uint32_t ref_cycle) { const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000; static const unsigned int frac = 1000; @@ -132,8 +132,7 @@ static void log_mpc_crc(struct dc *dc, REG_READ(DPP_TOP0_DPP_CRC_VAL_B_A), REG_READ(DPP_TOP0_DPP_CRC_VAL_R_G)); } -static void dcn10_log_hubbub_state(struct dc *dc, - struct dc_log_buffer_ctx *log_ctx) +void dcn10_log_hubbub_state(struct dc *dc, struct dc_log_buffer_ctx *log_ctx) { struct dc_context *dc_ctx = dc->ctx; struct dcn_hubbub_wm wm; @@ -232,7 +231,7 @@ static void dcn10_log_hubp_states(struct dc *dc, void *log_ctx) if (!s->blank_en) DTN_INFO("[%2d]: %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh" - " %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh" + "% 8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh" " %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh %8xh\n", pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start, dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler, @@ -467,65 +466,6 @@ void dcn10_log_hw_state(struct dc *dc, log_mpc_crc(dc, log_ctx); - { - if (pool->hpo_dp_stream_enc_count > 0) { - DTN_INFO("DP HPO S_ENC: Enabled OTG Format Depth Vid SDP Compressed Link\n"); - for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) { - struct hpo_dp_stream_encoder_state hpo_dp_se_state = {0}; - struct hpo_dp_stream_encoder *hpo_dp_stream_enc = pool->hpo_dp_stream_enc[i]; - - if (hpo_dp_stream_enc && hpo_dp_stream_enc->funcs->read_state) { - hpo_dp_stream_enc->funcs->read_state(hpo_dp_stream_enc, &hpo_dp_se_state); - - DTN_INFO("[%d]: %d %d %6s %d %d %d %d %d\n", - hpo_dp_stream_enc->id - ENGINE_ID_HPO_DP_0, - hpo_dp_se_state.stream_enc_enabled, - hpo_dp_se_state.otg_inst, - (hpo_dp_se_state.pixel_encoding == 0) ? "4:4:4" : - ((hpo_dp_se_state.pixel_encoding == 1) ? "4:2:2" : - (hpo_dp_se_state.pixel_encoding == 2) ? "4:2:0" : "Y-Only"), - (hpo_dp_se_state.component_depth == 0) ? 6 : - ((hpo_dp_se_state.component_depth == 1) ? 8 : - (hpo_dp_se_state.component_depth == 2) ? 10 : 12), - hpo_dp_se_state.vid_stream_enabled, - hpo_dp_se_state.sdp_enabled, - hpo_dp_se_state.compressed_format, - hpo_dp_se_state.mapped_to_link_enc); - } - } - - DTN_INFO("\n"); - } - - /* log DP HPO L_ENC section if any hpo_dp_link_enc exists */ - if (pool->hpo_dp_link_enc_count) { - DTN_INFO("DP HPO L_ENC: Enabled Mode Lanes Stream Slots VC Rate X VC Rate Y\n"); - - for (i = 0; i < pool->hpo_dp_link_enc_count; i++) { - struct hpo_dp_link_encoder *hpo_dp_link_enc = pool->hpo_dp_link_enc[i]; - struct hpo_dp_link_enc_state hpo_dp_le_state = {0}; - - if (hpo_dp_link_enc->funcs->read_state) { - hpo_dp_link_enc->funcs->read_state(hpo_dp_link_enc, &hpo_dp_le_state); - DTN_INFO("[%d]: %d %6s %d %d %d %d %d\n", - hpo_dp_link_enc->inst, - hpo_dp_le_state.link_enc_enabled, - (hpo_dp_le_state.link_mode == 0) ? "TPS1" : - (hpo_dp_le_state.link_mode == 1) ? "TPS2" : - (hpo_dp_le_state.link_mode == 2) ? "ACTIVE" : "TEST", - hpo_dp_le_state.lane_count, - hpo_dp_le_state.stream_src[0], - hpo_dp_le_state.slot_count[0], - hpo_dp_le_state.vc_rate_x[0], - hpo_dp_le_state.vc_rate_y[0]); - DTN_INFO("\n"); - } - } - - DTN_INFO("\n"); - } - } - DTN_INFO_END(); } @@ -1357,53 +1297,11 @@ void dcn10_init_pipes(struct dc *dc, struct dc_state *context) tg->funcs->tg_init(tg); } - - /* Power gate DSCs */ - if (hws->funcs.dsc_pg_control != NULL) { - uint32_t num_opps = 0; - uint32_t opp_id_src0 = OPP_ID_INVALID; - uint32_t opp_id_src1 = OPP_ID_INVALID; - - // Step 1: To find out which OPTC is running & OPTC DSC is ON - // We can't use res_pool->res_cap->num_timing_generator to check - // Because it records display pipes default setting built in driver, - // not display pipes of the current chip. - // Some ASICs would be fused display pipes less than the default setting. - // In dcnxx_resource_construct function, driver would obatin real information. - for (i = 0; i < dc->res_pool->timing_generator_count; i++) { - uint32_t optc_dsc_state = 0; - struct timing_generator *tg = dc->res_pool->timing_generators[i]; - - if (tg->funcs->is_tg_enabled(tg)) { - if (tg->funcs->get_dsc_status) - tg->funcs->get_dsc_status(tg, &optc_dsc_state); - // Only one OPTC with DSC is ON, so if we got one result, we would exit this block. - // non-zero value is DSC enabled - if (optc_dsc_state != 0) { - tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1); - break; - } - } - } - - // Step 2: To power down DSC but skip DSC of running OPTC - for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) { - struct dcn_dsc_state s = {0}; - - dc->res_pool->dscs[i]->funcs->dsc_read_state(dc->res_pool->dscs[i], &s); - - if ((s.dsc_opp_source == opp_id_src0 || s.dsc_opp_source == opp_id_src1) && - s.dsc_clock_en && s.dsc_fw_en) - continue; - - hws->funcs.dsc_pg_control(hws, dc->res_pool->dscs[i]->inst, false); - } - } } void dcn10_init_hw(struct dc *dc) { - int i; + int i, j; struct abm *abm = dc->res_pool->abm; struct dmcu *dmcu = dc->res_pool->dmcu; struct dce_hwseq *hws = dc->hwseq; @@ -1415,12 +1313,6 @@ void dcn10_init_hw(struct dc *dc) if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); - /* Align bw context with hw config when system resume. */ - if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) { - dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz; - dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz; - } - // Initialize the dccg if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->dccg_init) dc->res_pool->dccg->funcs->dccg_init(res_pool->dccg); @@ -1505,8 +1397,43 @@ void dcn10_init_hw(struct dc *dc) dmub_enable_outbox_notification(dc); /* we want to turn off all dp displays before doing detection */ - if (dc->config.power_down_display_on_boot) - dc_link_blank_all_dp_displays(dc); + if (dc->config.power_down_display_on_boot) { + uint8_t dpcd_power_state = '\0'; + enum dc_status status = DC_ERROR_UNEXPECTED; + + for (i = 0; i < dc->link_count; i++) { + if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) + continue; + + /* DP 2.0 requires that LTTPR Caps be read first */ + dp_retrieve_lttpr_cap(dc->links[i]); + + /* + * If any of the displays are lit up turn them off. + * The reason is that some MST hubs cannot be turned off + * completely until we tell them to do so. + * If not turned off, then displays connected to MST hub + * won't light up. + */ + status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, + &dpcd_power_state, sizeof(dpcd_power_state)); + if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) { + /* blank dp stream before power off receiver*/ + if (dc->links[i]->link_enc->funcs->get_dig_frontend) { + unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(dc->links[i]->link_enc); + + for (j = 0; j < dc->res_pool->stream_enc_count; j++) { + if (fe == dc->res_pool->stream_enc[j]->id) { + dc->res_pool->stream_enc[j]->funcs->dp_blank( + dc->res_pool->stream_enc[j]); + break; + } + } + } + dp_receiver_power_ctrl(dc->links[i], false); + } + } + } /* If taking control over from VBIOS, we may want to optimize our first * mode set, so we need to skip powering down pipes until we know which @@ -1639,7 +1566,7 @@ void dcn10_reset_hw_ctx_wrap( dcn10_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); if (hws->funcs.enable_stream_gating) - hws->funcs.enable_stream_gating(dc, pipe_ctx_old); + hws->funcs.enable_stream_gating(dc, pipe_ctx); if (old_clk) old_clk->funcs->cs_power_down(old_clk); } @@ -1972,9 +1899,10 @@ static bool wait_for_reset_trigger_to_occur( return rc; } -static uint64_t reduceSizeAndFraction(uint64_t *numerator, - uint64_t *denominator, - bool checkUint32Bounary) +uint64_t reduceSizeAndFraction( + uint64_t *numerator, + uint64_t *denominator, + bool checkUint32Bounary) { int i; bool ret = checkUint32Bounary == false; @@ -2022,7 +1950,7 @@ static uint64_t reduceSizeAndFraction(uint64_t *numerator, return ret; } -static bool is_low_refresh_rate(struct pipe_ctx *pipe) +bool is_low_refresh_rate(struct pipe_ctx *pipe) { uint32_t master_pipe_refresh_rate = pipe->stream->timing.pix_clk_100hz * 100 / @@ -2031,8 +1959,7 @@ static bool is_low_refresh_rate(struct pipe_ctx *pipe) return master_pipe_refresh_rate <= 30; } -static uint8_t get_clock_divider(struct pipe_ctx *pipe, - bool account_low_refresh_rate) +uint8_t get_clock_divider(struct pipe_ctx *pipe, bool account_low_refresh_rate) { uint32_t clock_divider = 1; uint32_t numpipes = 1; @@ -2052,8 +1979,10 @@ static uint8_t get_clock_divider(struct pipe_ctx *pipe, return clock_divider; } -static int dcn10_align_pixel_clocks(struct dc *dc, int group_size, - struct pipe_ctx *grouped_pipes[]) +int dcn10_align_pixel_clocks( + struct dc *dc, + int group_size, + struct pipe_ctx *grouped_pipes[]) { struct dc_context *dc_ctx = dc->ctx; int i, master = -1, embedded = -1; @@ -2342,11 +2271,11 @@ static void mmhub_read_vm_context0_settings(struct dcn10_hubp *hubp1, } -static void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp) +void dcn10_program_pte_vm(struct dce_hwseq *hws, struct hubp *hubp) { struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); - struct vm_system_aperture_param apt = {0}; - struct vm_context0_param vm0 = {0}; + struct vm_system_aperture_param apt = { {{ 0 } } }; + struct vm_context0_param vm0 = { { { 0 } } }; mmhub_read_vm_system_aperture_settings(hubp1, &apt, hws); mmhub_read_vm_context0_settings(hubp1, &vm0, hws); @@ -2519,7 +2448,7 @@ void dcn10_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, void dcn10_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) { struct hubp *hubp = pipe_ctx->plane_res.hubp; - struct mpcc_blnd_cfg blnd_cfg = {0}; + struct mpcc_blnd_cfg blnd_cfg = {{0}}; bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe; int mpcc_id; struct mpcc *new_mpcc; @@ -2624,7 +2553,7 @@ static void dcn10_update_dchubp_dpp( /* new calculated dispclk, dppclk are stored in * context->bw_ctx.bw.dcn.clk.dispclk_khz / dppclk_khz. current * dispclk, dppclk are from dc->clk_mgr->clks.dispclk_khz. - * dcn10_validate_bandwidth compute new dispclk, dppclk. + * dcn_validate_bandwidth compute new dispclk, dppclk. * dispclk will put in use after optimize_bandwidth when * ramp_up_dispclk_with_dpp is called. * there are two places for dppclk be put in use. One location @@ -2638,7 +2567,7 @@ static void dcn10_update_dchubp_dpp( * for example, eDP + external dp, change resolution of DP from * 1920x1080x144hz to 1280x960x60hz. * before change: dispclk = 337889 dppclk = 337889 - * change mode, dcn10_validate_bandwidth calculate + * change mode, dcn_validate_bandwidth calculate * dispclk = 143122 dppclk = 143122 * update_dchubp_dpp be executed before dispclk be updated, * dispclk = 337889, but dppclk use new value dispclk /2 = @@ -3247,11 +3176,13 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data) static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) { - struct pipe_ctx *test_pipe, *split_pipe; + struct pipe_ctx *test_pipe; const struct scaler_data *scl_data = &pipe_ctx->plane_res.scl_data; - struct rect r1 = scl_data->recout, r2, r2_half; - int r1_r = r1.x + r1.width, r1_b = r1.y + r1.height, r2_r, r2_b; + const struct rect *r1 = &scl_data->recout, *r2; + int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b; int cur_layer = pipe_ctx->plane_state->layer_index; + bool upper_pipe_exists = false; + struct fixed31_32 one = dc_fixpt_from_int(1); /** * Disable the cursor if there's another pipe above this with a @@ -3260,33 +3191,26 @@ static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx) */ for (test_pipe = pipe_ctx->top_pipe; test_pipe; test_pipe = test_pipe->top_pipe) { - // Skip invisible layer and pipe-split plane on same layer - if (!test_pipe->plane_state->visible || test_pipe->plane_state->layer_index == cur_layer) + if (!test_pipe->plane_state->visible) continue; - r2 = test_pipe->plane_res.scl_data.recout; - r2_r = r2.x + r2.width; - r2_b = r2.y + r2.height; - split_pipe = test_pipe; + r2 = &test_pipe->plane_res.scl_data.recout; + r2_r = r2->x + r2->width; + r2_b = r2->y + r2->height; - /** - * There is another half plane on same layer because of - * pipe-split, merge together per same height. - */ - for (split_pipe = pipe_ctx->top_pipe; split_pipe; - split_pipe = split_pipe->top_pipe) - if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) { - r2_half = split_pipe->plane_res.scl_data.recout; - r2.x = (r2_half.x < r2.x) ? r2_half.x : r2.x; - r2.width = r2.width + r2_half.width; - r2_r = r2.x + r2.width; - break; - } - - if (r1.x >= r2.x && r1.y >= r2.y && r1_r <= r2_r && r1_b <= r2_b) + if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b) return true; + + if (test_pipe->plane_state->layer_index < cur_layer) + upper_pipe_exists = true; } + // if plane scaled, assume an upper plane can handle cursor if it exists. + if (upper_pipe_exists && + (scl_data->ratios.horz.value != one.value || + scl_data->ratios.vert.value != one.value)) + return true; + return false; } @@ -3676,7 +3600,7 @@ void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx) void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings) { - struct encoder_unblank_param params = {0}; + struct encoder_unblank_param params = { { 0 } }; struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; struct dce_hwseq *hws = link->dc->hwseq; @@ -3689,7 +3613,7 @@ void dcn10_unblank_stream(struct pipe_ctx *pipe_ctx, if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (params.timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) params.timing.pix_clk_100hz /= 2; - pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); } if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h index e2508d637e..f0e0d07b03 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.h @@ -60,18 +60,14 @@ SRI(CURSOR_HOT_SPOT, CURSOR0_, id), \ SRI(CURSOR_DST_OFFSET, CURSOR0_, id) -#define IPP_REG_LIST_DCN201(id) \ - IPP_REG_LIST_DCN(id), \ - SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR0_, id), \ - SRI(CURSOR_SURFACE_ADDRESS, CURSOR0_, id), \ - SRI(CURSOR_SIZE, CURSOR0_, id), \ - SRI(CURSOR_CONTROL, CURSOR0_, id), \ - SRI(CURSOR_POSITION, CURSOR0_, id), \ - SRI(CURSOR_HOT_SPOT, CURSOR0_, id), \ - SRI(CURSOR_DST_OFFSET, CURSOR0_, id) - #define CURSOR0_CURSOR_CONTROL__CURSOR_2X_MAGNIFY__SHIFT 0x4 #define CURSOR0_CURSOR_CONTROL__CURSOR_2X_MAGNIFY_MASK 0x00000010L +#define CURSOR1_CURSOR_CONTROL__CURSOR_2X_MAGNIFY__SHIFT 0x4 +#define CURSOR1_CURSOR_CONTROL__CURSOR_2X_MAGNIFY_MASK 0x00000010L +#define CURSOR2_CURSOR_CONTROL__CURSOR_2X_MAGNIFY__SHIFT 0x4 +#define CURSOR2_CURSOR_CONTROL__CURSOR_2X_MAGNIFY_MASK 0x00000010L +#define CURSOR3_CURSOR_CONTROL__CURSOR_2X_MAGNIFY__SHIFT 0x4 +#define CURSOR3_CURSOR_CONTROL__CURSOR_2X_MAGNIFY_MASK 0x00000010L #define IPP_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -126,23 +122,6 @@ IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ IPP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh) -#define IPP_MASK_SH_LIST_DCN201(mask_sh) \ - IPP_MASK_SH_LIST_DCN(mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \ - IPP_SF(CURSOR0_0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh) - #define IPP_DCN10_REG_FIELD_LIST(type) \ type CNVC_SURFACE_PIXEL_FORMAT; \ type CNVC_BYPASS; \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index f4b34c110e..e4701825b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -646,9 +646,8 @@ static bool dcn10_link_encoder_validate_hdmi_output( crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) return false; - if ((!enc10->base.features.flags.bits.HDMI_6GB_EN || - enc10->base.ctx->dc->debug.hdmi20_disable) && - adjusted_pix_clk_100hz >= 3000000) + if (!enc10->base.features.flags.bits.HDMI_6GB_EN && + adjusted_pix_clk_100hz >= 3000000) return false; if (enc10->base.ctx->dc->debug.hdmi20_disable && crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) @@ -1461,14 +1460,5 @@ void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc, if (enc->features.flags.bits.IS_HBR3_CAPABLE) max_link_cap.link_rate = LINK_RATE_HIGH3; - if (enc->features.flags.bits.IS_UHBR10_CAPABLE) - max_link_cap.link_rate = LINK_RATE_UHBR10; - - if (enc->features.flags.bits.IS_UHBR13_5_CAPABLE) - max_link_cap.link_rate = LINK_RATE_UHBR13_5; - - if (enc->features.flags.bits.IS_UHBR20_CAPABLE) - max_link_cap.link_rate = LINK_RATE_UHBR20; - *link_settings = max_link_cap; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c index 2c409356f5..d54d731415 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c @@ -348,6 +348,36 @@ void opp1_program_stereo( */ } +void opp1_program_oppbuf( + struct output_pixel_processor *opp, + struct oppbuf_params *oppbuf) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + /* Program the oppbuf active width to be the frame width from mpc */ + REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, oppbuf->active_width); + + /* Specifies the number of segments in multi-segment mode (DP-MSO operation) + * description "In 1/2/4 segment mode, specifies the horizontal active width in pixels of the display panel. + * In 4 segment split left/right mode, specifies the horizontal 1/2 active width in pixels of the display panel. + * Used to determine segment boundaries in multi-segment mode. Used to determine the width of the vertical active space in 3D frame packed modes. + * OPPBUF_ACTIVE_WIDTH must be integer divisible by the total number of segments." + */ + REG_UPDATE(OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, oppbuf->mso_segmentation); + + /* description "Specifies the number of overlap pixels (1-8 overlapping pixels supported), used in multi-segment mode (DP-MSO operation)" */ + REG_UPDATE(OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, oppbuf->mso_overlap_pixel_num); + + /* description "Specifies the number of times a pixel is replicated (0-15 pixel replications supported). + * A value of 0 disables replication. The total number of times a pixel is output is OPPBUF_PIXEL_REPETITION + 1." + */ + REG_UPDATE(OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, oppbuf->pixel_repetition); + + /* Controls the number of padded pixels at the end of a segment */ + if (REG(OPPBUF_CONTROL1)) + REG_UPDATE(OPPBUF_CONTROL1, OPPBUF_NUM_SEGMENT_PADDED_PIXELS, oppbuf->num_segment_padded_pixels); +} + void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable) { struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index b1671b00ce..37848f4577 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -131,6 +131,22 @@ void optc1_setup_vertical_interrupt2( OTG_VERTICAL_INTERRUPT2_LINE_START, start_line); } +/** + * Vupdate keepout can be set to a window to block the update lock for that pipe from changing. + * Start offset begins with vstartup and goes for x number of clocks, + * end offset starts from end of vupdate to x number of clocks. + */ +void optc1_set_vupdate_keepout(struct timing_generator *optc, + struct vupdate_keepout_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, params->start_offset, + MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, params->end_offset, + OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, params->enable); +} + /** * program_timing_generator used by mode timing set * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. @@ -288,7 +304,7 @@ void optc1_program_timing( if (optc1_is_two_pixels_per_containter(&patched_crtc_timing) || optc1->opp_count == 2) h_div = H_TIMING_DIV_BY2; - if (REG(OPTC_DATA_FORMAT_CONTROL) && optc1->tg_mask->OPTC_DATA_FORMAT != 0) { + if (REG(OPTC_DATA_FORMAT_CONTROL)) { uint32_t data_fmt = 0; if (patched_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) @@ -860,7 +876,7 @@ void optc1_set_static_screen_control( OTG_STATIC_SCREEN_FRAME_COUNT, num_frames); } -static void optc1_setup_manual_trigger(struct timing_generator *optc) +void optc1_setup_manual_trigger(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -878,7 +894,7 @@ static void optc1_setup_manual_trigger(struct timing_generator *optc) OTG_TRIGA_CLEAR, 1); } -static void optc1_program_manual_trigger(struct timing_generator *optc) +void optc1_program_manual_trigger(struct timing_generator *optc) { struct optc *optc1 = DCN10TG_FROM_TG(optc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 858b721498..7daadb6a52 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -686,8 +686,9 @@ static struct output_pixel_processor *dcn10_opp_create( return &opp->base; } -static struct dce_aux *dcn10_aux_engine_create(struct dc_context *ctx, - uint32_t inst) +struct dce_aux *dcn10_aux_engine_create( + struct dc_context *ctx, + uint32_t inst) { struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); @@ -723,8 +724,9 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCE110(_MASK) }; -static struct dce_i2c_hw *dcn10_i2c_hw_create(struct dc_context *ctx, - uint32_t inst) +struct dce_i2c_hw *dcn10_i2c_hw_create( + struct dc_context *ctx, + uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); @@ -803,7 +805,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS4_CAPABLE = true }; -static struct link_encoder *dcn10_link_encoder_create( +struct link_encoder *dcn10_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn10_link_encoder *enc10 = @@ -845,7 +847,7 @@ static struct panel_cntl *dcn10_panel_cntl_create(const struct panel_cntl_init_d return &panel_cntl->base; } -static struct clock_source *dcn10_clock_source_create( +struct clock_source *dcn10_clock_source_create( struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, @@ -943,7 +945,7 @@ static const struct resource_create_funcs res_create_maximus_funcs = { .create_hwseq = dcn10_hwseq_create, }; -static void dcn10_clock_source_destroy(struct clock_source **clk_src) +void dcn10_clock_source_destroy(struct clock_source **clk_src) { kfree(TO_DCE110_CLK_SRC(*clk_src)); *clk_src = NULL; @@ -976,8 +978,10 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool) pool->base.mpc = NULL; } - kfree(pool->base.hubbub); - pool->base.hubbub = NULL; + if (pool->base.hubbub != NULL) { + kfree(pool->base.hubbub); + pool->base.hubbub = NULL; + } for (i = 0; i < pool->base.pipe_count; i++) { if (pool->base.opps[i] != NULL) @@ -1007,10 +1011,14 @@ static void dcn10_resource_destruct(struct dcn10_resource_pool *pool) for (i = 0; i < pool->base.res_cap->num_ddc; i++) { if (pool->base.engines[i] != NULL) dce110_engine_destroy(&pool->base.engines[i]); - kfree(pool->base.hw_i2cs[i]); - pool->base.hw_i2cs[i] = NULL; - kfree(pool->base.sw_i2cs[i]); - pool->base.sw_i2cs[i] = NULL; + if (pool->base.hw_i2cs[i] != NULL) { + kfree(pool->base.hw_i2cs[i]); + pool->base.hw_i2cs[i] = NULL; + } + if (pool->base.sw_i2cs[i] != NULL) { + kfree(pool->base.sw_i2cs[i]); + pool->base.sw_i2cs[i] = NULL; + } } for (i = 0; i < pool->base.audio_count; i++) { @@ -1120,7 +1128,7 @@ static enum dc_status build_mapped_resource( return DC_OK; } -static enum dc_status dcn10_add_stream_to_ctx( +enum dc_status dcn10_add_stream_to_ctx( struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream) @@ -1288,7 +1296,7 @@ struct stream_encoder *dcn10_find_first_free_match_stream_enc_for_link( * in daisy chain use case */ j = i; - if (link->ep_type == DISPLAY_ENDPOINT_PHY && pool->stream_enc[i]->id == + if (pool->stream_enc[i]->id == link->link_enc->preferred_engine) return pool->stream_enc[i]; } @@ -1312,7 +1320,7 @@ static const struct resource_funcs dcn10_res_pool_funcs = { .destroy = dcn10_destroy_resource_pool, .link_enc_create = dcn10_link_encoder_create, .panel_cntl_create = dcn10_panel_cntl_create, - .validate_bandwidth = dcn10_validate_bandwidth, + .validate_bandwidth = dcn_validate_bandwidth, .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer, .validate_plane = dcn10_validate_plane, .validate_global = dcn10_validate_global, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c index b0c08ee6bc..cf364ae931 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c @@ -29,9 +29,6 @@ #include "dcn10_stream_encoder.h" #include "reg_helper.h" #include "hw_shared.h" -#include "inc/link_dpcd.h" -#include "dpcd_defs.h" -#include "dcn30/dcn30_afmt.h" #define DC_LOGGER \ enc1->base.ctx->logger @@ -647,12 +644,6 @@ void enc1_stream_encoder_set_throttled_vcp_size( x), 26)); - // If y rounds up to integer, carry it over to x. - if (y >> 26) { - x += 1; - y = 0; - } - REG_SET_2(DP_MSE_RATE_CNTL, 0, DP_MSE_RATE_X, x, DP_MSE_RATE_Y, y); @@ -735,16 +726,6 @@ void enc1_stream_encoder_update_dp_info_packets( 0, /* packetIndex */ &info_frame->vsc); - /* VSC SDP at packetIndex 1 is used by PSR in DMCUB FW. - * Note that the enablement of GSP1 is not done below, - * it's done in FW. - */ - if (info_frame->vsc.valid) - enc1_update_generic_info_packet( - enc1, - 1, /* packetIndex */ - &info_frame->vsc); - if (info_frame->spd.valid) enc1_update_generic_info_packet( enc1, @@ -903,7 +884,6 @@ void enc1_stream_encoder_stop_dp_info_packets( } void enc1_stream_encoder_dp_blank( - struct dc_link *link, struct stream_encoder *enc) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -934,8 +914,6 @@ void enc1_stream_encoder_dp_blank( /* disable DP stream */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM); - /* the encoder stops sending the video stream * at the start of the vertical blanking. * Poll for DP_VID_STREAM_STATUS == 0 @@ -952,13 +930,10 @@ void enc1_stream_encoder_dp_blank( */ REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true); - - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET); } /* output video stream to link encoder */ void enc1_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param) { @@ -1025,8 +1000,6 @@ void enc1_stream_encoder_dp_unblank( */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); - - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } void enc1_stream_encoder_set_avmute( @@ -1471,10 +1444,6 @@ void enc1_se_hdmi_audio_setup( void enc1_se_hdmi_audio_disable( struct stream_encoder *enc) { -#if defined(CONFIG_DRM_AMD_DC_DCN) - if (enc->afmt && enc->afmt->funcs->afmt_powerdown) - enc->afmt->funcs->afmt_powerdown(enc->afmt); -#endif enc1_se_enable_audio_clock(enc, false); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h index 687d7e4bf7..0d86df9787 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h @@ -627,11 +627,9 @@ void enc1_stream_encoder_stop_dp_info_packets( struct stream_encoder *enc); void enc1_stream_encoder_dp_blank( - struct dc_link *link, struct stream_encoder *enc); void enc1_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h index f98aba3080..ede65100a0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.h @@ -169,29 +169,7 @@ type DTBCLK_DTO_DIV[MAX_PIPES];\ type DCCG_AUDIO_DTO_SEL;\ type DCCG_AUDIO_DTO0_SOURCE_SEL;\ - type DENTIST_DISPCLK_CHG_MODE;\ - type DSCCLK0_DTO_PHASE;\ - type DSCCLK0_DTO_MODULO;\ - type DSCCLK1_DTO_PHASE;\ - type DSCCLK1_DTO_MODULO;\ - type DSCCLK2_DTO_PHASE;\ - type DSCCLK2_DTO_MODULO;\ - type DSCCLK0_DTO_ENABLE;\ - type DSCCLK1_DTO_ENABLE;\ - type DSCCLK2_DTO_ENABLE;\ - type SYMCLK32_ROOT_SE0_GATE_DISABLE;\ - type SYMCLK32_ROOT_SE1_GATE_DISABLE;\ - type SYMCLK32_ROOT_SE2_GATE_DISABLE;\ - type SYMCLK32_ROOT_SE3_GATE_DISABLE;\ - type SYMCLK32_ROOT_LE0_GATE_DISABLE;\ - type SYMCLK32_ROOT_LE1_GATE_DISABLE;\ - type DPSTREAMCLK_ROOT_GATE_DISABLE;\ - type DPSTREAMCLK_GATE_DISABLE;\ - type HDMISTREAMCLK0_DTO_PHASE;\ - type HDMISTREAMCLK0_DTO_MODULO;\ - type HDMICHARCLK0_GATE_DISABLE;\ - type HDMICHARCLK0_ROOT_GATE_DISABLE; - + type DENTIST_DISPCLK_CHG_MODE; struct dccg_shift { DCCG_REG_FIELD_LIST(uint8_t) @@ -227,16 +205,6 @@ struct dccg_registers { uint32_t SYMCLK32_SE_CNTL; uint32_t SYMCLK32_LE_CNTL; uint32_t DENTIST_DISPCLK_CNTL; - uint32_t DSCCLK_DTO_CTRL; - uint32_t DSCCLK0_DTO_PARAM; - uint32_t DSCCLK1_DTO_PARAM; - uint32_t DSCCLK2_DTO_PARAM; - uint32_t DPSTREAMCLK_ROOT_GATE_DISABLE; - uint32_t DPSTREAMCLK_GATE_DISABLE; - uint32_t DCCG_GATE_DISABLE_CNTL3; - uint32_t HDMISTREAMCLK0_DTO_PARAM; - uint32_t DCCG_GATE_DISABLE_CNTL4; - }; struct dcn_dccg { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c index 970b65efea..a9e420c7d7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c @@ -251,6 +251,20 @@ static void dpp2_cnv_setup ( } +void dpp2_cnv_set_bias_scale( + struct dpp *dpp_base, + struct dc_bias_and_scale *bias_and_scale) +{ + struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); + + REG_UPDATE(FCNV_FP_BIAS_R, FCNV_FP_BIAS_R, bias_and_scale->bias_red); + REG_UPDATE(FCNV_FP_BIAS_G, FCNV_FP_BIAS_G, bias_and_scale->bias_green); + REG_UPDATE(FCNV_FP_BIAS_B, FCNV_FP_BIAS_B, bias_and_scale->bias_blue); + REG_UPDATE(FCNV_FP_SCALE_R, FCNV_FP_SCALE_R, bias_and_scale->scale_red); + REG_UPDATE(FCNV_FP_SCALE_G, FCNV_FP_SCALE_G, bias_and_scale->scale_green); + REG_UPDATE(FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, bias_and_scale->scale_blue); +} + /*compute the maximum number of lines that we can fit in the line buffer*/ void dscl2_calc_lb_num_partitions( const struct scaler_data *scl_data, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c index ef5c4c0f4d..79b640e202 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c @@ -162,8 +162,6 @@ static void dsc2_read_state(struct display_stream_compressor *dsc, struct dcn_ds REG_GET(DSCC_PPS_CONFIG2, PIC_WIDTH, &s->dsc_pic_width); REG_GET(DSCC_PPS_CONFIG2, PIC_HEIGHT, &s->dsc_pic_height); REG_GET(DSCC_PPS_CONFIG7, SLICE_BPG_OFFSET, &s->dsc_slice_bpg_offset); - REG_GET_2(DSCRM_DSC_FORWARD_CONFIG, DSCRM_DSC_FORWARD_EN, &s->dsc_fw_en, - DSCRM_DSC_OPP_PIPE_SOURCE, &s->dsc_opp_source); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c index 994fb732a7..880954ac0b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c @@ -527,7 +527,7 @@ static const uint16_t filter_12tap_16p_183[108] = { 0, 84, 16328, 16032, 416, 1944, 1944, 416, 16032, 16328, 84, 0, }; -static const uint16_t *wbscl_get_filter_3tap_16p(struct fixed31_32 ratio) +const uint16_t *wbscl_get_filter_3tap_16p(struct fixed31_32 ratio) { if (ratio.value < dc_fixpt_one.value) return filter_3tap_16p_upscale; @@ -539,7 +539,7 @@ static const uint16_t *wbscl_get_filter_3tap_16p(struct fixed31_32 ratio) return filter_3tap_16p_183; } -static const uint16_t *wbscl_get_filter_4tap_16p(struct fixed31_32 ratio) +const uint16_t *wbscl_get_filter_4tap_16p(struct fixed31_32 ratio) { if (ratio.value < dc_fixpt_one.value) return filter_4tap_16p_upscale; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c index dc1752e9f4..5adf42a7cc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -192,8 +192,9 @@ void hubp2_vready_at_or_After_vsync(struct hubp *hubp, REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, value); } -static void hubp2_program_requestor(struct hubp *hubp, - struct _vcs_dpi_display_rq_regs_st *rq_regs) +void hubp2_program_requestor( + struct hubp *hubp, + struct _vcs_dpi_display_rq_regs_st *rq_regs) { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); @@ -928,16 +929,6 @@ bool hubp2_is_flip_pending(struct hubp *hubp) } void hubp2_set_blank(struct hubp *hubp, bool blank) -{ - hubp2_set_blank_regs(hubp, blank); - - if (blank) { - hubp->mpcc_id = 0xf; - hubp->opp_id = OPP_ID_INVALID; - } -} - -void hubp2_set_blank_regs(struct hubp *hubp, bool blank) { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); uint32_t blank_en = blank ? 1 : 0; @@ -960,6 +951,9 @@ void hubp2_set_blank_regs(struct hubp *hubp, bool blank) HUBP_NO_OUTSTANDING_REQ, 1, 1, 200); } + + hubp->mpcc_id = 0xf; + hubp->opp_id = OPP_ID_INVALID; } } @@ -1291,7 +1285,7 @@ void hubp2_read_state(struct hubp *hubp) } -static void hubp2_validate_dml_output(struct hubp *hubp, +void hubp2_validate_dml_output(struct hubp *hubp, struct dc_context *ctx, struct _vcs_dpi_display_rq_regs_st *dml_rq_regs, struct _vcs_dpi_display_dlg_regs_st *dml_dlg_attr, @@ -1609,7 +1603,6 @@ static struct hubp_funcs dcn20_hubp_funcs = { .hubp_setup_interdependent = hubp2_setup_interdependent, .hubp_set_vm_system_aperture_settings = hubp2_set_vm_system_aperture_settings, .set_blank = hubp2_set_blank, - .set_blank_regs = hubp2_set_blank_regs, .dcc_control = hubp2_dcc_control, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h index 9204c3ef32..eea2254b15 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.h @@ -330,7 +330,6 @@ void hubp2_program_surface_config( bool hubp2_is_flip_pending(struct hubp *hubp); void hubp2_set_blank(struct hubp *hubp, bool blank); -void hubp2_set_blank_regs(struct hubp *hubp, bool blank); void hubp2_cursor_set_position( struct hubp *hubp, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index 4991e93e53..a47ba1d45b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -52,9 +52,6 @@ #include "dc_dmub_srv.h" #include "dce/dmub_hw_lock_mgr.h" #include "hw_sequencer.h" -#include "inc/link_dpcd.h" -#include "dpcd_defs.h" -#include "inc/link_enc_cfg.h" #define DC_LOGGER_INIT(logger) @@ -615,11 +612,6 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) pipe_ctx->pipe_idx); } -void dcn20_disable_pixel_data(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank) -{ - dcn20_blank_pixel_data(dc, pipe_ctx, blank); -} - static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, int opp_cnt) { @@ -1085,8 +1077,10 @@ static void dcn20_power_on_plane( } } -static void dcn20_enable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx, - struct dc_state *context) +void dcn20_enable_plane( + struct dc *dc, + struct pipe_ctx *pipe_ctx, + struct dc_state *context) { //if (dc->debug.sanity_checks) { // dcn10_verify_allow_pstate_change_high(dc); @@ -1845,11 +1839,6 @@ void dcn20_optimize_bandwidth( dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); - if (dc->clk_mgr->dc_mode_softmax_enabled) - if (dc->clk_mgr->clks.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 && - context->bw_ctx.bw.dcn.clk.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->dc_mode_softmax_memclk); - dc->clk_mgr->funcs->update_clocks( dc->clk_mgr, context, @@ -2131,7 +2120,7 @@ void dcn20_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx) void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings) { - struct encoder_unblank_param params = {0}; + struct encoder_unblank_param params = { { 0 } }; struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->link; struct dce_hwseq *hws = link->dc->hwseq; @@ -2146,17 +2135,12 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx, params.link_settings.link_rate = link_settings->link_rate; - if (is_dp_128b_132b_signal(pipe_ctx)) { - /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank( - pipe_ctx->stream_res.hpo_dp_stream_enc, - pipe_ctx->stream_res.tg->inst); - } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { + if (dc_is_dp_signal(pipe_ctx->stream->signal)) { if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1) params.timing.pix_clk_100hz /= 2; pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine( pipe_ctx->stream_res.stream_enc, params.opp_cnt > 1); - pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); + pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(pipe_ctx->stream_res.stream_enc, ¶ms); } if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { @@ -2278,7 +2262,7 @@ void dcn20_reset_hw_ctx_wrap( dcn20_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); if (hws->funcs.enable_stream_gating) - hws->funcs.enable_stream_gating(dc, pipe_ctx_old); + hws->funcs.enable_stream_gating(dc, pipe_ctx); if (old_clk) old_clk->funcs->cs_power_down(old_clk); } @@ -2306,7 +2290,7 @@ void dcn20_update_visual_confirm_color(struct dc *dc, struct pipe_ctx *pipe_ctx, void dcn20_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx) { struct hubp *hubp = pipe_ctx->plane_res.hubp; - struct mpcc_blnd_cfg blnd_cfg = {0}; + struct mpcc_blnd_cfg blnd_cfg = { {0} }; bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha; int mpcc_id; struct mpcc *new_mpcc; @@ -2390,39 +2374,14 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) uint32_t active_total_with_borders; uint32_t early_control = 0; struct timing_generator *tg = pipe_ctx->stream_res.tg; - struct link_encoder *link_enc; - - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) - link_enc = link_enc_cfg_get_link_enc_used_by_stream(link->ctx->dc, pipe_ctx->stream); - else - link_enc = link->link_enc; - ASSERT(link_enc); /* For MST, there are multiply stream go to only one link. * connect DIG back_end to front_end while enable_stream and * disconnect them during disable_stream * BY this, it is logic clean to separate stream and link */ - if (is_dp_128b_132b_signal(pipe_ctx)) { - if (pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control) - pipe_ctx->stream->ctx->dc->hwseq->funcs.setup_hpo_hw_control( - pipe_ctx->stream->ctx->dc->hwseq, true); - setup_dp_hpo_stream(pipe_ctx, true); - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream( - pipe_ctx->stream_res.hpo_dp_stream_enc); - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->map_stream_to_link( - pipe_ctx->stream_res.hpo_dp_stream_enc, - pipe_ctx->stream_res.hpo_dp_stream_enc->inst, - pipe_ctx->link_res.hpo_dp_link_enc->inst); - } - - if (!is_dp_128b_132b_signal(pipe_ctx) && link_enc) - link_enc->funcs->connect_dig_be_to_fe( - link_enc, pipe_ctx->stream_res.stream_enc->id, true); - - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE); + link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc, + pipe_ctx->stream_res.stream_enc->id, true); if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) { if (link->dc->hwss.program_dmdata_engine) @@ -2431,9 +2390,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) link->dc->hwss.update_info_frame(pipe_ctx); - if (dc_is_dp_signal(pipe_ctx->stream->signal)) - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); - /* enable early control to avoid corruption on DP monitor*/ active_total_with_borders = timing->h_addressable @@ -2450,9 +2406,7 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx) /* enable audio only within mode set */ if (pipe_ctx->stream_res.audio != NULL) { - if (is_dp_128b_132b_signal(pipe_ctx)) - pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.hpo_dp_stream_enc); - else if (dc_is_dp_signal(pipe_ctx->stream->signal)) + if (dc_is_dp_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc); } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h index 33a36c02b2..6bba191cd3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h @@ -53,10 +53,6 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx); void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx, struct dc_link_settings *link_settings); void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx); -void dcn20_disable_pixel_data( - struct dc *dc, - struct pipe_ctx *pipe_ctx, - bool blank); void dcn20_blank_pixel_data( struct dc *dc, struct pipe_ctx *pipe_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index 91e4885b74..5cfd4b0afe 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -27,8 +27,6 @@ #include "dcn10/dcn10_hw_sequencer.h" #include "dcn20_hwseq.h" -#include "dcn20_init.h" - static const struct hw_sequencer_funcs dcn20_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c index 15734db0cd..947eb0df3f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c @@ -400,9 +400,10 @@ static void mpc20_program_ogam_pwl( } -static void apply_DEDCN20_305_wa(struct mpc *mpc, int mpcc_id, - enum dc_lut_mode current_mode, - enum dc_lut_mode next_mode) +void apply_DEDCN20_305_wa( + struct mpc *mpc, + int mpcc_id, enum dc_lut_mode current_mode, + enum dc_lut_mode next_mode) { struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc); @@ -524,7 +525,7 @@ static void mpc2_init_mpcc(struct mpcc *mpcc, int mpcc_inst) mpcc->sm_cfg.enable = false; } -static struct mpcc *mpc2_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id) +struct mpcc *mpc2_get_mpcc_for_dpp(struct mpc_tree *tree, int dpp_id) { struct mpcc *tmp_mpcc = tree->opp_list; diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c index 0340fdd3f5..f6e747f25e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c @@ -72,6 +72,21 @@ bool optc2_enable_crtc(struct timing_generator *optc) return true; } +/** + * DRR double buffering control to select buffer point + * for V_TOTAL, H_TOTAL, VTOTAL_MIN, VTOTAL_MAX, VTOTAL_MIN_SEL and VTOTAL_MAX_SEL registers + * Options: anytime, start of frame, dp start of frame (range timing) + */ +void optc2_set_timing_db_mode(struct timing_generator *optc, bool enable) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + uint32_t blank_data_double_buffer_enable = enable ? 1 : 0; + + REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL, + OTG_RANGE_TIMING_DBUF_UPDATE_MODE, blank_data_double_buffer_enable); +} + /** *For the below, I'm not sure how your GSL parameters are stored in your env, * so I will assume a gsl_params struct for now @@ -95,6 +110,30 @@ void optc2_set_gsl(struct timing_generator *optc, } +/* Use the gsl allow flip as the master update lock */ +void optc2_use_gsl_as_master_update_lock(struct timing_generator *optc, + const struct gsl_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_UPDATE(OTG_GSL_CONTROL, + OTG_MASTER_UPDATE_LOCK_GSL_EN, params->master_update_lock_gsl_en); +} + +/* You can control the GSL timing by limiting GSL to a window (X,Y) */ +void optc2_set_gsl_window(struct timing_generator *optc, + const struct gsl_params *params) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_2(OTG_GSL_WINDOW_X, 0, + OTG_GSL_WINDOW_START_X, params->gsl_window_start_x, + OTG_GSL_WINDOW_END_X, params->gsl_window_end_x); + REG_SET_2(OTG_GSL_WINDOW_Y, 0, + OTG_GSL_WINDOW_START_Y, params->gsl_window_start_y, + OTG_GSL_WINDOW_END_Y, params->gsl_window_end_y); +} + void optc2_set_gsl_source_select( struct timing_generator *optc, int group_idx, @@ -117,6 +156,18 @@ void optc2_set_gsl_source_select( } } +/* DSC encoder frame start controls: x = h position, line_num = # of lines from vstartup */ +void optc2_set_dsc_encoder_frame_start(struct timing_generator *optc, + int x_position, + int line_num) +{ + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_SET_2(OTG_DSC_START_POSITION, 0, + OTG_DSC_START_POSITION_X, x_position, + OTG_DSC_START_POSITION_LINE_NUM, line_num); +} + /* Set DSC-related configuration. * dsc_mode: 0 disables DSC, other values enable DSC in specified format * sc_bytes_per_pixel: Bytes per pixel in u3.28 format @@ -139,19 +190,6 @@ void optc2_set_dsc_config(struct timing_generator *optc, OPTC_DSC_SLICE_WIDTH, dsc_slice_width); } -/* Get DSC-related configuration. - * dsc_mode: 0 disables DSC, other values enable DSC in specified format - */ -void optc2_get_dsc_status(struct timing_generator *optc, - uint32_t *dsc_mode) -{ - struct optc *optc1 = DCN10TG_FROM_TG(optc); - - REG_GET(OPTC_DATA_FORMAT_CONTROL, - OPTC_DSC_MODE, dsc_mode); -} - - /*TEMP: Need to figure out inheritance model here.*/ bool optc2_is_two_pixels_per_containter(const struct dc_crtc_timing *timing) { @@ -242,8 +280,8 @@ void optc2_get_optc_source(struct timing_generator *optc, *num_of_src_opp = 1; } -static void optc2_set_dwb_source(struct timing_generator *optc, - uint32_t dwb_pipe_inst) +void optc2_set_dwb_source(struct timing_generator *optc, + uint32_t dwb_pipe_inst) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -255,7 +293,7 @@ static void optc2_set_dwb_source(struct timing_generator *optc, OPTC_DWB1_SOURCE_SELECT, optc->inst); } -static void optc2_align_vblanks( +void optc2_align_vblanks( struct timing_generator *optc_master, struct timing_generator *optc_slave, uint32_t master_pixel_clock_100Hz, @@ -429,11 +467,6 @@ void optc2_lock_doublebuffer_enable(struct timing_generator *optc) (h_blank_start - 200 - 1) / optc1->opp_count, MASTER_UPDATE_LOCK_DB_Y, v_blank_start - 1); - - REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100, - OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1); } void optc2_lock_doublebuffer_disable(struct timing_generator *optc) @@ -541,7 +574,6 @@ static struct timing_generator_funcs dcn20_tg_funcs = { .get_crc = optc1_get_crc, .configure_crc = optc2_configure_crc, .set_dsc_config = optc2_set_dsc_config, - .get_dsc_status = optc2_get_dsc_status, .set_dwb_source = optc2_set_dwb_source, .set_odm_bypass = optc2_set_odm_bypass, .set_odm_combine = optc2_set_odm_combine, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h index f7968b9ca1..be19a6885f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h @@ -98,9 +98,6 @@ void optc2_set_dsc_config(struct timing_generator *optc, uint32_t dsc_bytes_per_pixel, uint32_t dsc_slice_width); -void optc2_get_dsc_status(struct timing_generator *optc, - uint32_t *dsc_mode); - void optc2_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 2a72517e2b..ede11eb120 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -35,7 +35,7 @@ #include "include/irq_service_interface.h" #include "dcn20/dcn20_resource.h" -#include "dml/dcn20/dcn20_fpu.h" +#include "dml/dcn2x/dcn2x.h" #include "dcn10/dcn10_hubp.h" #include "dcn10/dcn10_ipp.h" @@ -63,7 +63,6 @@ #include "dcn20_dccg.h" #include "dcn20_vmid.h" #include "dc_link_ddc.h" -#include "dc_link_dp.h" #include "dce/dce_panel_cntl.h" #include "navi10_ip_offset.h" @@ -87,7 +86,6 @@ #include "dce/dce_aux.h" #include "dce/dce_i2c.h" #include "vm_helper.h" -#include "link_enc_cfg.h" #include "amdgpu_socbb.h" @@ -1597,32 +1595,15 @@ static void get_pixel_clock_parameters( const struct dc_stream_state *stream = pipe_ctx->stream; struct pipe_ctx *odm_pipe; int opp_cnt = 1; - struct dc_link *link = stream->link; - struct link_encoder *link_enc = NULL; for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) opp_cnt++; pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz; - - /* Links supporting dynamically assigned link encoder will be assigned next - * available encoder if one not already assigned. - */ - if (link->is_dig_mapping_flexible && - link->dc->res_pool->funcs->link_encs_assign) { - link_enc = link_enc_cfg_get_link_enc_used_by_stream(stream->ctx->dc, stream); - if (link_enc == NULL) - link_enc = link_enc_cfg_get_next_avail_link_enc(stream->ctx->dc); - } else - link_enc = stream->link->link_enc; - ASSERT(link_enc); - - if (link_enc) - pixel_clk_params->encoder_object_id = link_enc->id; + pixel_clk_params->encoder_object_id = stream->link->link_enc->id; pixel_clk_params->signal_type = pipe_ctx->stream->signal; pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1; /* TODO: un-hardcode*/ - /* TODO - DP2.0 HW: calculate requested_sym_clk for UHBR rates */ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW * LINK_RATE_REF_FREQ_IN_KHZ; pixel_clk_params->flags.ENABLE_SS = 0; @@ -3065,8 +3046,6 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; - if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) - return true; } return false; } @@ -3093,7 +3072,8 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { struct dc_link *link = context->streams[0]->sink->link; - if (link->link_index == 0 && context->bw_ctx.dml.vba.StutterPeriod > 5000.0) + if ((link->link_index == 0 && link->psr_settings.psr_feature_enabled) + || context->bw_ctx.dml.vba.StutterPeriod > 5000.0) return DCN_ZSTATE_SUPPORT_ALLOW; else return DCN_ZSTATE_SUPPORT_DISALLOW; @@ -3116,10 +3096,6 @@ void dcn20_calculate_dlg_params( context->bw_ctx.bw.dcn.clk.dcfclk_khz = context->bw_ctx.dml.vba.DCFCLK * 1000; context->bw_ctx.bw.dcn.clk.socclk_khz = context->bw_ctx.dml.vba.SOCCLK * 1000; context->bw_ctx.bw.dcn.clk.dramclk_khz = context->bw_ctx.dml.vba.DRAMSpeed * 1000 / 16; - - if (dc->debug.min_dram_clk_khz > context->bw_ctx.bw.dcn.clk.dramclk_khz) - context->bw_ctx.bw.dcn.clk.dramclk_khz = dc->debug.min_dram_clk_khz; - context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = context->bw_ctx.dml.vba.DCFCLKDeepSleep * 1000; context->bw_ctx.bw.dcn.clk.fclk_khz = context->bw_ctx.dml.vba.FabricClock * 1000; context->bw_ctx.bw.dcn.clk.p_state_change_support = @@ -3166,9 +3142,6 @@ void dcn20_calculate_dlg_params( if (!context->res_ctx.pipe_ctx[i].stream) continue; - if (dc->ctx->dce_version == DCN_VERSION_2_01) - cstate_en = false; - context->bw_ctx.dml.funcs.rq_dlg_get_dlg_reg(&context->bw_ctx.dml, &context->res_ctx.pipe_ctx[i].dlg_regs, &context->res_ctx.pipe_ctx[i].ttu_regs, @@ -3659,6 +3632,9 @@ static enum dml_project get_dml_project_version(uint32_t hw_internal_rev) return DML_PROJECT_NAVI10v2; } +#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) +#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) + static bool init_soc_bounding_box(struct dc *dc, struct dcn20_resource_pool *pool) { @@ -3795,8 +3771,6 @@ static bool dcn20_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - dc->caps.hdmi_frl_pcon_support = true; - if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { dc->debug = debug_defaults_drv; } else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c index aab25ca834..e6307397e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c @@ -29,8 +29,6 @@ #include "dcn20_stream_encoder.h" #include "reg_helper.h" #include "hw_shared.h" -#include "inc/link_dpcd.h" -#include "dpcd_defs.h" #define DC_LOGGER \ enc1->base.ctx->logger @@ -211,8 +209,7 @@ static void enc2_stream_encoder_stop_hdmi_info_packets( /* Update GSP7 SDP 128 byte long */ static void enc2_update_gsp7_128_info_packet( struct dcn10_stream_encoder *enc1, - const struct dc_info_packet_128 *info_packet, - bool immediate_update) + const struct dc_info_packet_128 *info_packet) { uint32_t i; @@ -267,9 +264,7 @@ static void enc2_update_gsp7_128_info_packet( REG_WRITE(AFMT_GENERIC_7, *content++); } - REG_UPDATE_2(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC7_FRAME_UPDATE, !immediate_update, - AFMT_GENERIC7_IMMEDIATE_UPDATE, immediate_update); + REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, 1); } /* Set DSC-related configuration. @@ -295,8 +290,7 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc, static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc, bool enable, - uint8_t *dsc_packed_pps, - bool immediate_update) + uint8_t *dsc_packed_pps) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -312,7 +306,7 @@ static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc, pps_sdp.hb2 = 127; pps_sdp.hb3 = 0; memcpy(&pps_sdp.sb[0], dsc_packed_pps, sizeof(pps_sdp.sb)); - enc2_update_gsp7_128_info_packet(enc1, &pps_sdp, immediate_update); + enc2_update_gsp7_128_info_packet(enc1, &pps_sdp); /* Enable Generic Stream Packet 7 (GSP) transmission */ //REG_UPDATE(DP_SEC_CNTL, @@ -450,7 +444,6 @@ static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing) } void enc2_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param) { @@ -529,8 +522,6 @@ void enc2_stream_encoder_dp_unblank( */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true); - - dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM); } static void enc2_dp_set_odm_combine( diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h index baa1e539f3..f3d1a0237b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.h @@ -104,7 +104,6 @@ void enc2_stream_encoder_dp_set_stream_attribute( uint32_t enable_sdp_splitting); void enc2_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param); diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c index c5e200d090..36044cb8ec 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c @@ -680,7 +680,7 @@ void hubbub21_wm_read_state(struct hubbub *hubbub, DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, &s->dram_clk_chanage); } -static void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) +void hubbub21_apply_DEDCN21_147_wa(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); uint32_t prog_wm_value; diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 58e459c7e7..3de1bcf9b3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -183,7 +183,7 @@ static void hubp21_setup( } -static void hubp21_set_viewport( +void hubp21_set_viewport( struct hubp *hubp, const struct rect *viewport, const struct rect *viewport_c) @@ -225,8 +225,8 @@ static void hubp21_set_viewport( SEC_VIEWPORT_Y_START_C, viewport_c->y); } -static void hubp21_set_vm_system_aperture_settings(struct hubp *hubp, - struct vm_system_aperture_param *apt) +void hubp21_set_vm_system_aperture_settings(struct hubp *hubp, + struct vm_system_aperture_param *apt) { struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); @@ -248,7 +248,7 @@ static void hubp21_set_vm_system_aperture_settings(struct hubp *hubp, SYSTEM_ACCESS_MODE, 0x3); } -static void hubp21_validate_dml_output(struct hubp *hubp, +void hubp21_validate_dml_output(struct hubp *hubp, struct dc_context *ctx, struct _vcs_dpi_display_rq_regs_st *dml_rq_regs, struct _vcs_dpi_display_dlg_regs_st *dml_dlg_attr, @@ -664,8 +664,7 @@ static void program_surface_flip_and_addr(struct hubp *hubp, struct surface_flip flip_regs->DCSURF_PRIMARY_SURFACE_ADDRESS); } -static void dmcub_PLAT_54186_wa(struct hubp *hubp, - struct surface_flip_registers *flip_regs) +void dmcub_PLAT_54186_wa(struct hubp *hubp, struct surface_flip_registers *flip_regs) { struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv; struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); @@ -698,7 +697,7 @@ static void dmcub_PLAT_54186_wa(struct hubp *hubp, PERF_TRACE(); // TODO: remove after performance is stable. } -static bool hubp21_program_surface_flip_and_addr( +bool hubp21_program_surface_flip_and_addr( struct hubp *hubp, const struct dc_plane_address *address, bool flip_immediate) @@ -806,7 +805,7 @@ static bool hubp21_program_surface_flip_and_addr( return true; } -static void hubp21_init(struct hubp *hubp) +void hubp21_init(struct hubp *hubp) { // DEDCN21-133: Inconsistent row starting line for flip between DPTE and Meta // This is a chicken bit to enable the ECO fix. diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index b270f0b194..54c11ba550 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -28,8 +28,6 @@ #include "dcn20/dcn20_hwseq.h" #include "dcn21_hwseq.h" -#include "dcn21_init.h" - static const struct hw_sequencer_funcs dcn21_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c index 0a1ba6e708..aa46c35b05 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c @@ -203,7 +203,7 @@ static bool update_cfg_data( return true; } -static bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc) +bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); int value; @@ -277,7 +277,7 @@ void dcn21_link_encoder_enable_dp_output( } -static void dcn21_link_encoder_enable_dp_mst_output( +void dcn21_link_encoder_enable_dp_mst_output( struct link_encoder *enc, const struct dc_link_settings *link_settings, enum clock_source_id clock_source) @@ -288,8 +288,9 @@ static void dcn21_link_encoder_enable_dp_mst_output( dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source); } -static void dcn21_link_encoder_disable_output(struct link_encoder *enc, - enum signal_type signal) +void dcn21_link_encoder_disable_output( + struct link_encoder *enc, + enum signal_type signal) { dcn10_link_encoder_disable_output(enc, signal); diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index e5cc6bf457..92a308ad12 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -35,7 +35,7 @@ #include "include/irq_service_interface.h" #include "dcn20/dcn20_resource.h" -#include "dml/dcn20/dcn20_fpu.h" +#include "dml/dcn2x/dcn2x.h" #include "clk_mgr.h" #include "dcn10/dcn10_hubp.h" @@ -784,8 +784,9 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) }; -static struct dce_i2c_hw *dcn21_i2c_hw_create(struct dc_context *ctx, - uint32_t inst) +struct dce_i2c_hw *dcn21_i2c_hw_create( + struct dc_context *ctx, + uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); @@ -1092,7 +1093,7 @@ static void patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_s } } -static void dcn21_calculate_wm( +void dcn21_calculate_wm( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, int *out_pipe_cnt, @@ -1389,7 +1390,7 @@ static noinline bool dcn21_validate_bandwidth_fp(struct dc *dc, * with DC_FP_START()/DC_FP_END(). Use the same approach as for * dcn20_validate_bandwidth in dcn20_resource.c. */ -static bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, +bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate) { bool voltage_supported; @@ -1479,8 +1480,8 @@ static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx) return &hubbub->base; } -static struct output_pixel_processor *dcn21_opp_create(struct dc_context *ctx, - uint32_t inst) +struct output_pixel_processor *dcn21_opp_create( + struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); @@ -1495,8 +1496,9 @@ static struct output_pixel_processor *dcn21_opp_create(struct dc_context *ctx, return &opp->base; } -static struct timing_generator *dcn21_timing_generator_create(struct dc_context *ctx, - uint32_t instance) +struct timing_generator *dcn21_timing_generator_create( + struct dc_context *ctx, + uint32_t instance) { struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL); @@ -1516,7 +1518,7 @@ static struct timing_generator *dcn21_timing_generator_create(struct dc_context return &tgn10->base; } -static struct mpc *dcn21_mpc_create(struct dc_context *ctx) +struct mpc *dcn21_mpc_create(struct dc_context *ctx) { struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), GFP_KERNEL); @@ -1543,8 +1545,8 @@ static void read_dce_straps( } -static struct display_stream_compressor *dcn21_dsc_create(struct dc_context *ctx, - uint32_t inst) +struct display_stream_compressor *dcn21_dsc_create( + struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); @@ -1681,8 +1683,9 @@ static struct dc_cap_funcs cap_funcs = { .get_dcc_compression_cap = dcn20_get_dcc_compression_cap }; -static struct stream_encoder *dcn21_stream_encoder_create(enum engine_id eng_id, - struct dc_context *ctx) +struct stream_encoder *dcn21_stream_encoder_create( + enum engine_id eng_id, + struct dc_context *ctx) { struct dcn10_stream_encoder *enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); @@ -1914,7 +1917,7 @@ static int dcn21_populate_dml_pipes_from_context( return pipe_cnt; } -static enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state *plane_state) +enum dc_status dcn21_patch_unknown_plane_state(struct dc_plane_state *plane_state) { enum dc_status result = DC_OK; @@ -2025,8 +2028,6 @@ static bool dcn21_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - dc->caps.hdmi_frl_pcon_support = true; - if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c index 95528e5ef8..fa981cd04d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c @@ -44,14 +44,11 @@ afmt3->base.ctx -void afmt3_setup_hdmi_audio( +static void afmt3_setup_hdmi_audio( struct afmt *afmt) { struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); - if (afmt->funcs->afmt_poweron) - afmt->funcs->afmt_poweron(afmt); - /* AFMT_AUDIO_PACKET_CONTROL */ REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); @@ -116,7 +113,7 @@ static union audio_cea_channels speakers_to_channels( return cea_channels; } -void afmt3_se_audio_setup( +static void afmt3_se_audio_setup( struct afmt *afmt, unsigned int az_inst, struct audio_info *audio_info) @@ -141,24 +138,20 @@ void afmt3_se_audio_setup( REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels); /* Disable forced mem power off */ - if (afmt->funcs->afmt_poweron == NULL) - REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0); + REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0); } -void afmt3_audio_mute_control( +static void afmt3_audio_mute_control( struct afmt *afmt, bool mute) { struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); - if (mute && afmt->funcs->afmt_powerdown) - afmt->funcs->afmt_powerdown(afmt); - if (!mute && afmt->funcs->afmt_poweron) - afmt->funcs->afmt_poweron(afmt); + /* enable/disable transmission of audio packets */ REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute); } -void afmt3_audio_info_immediate_update( +static void afmt3_audio_info_immediate_update( struct afmt *afmt) { struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); @@ -167,14 +160,11 @@ void afmt3_audio_info_immediate_update( REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1); } -void afmt3_setup_dp_audio( +static void afmt3_setup_dp_audio( struct afmt *afmt) { struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); - if (afmt->funcs->afmt_poweron) - afmt->funcs->afmt_poweron(afmt); - /* AFMT_AUDIO_PACKET_CONTROL */ REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h index 97e0cf62f9..85d4619207 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h @@ -121,12 +121,6 @@ struct afmt_funcs { void (*setup_dp_audio)( struct afmt *afmt); - - void (*afmt_poweron)( - struct afmt *afmt); - - void (*afmt_powerdown)( - struct afmt *afmt); }; struct afmt { @@ -142,24 +136,6 @@ struct dcn30_afmt { const struct dcn30_afmt_mask *afmt_mask; }; -void afmt3_setup_hdmi_audio( - struct afmt *afmt); - -void afmt3_se_audio_setup( - struct afmt *afmt, - unsigned int az_inst, - struct audio_info *audio_info); - -void afmt3_audio_mute_control( - struct afmt *afmt, - bool mute); - -void afmt3_audio_info_immediate_update( - struct afmt *afmt); - -void afmt3_setup_dp_audio( - struct afmt *afmt); - void afmt3_construct(struct dcn30_afmt *afmt3, struct dc_context *ctx, uint32_t inst, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c index 6f3c2fb607..46ea39f5ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c @@ -192,10 +192,6 @@ void dcn30_link_encoder_construct( enc10->base.features.flags.bits.IS_HBR3_CAPABLE = bp_cap_info.DP_HBR3_EN; enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; - enc10->base.features.flags.bits.IS_DP2_CAPABLE = bp_cap_info.IS_DP2_CAPABLE; - enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; - enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; - enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN; enc10->base.features.flags.bits.DP_IS_USB_C = bp_cap_info.DP_IS_USB_C; } else { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c index a04ca4a983..8487516819 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c @@ -50,6 +50,22 @@ enc1->base.ctx +void convert_dc_info_packet_to_128( + const struct dc_info_packet *info_packet, + struct dc_info_packet_128 *info_packet_128) +{ + unsigned int i; + + info_packet_128->hb0 = info_packet->hb0; + info_packet_128->hb1 = info_packet->hb1; + info_packet_128->hb2 = info_packet->hb2; + info_packet_128->hb3 = info_packet->hb3; + + for (i = 0; i < 32; i++) { + info_packet_128->sb[i] = info_packet->sb[i]; + } + +} static void enc3_update_hdmi_info_packet( struct dcn10_stream_encoder *enc1, uint32_t packet_index, @@ -61,8 +77,7 @@ static void enc3_update_hdmi_info_packet( enc1->base.vpg->funcs->update_generic_info_packet( enc1->base.vpg, packet_index, - info_packet, - true); + info_packet); /* enable transmission of packet(s) - * packet transmission begins on the next frame */ @@ -320,8 +335,7 @@ static void enc3_dp_set_dsc_config(struct stream_encoder *enc, static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc, bool enable, - uint8_t *dsc_packed_pps, - bool immediate_update) + uint8_t *dsc_packed_pps) { struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -351,8 +365,7 @@ static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc, enc1->base.vpg->funcs->update_generic_info_packet( enc1->base.vpg, 11 + i, - &pps_sdp, - immediate_update); + &pps_sdp); } /* SW should make sure VBID[6] update line number is bigger @@ -416,22 +429,19 @@ static void enc3_stream_encoder_update_dp_info_packets( enc->vpg->funcs->update_generic_info_packet( enc->vpg, 0, /* packetIndex */ - &info_frame->vsc, - true); + &info_frame->vsc); } if (info_frame->spd.valid) { enc->vpg->funcs->update_generic_info_packet( enc->vpg, 2, /* packetIndex */ - &info_frame->spd, - true); + &info_frame->spd); } if (info_frame->hdrsmd.valid) { enc->vpg->funcs->update_generic_info_packet( enc->vpg, 3, /* packetIndex */ - &info_frame->hdrsmd, - true); + &info_frame->hdrsmd); } /* packetIndex 4 is used for send immediate sdp message, and please * use other packetIndex (such as 5,6) for other info packet @@ -473,7 +483,7 @@ static void enc3_dp_set_odm_combine( } /* setup stream encoder in dvi mode */ -static void enc3_stream_encoder_dvi_set_stream_attribute( +void enc3_stream_encoder_dvi_set_stream_attribute( struct stream_encoder *enc, struct dc_crtc_timing *crtc_timing, bool is_dual_link) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c index ab3918c0a1..23a52d47e6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c @@ -41,7 +41,8 @@ dpp->tf_shift->field_name, dpp->tf_mask->field_name -static void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s) +void dpp30_read_state(struct dpp *dpp_base, + struct dcn_dpp_state *s) { struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); @@ -372,7 +373,7 @@ void dpp3_set_cursor_attributes( } -static bool dpp3_get_optimal_number_of_taps( +bool dpp3_get_optimal_number_of_taps( struct dpp *dpp, struct scaler_data *scl_data, const struct scaling_taps *in_taps) @@ -473,51 +474,18 @@ static bool dpp3_get_optimal_number_of_taps( return true; } -static void dpp3_deferred_update(struct dpp *dpp_base) +void dpp3_cnv_set_bias_scale( + struct dpp *dpp_base, + struct dc_bias_and_scale *bias_and_scale) { - int bypass_state; struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); - if (dpp_base->deferred_reg_writes.bits.disable_dscl) { - REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); - dpp_base->deferred_reg_writes.bits.disable_dscl = false; - } - - if (dpp_base->deferred_reg_writes.bits.disable_gamcor) { - REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state); - if (bypass_state == 0) { // only program if bypass was latched - REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3); - } else - ASSERT(0); // LUT select was updated again before vupdate - dpp_base->deferred_reg_writes.bits.disable_gamcor = false; - } - - if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) { - REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state); - if (bypass_state == 0) { // only program if bypass was latched - REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3); - } else - ASSERT(0); // LUT select was updated again before vupdate - dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false; - } - - if (dpp_base->deferred_reg_writes.bits.disable_3dlut) { - REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state); - if (bypass_state == 0) { // only program if bypass was latched - REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3); - } else - ASSERT(0); // LUT select was updated again before vupdate - dpp_base->deferred_reg_writes.bits.disable_3dlut = false; - } - - if (dpp_base->deferred_reg_writes.bits.disable_shaper) { - REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state); - if (bypass_state == 0) { // only program if bypass was latched - REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3); - } else - ASSERT(0); // LUT select was updated again before vupdate - dpp_base->deferred_reg_writes.bits.disable_shaper = false; - } + REG_UPDATE(FCNV_FP_BIAS_R, FCNV_FP_BIAS_R, bias_and_scale->bias_red); + REG_UPDATE(FCNV_FP_BIAS_G, FCNV_FP_BIAS_G, bias_and_scale->bias_green); + REG_UPDATE(FCNV_FP_BIAS_B, FCNV_FP_BIAS_B, bias_and_scale->bias_blue); + REG_UPDATE(FCNV_FP_SCALE_R, FCNV_FP_SCALE_R, bias_and_scale->scale_red); + REG_UPDATE(FCNV_FP_SCALE_G, FCNV_FP_SCALE_G, bias_and_scale->scale_green); + REG_UPDATE(FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, bias_and_scale->scale_blue); } static void dpp3_power_on_blnd_lut( @@ -527,13 +495,9 @@ static void dpp3_power_on_blnd_lut( struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { - if (power_on) { - REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0); + REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, power_on ? 0 : 3); + if (power_on) REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5); - } else { - dpp_base->ctx->dc->optimized_required = true; - dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true; - } } else { REG_SET(CM_MEM_PWR_CTRL, 0, BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1); @@ -547,13 +511,9 @@ static void dpp3_power_on_hdr3dlut( struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { - if (power_on) { - REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0); + REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, power_on ? 0 : 3); + if (power_on) REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5); - } else { - dpp_base->ctx->dc->optimized_required = true; - dpp_base->deferred_reg_writes.bits.disable_3dlut = true; - } } } @@ -564,13 +524,9 @@ static void dpp3_power_on_shaper( struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { - if (power_on) { - REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0); + REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, power_on ? 0 : 3); + if (power_on) REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5); - } else { - dpp_base->ctx->dc->optimized_required = true; - dpp_base->deferred_reg_writes.bits.disable_shaper = true; - } } } @@ -735,8 +691,8 @@ static enum dc_lut_mode dpp3_get_blndgam_current(struct dpp *dpp_base) return mode; } -static bool dpp3_program_blnd_lut(struct dpp *dpp_base, - const struct pwl_params *params) +bool dpp3_program_blnd_lut( + struct dpp *dpp_base, const struct pwl_params *params) { enum dc_lut_mode current_mode; enum dc_lut_mode next_mode; @@ -1148,8 +1104,9 @@ static void dpp3_program_shaper_lutb_settings( } -static bool dpp3_program_shaper(struct dpp *dpp_base, - const struct pwl_params *params) +bool dpp3_program_shaper( + struct dpp *dpp_base, + const struct pwl_params *params) { enum dc_lut_mode current_mode; enum dc_lut_mode next_mode; @@ -1338,8 +1295,9 @@ static void dpp3_select_3dlut_ram_mask( REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0); } -static bool dpp3_program_3dlut(struct dpp *dpp_base, - struct tetrahedral_params *params) +bool dpp3_program_3dlut( + struct dpp *dpp_base, + struct tetrahedral_params *params) { enum dc_lut_mode mode; bool is_17x17x17; @@ -1442,7 +1400,6 @@ static struct dpp_funcs dcn30_dpp_funcs = { .dpp_program_blnd_lut = dpp3_program_blnd_lut, .dpp_program_shaper_lut = dpp3_program_shaper, .dpp_program_3dlut = dpp3_program_3dlut, - .dpp_deferred_update = dpp3_deferred_update, .dpp_program_bias_and_scale = NULL, .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, .set_cursor_attributes = dpp3_set_cursor_attributes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c index 387eec6161..72c5687adc 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c @@ -136,13 +136,9 @@ static void dpp3_power_on_gamcor_lut( struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { - if (power_on) { - REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); + REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3); + if (power_on) REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); - } else { - dpp_base->ctx->dc->optimized_required = true; - dpp_base->deferred_reg_writes.bits.disable_gamcor = true; - } } else REG_SET(CM_MEM_PWR_CTRL, 0, GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c index 6a4dcafb9b..f246125232 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c @@ -356,6 +356,12 @@ void hubp3_dcc_control_sienna_cichlid(struct hubp *hubp, { struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); + /*Workaround until UMD fix the new dcc_ind_blk interface */ + if (dcc->independent_64b_blks && dcc->dcc_ind_blk == 0) + dcc->dcc_ind_blk = 1; + if (dcc->independent_64b_blks_c && dcc->dcc_ind_blk_c == 0) + dcc->dcc_ind_blk_c = 1; + REG_UPDATE_6(DCSURF_SURFACE_CONTROL, PRIMARY_SURFACE_DCC_EN, dcc->enable, PRIMARY_SURFACE_DCC_IND_BLK, dcc->dcc_ind_blk, @@ -490,7 +496,6 @@ static struct hubp_funcs dcn30_hubp_funcs = { .hubp_setup_interdependent = hubp2_setup_interdependent, .hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings, .set_blank = hubp2_set_blank, - .set_blank_regs = hubp2_set_blank_regs, .dcc_control = hubp3_dcc_control, .mem_program_viewport = min_set_viewport, .set_cursor_attributes = hubp2_cursor_set_attributes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index 1db1ca1941..0950784baf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -344,17 +344,6 @@ void dcn30_enable_writeback( dwb->funcs->enable(dwb, &wb_info->dwb_params); } -void dcn30_prepare_bandwidth(struct dc *dc, - struct dc_state *context) -{ - if (dc->clk_mgr->dc_mode_softmax_enabled) - if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 && - context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000) - dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz); - - dcn20_prepare_bandwidth(dc, context); -} - void dcn30_disable_writeback( struct dc *dc, unsigned int dwb_pipe_inst) @@ -448,7 +437,7 @@ void dcn30_init_hw(struct dc *dc) struct dce_hwseq *hws = dc->hwseq; struct dc_bios *dcb = dc->ctx->dc_bios; struct resource_pool *res_pool = dc->res_pool; - int i; + int i, j; int edp_num; uint32_t backlight = MAX_BACKLIGHT_LEVEL; @@ -545,8 +534,41 @@ void dcn30_init_hw(struct dc *dc) hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); /* we want to turn off all dp displays before doing detection */ - if (dc->config.power_down_display_on_boot) - dc_link_blank_all_dp_displays(dc); + if (dc->config.power_down_display_on_boot) { + uint8_t dpcd_power_state = '\0'; + enum dc_status status = DC_ERROR_UNEXPECTED; + + for (i = 0; i < dc->link_count; i++) { + if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) + continue; + /* DP 2.0 states that LTTPR regs must be read first */ + dp_retrieve_lttpr_cap(dc->links[i]); + + /* if any of the displays are lit up turn them off */ + status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, + &dpcd_power_state, sizeof(dpcd_power_state)); + if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) { + /* blank dp stream before power off receiver*/ + if (dc->links[i]->link_enc->funcs->get_dig_frontend) { + unsigned int fe; + + fe = dc->links[i]->link_enc->funcs->get_dig_frontend( + dc->links[i]->link_enc); + if (fe == ENGINE_ID_UNKNOWN) + continue; + + for (j = 0; j < dc->res_pool->stream_enc_count; j++) { + if (fe == dc->res_pool->stream_enc[j]->id) { + dc->res_pool->stream_enc[j]->funcs->dp_blank( + dc->res_pool->stream_enc[j]); + break; + } + } + } + dp_receiver_power_ctrl(dc->links[i], false); + } + } + } /* If taking control over from VBIOS, we may want to optimize our first * mode set, so we need to skip powering down pipes until we know which diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h index 73e7b690e8..e9a0005288 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h @@ -27,7 +27,7 @@ #define __DC_HWSS_DCN30_H__ #include "hw_sequencer_private.h" -#include "dcn20/dcn20_hwseq.h" + struct dc; void dcn30_init_hw(struct dc *dc); @@ -47,9 +47,6 @@ void dcn30_disable_writeback( struct dc *dc, unsigned int dwb_pipe_inst); -void dcn30_prepare_bandwidth(struct dc *dc, - struct dc_state *context); - bool dcn30_mmhubbub_warmup( struct dc *dc, unsigned int num_dwb, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index bb347319de..3a5b53dd2f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -29,8 +29,6 @@ #include "dcn21/dcn21_hwseq.h" #include "dcn30_hwseq.h" -#include "dcn30_init.h" - static const struct hw_sequencer_funcs dcn30_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn30_init_hw, @@ -55,7 +53,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .enable_audio_stream = dce110_enable_audio_stream, .disable_audio_stream = dce110_disable_audio_stream, .disable_plane = dcn20_disable_plane, - .disable_pixel_data = dcn20_disable_pixel_data, .pipe_control_lock = dcn20_pipe_control_lock, .interdependent_update_lock = dcn10_lock_all_pipes, .cursor_lock = dcn10_cursor_lock, @@ -103,7 +100,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = { .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, .get_dcc_en_bits = dcn10_get_dcc_en_bits, .update_visual_confirm_color = dcn20_update_visual_confirm_color, - .is_abm_supported = dcn21_is_abm_supported }; static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c index 7a93eff183..1c4b171c68 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mmhubbub.c @@ -100,7 +100,7 @@ static void mmhubbub3_warmup_mcif(struct mcif_wb *mcif_wb, REG_UPDATE(MMHUBBUB_WARMUP_CONTROL_STATUS, MMHUBBUB_WARMUP_EN, false); } -static void mmhubbub3_config_mcif_buf(struct mcif_wb *mcif_wb, +void mmhubbub3_config_mcif_buf(struct mcif_wb *mcif_wb, struct mcif_buf_params *params, unsigned int dest_height) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c index 0ce0d6165f..a82319f4d0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c @@ -1362,7 +1362,7 @@ uint32_t mpcc3_acquire_rmu(struct mpc *mpc, int mpcc_id, int rmu_idx) return -1; } -static int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) +int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) { struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); int rmu_idx; @@ -1381,11 +1381,13 @@ static int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) } -static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc) +static void mpc3_mpc_init(struct mpc *mpc) { struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); int mpcc_id; + mpc1_mpc_init(mpc); + if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) { REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3); @@ -1403,7 +1405,7 @@ const struct mpc_funcs dcn30_mpc_funcs = { .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, - .mpc_init = mpc1_mpc_init, + .mpc_init = mpc3_mpc_init, .mpc_init_single_inst = mpc1_mpc_init_single_inst, .update_blending = mpc2_update_blending, .cursor_lock = mpc1_cursor_lock, @@ -1430,7 +1432,6 @@ const struct mpc_funcs dcn30_mpc_funcs = { .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut, .get_mpc_out_mux = mpc1_get_mpc_out_mux, .set_bg_color = mpc1_set_bg_color, - .set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode, }; void dcn30_mpc_construct(struct dcn30_mpc *mpc30, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index f5e8916601..089be73475 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -73,23 +73,16 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc) OTG_H_BLANK_END, &h_blank_end); REG_UPDATE_2(OTG_GLOBAL_CONTROL1, - MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start - 1, - MASTER_UPDATE_LOCK_DB_END_Y, v_blank_start); + MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start, + MASTER_UPDATE_LOCK_DB_END_Y, v_blank_end); REG_UPDATE_2(OTG_GLOBAL_CONTROL4, - DIG_UPDATE_POSITION_X, h_blank_start - 180 - 1, - DIG_UPDATE_POSITION_Y, v_blank_start - 1); - // there is a DIG_UPDATE_VCOUNT_MODE and it is 0. - + DIG_UPDATE_POSITION_X, 20, + DIG_UPDATE_POSITION_Y, v_blank_start); REG_UPDATE_3(OTG_GLOBAL_CONTROL0, MASTER_UPDATE_LOCK_DB_START_X, h_blank_start - 200 - 1, - MASTER_UPDATE_LOCK_DB_END_X, h_blank_start - 180, + MASTER_UPDATE_LOCK_DB_END_X, h_blank_end, MASTER_UPDATE_LOCK_DB_EN, 1); REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1); - - REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0, - MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100, - OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1); } void optc3_lock_doublebuffer_disable(struct timing_generator *optc) @@ -332,7 +325,6 @@ static struct timing_generator_funcs dcn30_tg_funcs = { .get_crc = optc1_get_crc, .configure_crc = optc2_configure_crc, .set_dsc_config = optc3_set_dsc_config, - .get_dsc_status = optc2_get_dsc_status, .set_dwb_source = NULL, .set_odm_bypass = optc3_set_odm_bypass, .set_odm_combine = optc3_set_odm_combine, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 8ca26383b5..0294d0cc47 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -816,7 +816,7 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = true, .nv12 = true, .fp16 = true, - .p010 = true, + .p010 = false, .ayuv = false, }, @@ -875,7 +875,7 @@ static const struct dc_debug_options debug_defaults_diags = { .use_max_lb = true }; -static void dcn30_dpp_destroy(struct dpp **dpp) +void dcn30_dpp_destroy(struct dpp **dpp) { kfree(TO_DCN20_DPP(*dpp)); *dpp = NULL; @@ -992,7 +992,7 @@ static struct mpc *dcn30_mpc_create( return &mpc30->base; } -static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx) +struct hubbub *dcn30_hubbub_create(struct dc_context *ctx) { int i; @@ -1143,8 +1143,9 @@ static struct afmt *dcn30_afmt_create( return &afmt3->base; } -static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id, - struct dc_context *ctx) +struct stream_encoder *dcn30_stream_encoder_create( + enum engine_id eng_id, + struct dc_context *ctx) { struct dcn10_stream_encoder *enc1; struct vpg *vpg; @@ -1163,12 +1164,8 @@ static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id, vpg = dcn30_vpg_create(ctx, vpg_inst); afmt = dcn30_afmt_create(ctx, afmt_inst); - if (!enc1 || !vpg || !afmt) { - kfree(enc1); - kfree(vpg); - kfree(afmt); + if (!enc1 || !vpg || !afmt) return NULL; - } dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, @@ -1178,7 +1175,8 @@ static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id, return &enc1->base; } -static struct dce_hwseq *dcn30_hwseq_create(struct dc_context *ctx) +struct dce_hwseq *dcn30_hwseq_create( + struct dc_context *ctx) { struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); @@ -1705,6 +1703,9 @@ bool dcn30_release_post_bldn_3dlut( return ret; } +#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) +#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) + static bool is_soc_bounding_box_valid(struct dc *dc) { uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; @@ -1855,7 +1856,7 @@ static struct pipe_ctx *dcn30_find_split_pipe( return pipe; } -noinline bool dcn30_internal_validate_bw( +static noinline bool dcn30_internal_validate_bw( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, @@ -1923,25 +1924,23 @@ noinline bool dcn30_internal_validate_bw( if (vlevel == context->bw_ctx.dml.soc.num_states) goto validate_fail; - if (!dc->config.enable_windowed_mpo_odm) { - for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; - struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; - if (!pipe->stream) - continue; + if (!pipe->stream) + continue; - /* We only support full screen mpo with ODM */ - if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled - && pipe->plane_state && mpo_pipe - && memcmp(&mpo_pipe->plane_res.scl_data.recout, - &pipe->plane_res.scl_data.recout, - sizeof(struct rect)) != 0) { - ASSERT(mpo_pipe->plane_state != pipe->plane_state); - goto validate_fail; - } - pipe_idx++; + /* We only support full screen mpo with ODM */ + if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled + && pipe->plane_state && mpo_pipe + && memcmp(&mpo_pipe->plane_res.scl_data.recout, + &pipe->plane_res.scl_data.recout, + sizeof(struct rect)) != 0) { + ASSERT(mpo_pipe->plane_state != pipe->plane_state); + goto validate_fail; } + pipe_idx++; } /* merge pipes if necessary */ @@ -2124,10 +2123,10 @@ static noinline void dcn30_calculate_wm_and_dlg_fp( int pipe_cnt, int vlevel) { - int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; int i, pipe_idx; - double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb]; - bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported; + double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; + bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != + dm_dram_clock_change_unsupported; if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) dcfclk = context->bw_ctx.dml.soc.min_dcfclk; @@ -2203,7 +2202,6 @@ static noinline void dcn30_calculate_wm_and_dlg_fp( context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us; context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us; } - context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; @@ -2321,9 +2319,7 @@ bool dcn30_validate_bandwidth(struct dc *dc, goto validate_out; } - DC_FP_START(); dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); - DC_FP_END(); BW_VAL_TRACE_END_WATERMARKS(); @@ -2637,8 +2633,6 @@ static bool dcn30_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - dc->caps.hdmi_frl_pcon_support = true; - /* read VBIOS LTTPR caps */ { if (ctx->dc_bios->funcs->get_lttpr_caps) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h index b92e4cc023..b754b89bea 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h @@ -55,13 +55,6 @@ unsigned int dcn30_calc_max_scaled_time( bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate); -bool dcn30_internal_validate_bw( - struct dc *dc, - struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int *pipe_cnt_out, - int *vlevel_out, - bool fast_validate); void dcn30_calculate_wm_and_dlg( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c index 14bc44b1f8..8cfd181b4d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c @@ -43,11 +43,10 @@ vpg3->base.ctx -void vpg3_update_generic_info_packet( +static void vpg3_update_generic_info_packet( struct vpg *vpg, uint32_t packet_index, - const struct dc_info_packet *info_packet, - bool immediate_update) + const struct dc_info_packet *info_packet) { struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg); uint32_t i; @@ -107,138 +106,69 @@ void vpg3_update_generic_info_packet( /* atomically update double-buffered GENERIC0 registers in immediate mode * (update at next block_update when block_update_lock == 0). */ - if (immediate_update) { - switch (packet_index) { - case 0: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC0_IMMEDIATE_UPDATE, 1); - break; - case 1: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC1_IMMEDIATE_UPDATE, 1); - break; - case 2: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC2_IMMEDIATE_UPDATE, 1); - break; - case 3: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC3_IMMEDIATE_UPDATE, 1); - break; - case 4: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC4_IMMEDIATE_UPDATE, 1); - break; - case 5: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC5_IMMEDIATE_UPDATE, 1); - break; - case 6: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC6_IMMEDIATE_UPDATE, 1); - break; - case 7: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC7_IMMEDIATE_UPDATE, 1); - break; - case 8: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC8_IMMEDIATE_UPDATE, 1); - break; - case 9: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC9_IMMEDIATE_UPDATE, 1); - break; - case 10: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC10_IMMEDIATE_UPDATE, 1); - break; - case 11: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC11_IMMEDIATE_UPDATE, 1); - break; - case 12: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC12_IMMEDIATE_UPDATE, 1); - break; - case 13: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC13_IMMEDIATE_UPDATE, 1); - break; - case 14: - REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, - VPG_GENERIC14_IMMEDIATE_UPDATE, 1); - break; - default: - break; - } - } else { - switch (packet_index) { - case 0: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC0_FRAME_UPDATE, 1); - break; - case 1: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC1_FRAME_UPDATE, 1); - break; - case 2: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC2_FRAME_UPDATE, 1); - break; - case 3: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC3_FRAME_UPDATE, 1); - break; - case 4: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC4_FRAME_UPDATE, 1); - break; - case 5: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC5_FRAME_UPDATE, 1); - break; - case 6: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC6_FRAME_UPDATE, 1); - break; - case 7: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC7_FRAME_UPDATE, 1); - break; - case 8: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC8_FRAME_UPDATE, 1); - break; - case 9: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC9_FRAME_UPDATE, 1); - break; - case 10: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC10_FRAME_UPDATE, 1); - break; - case 11: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC11_FRAME_UPDATE, 1); - break; - case 12: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC12_FRAME_UPDATE, 1); - break; - case 13: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC13_FRAME_UPDATE, 1); - break; - case 14: - REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, - VPG_GENERIC14_FRAME_UPDATE, 1); - break; - - default: - break; - } - + switch (packet_index) { + case 0: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC0_IMMEDIATE_UPDATE, 1); + break; + case 1: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC1_IMMEDIATE_UPDATE, 1); + break; + case 2: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC2_IMMEDIATE_UPDATE, 1); + break; + case 3: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC3_IMMEDIATE_UPDATE, 1); + break; + case 4: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC4_IMMEDIATE_UPDATE, 1); + break; + case 5: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC5_IMMEDIATE_UPDATE, 1); + break; + case 6: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC6_IMMEDIATE_UPDATE, 1); + break; + case 7: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC7_IMMEDIATE_UPDATE, 1); + break; + case 8: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC8_IMMEDIATE_UPDATE, 1); + break; + case 9: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC9_IMMEDIATE_UPDATE, 1); + break; + case 10: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC10_IMMEDIATE_UPDATE, 1); + break; + case 11: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC11_IMMEDIATE_UPDATE, 1); + break; + case 12: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC12_IMMEDIATE_UPDATE, 1); + break; + case 13: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC13_IMMEDIATE_UPDATE, 1); + break; + case 14: + REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, + VPG_GENERIC14_IMMEDIATE_UPDATE, 1); + break; + default: + break; } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h index ed9a5549c3..6161e9e663 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h @@ -138,14 +138,7 @@ struct vpg_funcs { void (*update_generic_info_packet)( struct vpg *vpg, uint32_t packet_index, - const struct dc_info_packet *info_packet, - bool immediate_update); - - void (*vpg_poweron)( - struct vpg *vpg); - - void (*vpg_powerdown)( - struct vpg *vpg); + const struct dc_info_packet *info_packet); }; struct vpg { @@ -161,12 +154,6 @@ struct dcn30_vpg { const struct dcn30_vpg_mask *vpg_mask; }; -void vpg3_update_generic_info_packet( - struct vpg *vpg, - uint32_t packet_index, - const struct dc_info_packet *info_packet, - bool immediate_update); - void vpg3_construct(struct dcn30_vpg *vpg3, struct dc_context *ctx, uint32_t inst, diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile index 7aa628c219..09264716d1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn301/Makefile @@ -13,6 +13,32 @@ DCN301 = dcn301_init.o dcn301_resource.o dcn301_dccg.o \ dcn301_dio_link_encoder.o dcn301_hwseq.o dcn301_panel_cntl.o dcn301_hubbub.o +ifdef CONFIG_X86 +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -msse +endif + +ifdef CONFIG_PPC64 +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o := -mhard-float -maltivec +endif + +ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mhard-float +endif + +ifdef CONFIG_X86 +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -mpreferred-stack-boundary=4 +else +CFLAGS_$(AMDDALPATH)/dc/dcn301/dcn301_resource.o += -msse2 +endif +endif + AMD_DAL_DCN301 = $(addprefix $(AMDDALPATH)/dc/dcn301/,$(DCN301)) AMD_DISPLAY_FILES += $(AMD_DAL_DCN301) diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c index 3d42a1a337..e85b695f23 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -30,8 +30,6 @@ #include "dcn30/dcn30_hwseq.h" #include "dcn301_hwseq.h" -#include "dcn301_init.h" - static const struct hw_sequencer_funcs dcn301_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c index ad0df1a72a..736bda30ab 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_panel_cntl.c @@ -93,7 +93,7 @@ static unsigned int dcn301_get_16_bit_backlight_from_pwm(struct panel_cntl *pane return (uint32_t)(current_backlight); } -static uint32_t dcn301_panel_cntl_hw_init(struct panel_cntl *panel_cntl) +uint32_t dcn301_panel_cntl_hw_init(struct panel_cntl *panel_cntl) { struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); uint32_t value; @@ -147,7 +147,7 @@ static uint32_t dcn301_panel_cntl_hw_init(struct panel_cntl *panel_cntl) return current_backlight; } -static void dcn301_panel_cntl_destroy(struct panel_cntl **panel_cntl) +void dcn301_panel_cntl_destroy(struct panel_cntl **panel_cntl) { struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(*panel_cntl); @@ -155,7 +155,7 @@ static void dcn301_panel_cntl_destroy(struct panel_cntl **panel_cntl) *panel_cntl = NULL; } -static bool dcn301_is_panel_backlight_on(struct panel_cntl *panel_cntl) +bool dcn301_is_panel_backlight_on(struct panel_cntl *panel_cntl) { struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); uint32_t value; @@ -165,7 +165,7 @@ static bool dcn301_is_panel_backlight_on(struct panel_cntl *panel_cntl) return value; } -static bool dcn301_is_panel_powered_on(struct panel_cntl *panel_cntl) +bool dcn301_is_panel_powered_on(struct panel_cntl *panel_cntl) { struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); uint32_t pwr_seq_state, dig_on, dig_on_ovrd; @@ -177,7 +177,7 @@ static bool dcn301_is_panel_powered_on(struct panel_cntl *panel_cntl) return (pwr_seq_state == 1) || (dig_on == 1 && dig_on_ovrd == 1); } -static void dcn301_store_backlight_level(struct panel_cntl *panel_cntl) +void dcn301_store_backlight_level(struct panel_cntl *panel_cntl) { struct dcn301_panel_cntl *dcn301_panel_cntl = TO_DCN301_PANEL_CNTL(panel_cntl); diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c index 5d9637b074..dea358b017 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c @@ -82,7 +82,6 @@ #include "dce/dce_i2c.h" #include "dml/dcn30/display_mode_vba_30.h" -#include "dml/dcn301/dcn301_fpu.h" #include "vm_helper.h" #include "dcn20/dcn20_vmid.h" #include "amdgpu_socbb.h" @@ -92,6 +91,184 @@ #define DC_LOGGER_INIT(logger) +struct _vcs_dpi_ip_params_st dcn3_01_ip = { + .odm_capable = 1, + .gpuvm_enable = 1, + .hostvm_enable = 1, + .gpuvm_max_page_table_levels = 1, + .hostvm_max_page_table_levels = 2, + .hostvm_cached_page_table_levels = 0, + .pte_group_size_bytes = 2048, + .num_dsc = 3, + .rob_buffer_size_kbytes = 184, + .det_buffer_size_kbytes = 184, + .dpte_buffer_size_in_pte_reqs_luma = 64, + .dpte_buffer_size_in_pte_reqs_chroma = 32, + .pde_proc_buffer_size_64k_reqs = 48, + .dpp_output_buffer_pixels = 2560, + .opp_output_buffer_lines = 1, + .pixel_chunk_size_kbytes = 8, + .meta_chunk_size_kbytes = 2, + .writeback_chunk_size_kbytes = 8, + .line_buffer_size_bits = 789504, + .is_line_buffer_bpp_fixed = 0, // ? + .line_buffer_fixed_bpp = 48, // ? + .dcc_supported = true, + .writeback_interface_buffer_size_kbytes = 90, + .writeback_line_buffer_buffer_size = 656640, + .max_line_buffer_lines = 12, + .writeback_luma_buffer_size_kbytes = 12, // writeback_line_buffer_buffer_size = 656640 + .writeback_chroma_buffer_size_kbytes = 8, + .writeback_chroma_line_buffer_width_pixels = 4, + .writeback_max_hscl_ratio = 1, + .writeback_max_vscl_ratio = 1, + .writeback_min_hscl_ratio = 1, + .writeback_min_vscl_ratio = 1, + .writeback_max_hscl_taps = 1, + .writeback_max_vscl_taps = 1, + .writeback_line_buffer_luma_buffer_size = 0, + .writeback_line_buffer_chroma_buffer_size = 14643, + .cursor_buffer_size = 8, + .cursor_chunk_size = 2, + .max_num_otg = 4, + .max_num_dpp = 4, + .max_num_wb = 1, + .max_dchub_pscl_bw_pix_per_clk = 4, + .max_pscl_lb_bw_pix_per_clk = 2, + .max_lb_vscl_bw_pix_per_clk = 4, + .max_vscl_hscl_bw_pix_per_clk = 4, + .max_hscl_ratio = 6, + .max_vscl_ratio = 6, + .hscl_mults = 4, + .vscl_mults = 4, + .max_hscl_taps = 8, + .max_vscl_taps = 8, + .dispclk_ramp_margin_percent = 1, + .underscan_factor = 1.11, + .min_vblank_lines = 32, + .dppclk_delay_subtotal = 46, + .dynamic_metadata_vm_enabled = true, + .dppclk_delay_scl_lb_only = 16, + .dppclk_delay_scl = 50, + .dppclk_delay_cnvc_formatter = 27, + .dppclk_delay_cnvc_cursor = 6, + .dispclk_delay_subtotal = 119, + .dcfclk_cstate_latency = 5.2, // SRExitTime + .max_inter_dcn_tile_repeaters = 8, + .max_num_hdmi_frl_outputs = 0, + .odm_combine_4to1_supported = true, + + .xfc_supported = false, + .xfc_fill_bw_overhead_percent = 10.0, + .xfc_fill_constant_bytes = 0, + .gfx7_compat_tiling_supported = 0, + .number_of_cursors = 1, +}; + +struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc = { + .clock_limits = { + { + .state = 0, + .dram_speed_mts = 2400.0, + .fabricclk_mhz = 600, + .socclk_mhz = 278.0, + .dcfclk_mhz = 400.0, + .dscclk_mhz = 206.0, + .dppclk_mhz = 1015.0, + .dispclk_mhz = 1015.0, + .phyclk_mhz = 600.0, + }, + { + .state = 1, + .dram_speed_mts = 2400.0, + .fabricclk_mhz = 688, + .socclk_mhz = 278.0, + .dcfclk_mhz = 400.0, + .dscclk_mhz = 206.0, + .dppclk_mhz = 1015.0, + .dispclk_mhz = 1015.0, + .phyclk_mhz = 600.0, + }, + { + .state = 2, + .dram_speed_mts = 4267.0, + .fabricclk_mhz = 1067, + .socclk_mhz = 278.0, + .dcfclk_mhz = 608.0, + .dscclk_mhz = 296.0, + .dppclk_mhz = 1015.0, + .dispclk_mhz = 1015.0, + .phyclk_mhz = 810.0, + }, + + { + .state = 3, + .dram_speed_mts = 4267.0, + .fabricclk_mhz = 1067, + .socclk_mhz = 715.0, + .dcfclk_mhz = 676.0, + .dscclk_mhz = 338.0, + .dppclk_mhz = 1015.0, + .dispclk_mhz = 1015.0, + .phyclk_mhz = 810.0, + }, + + { + .state = 4, + .dram_speed_mts = 4267.0, + .fabricclk_mhz = 1067, + .socclk_mhz = 953.0, + .dcfclk_mhz = 810.0, + .dscclk_mhz = 338.0, + .dppclk_mhz = 1015.0, + .dispclk_mhz = 1015.0, + .phyclk_mhz = 810.0, + }, + }, + + .sr_exit_time_us = 9.0, + .sr_enter_plus_exit_time_us = 11.0, + .urgent_latency_us = 4.0, + .urgent_latency_pixel_data_only_us = 4.0, + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, + .urgent_latency_vm_data_only_us = 4.0, + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 80.0, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 75.0, + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, + .max_avg_sdp_bw_use_normal_percent = 60.0, + .max_avg_dram_bw_use_normal_percent = 60.0, + .writeback_latency_us = 12.0, + .max_request_size_bytes = 256, + .dram_channel_width_bytes = 4, + .fabric_datapath_to_dcn_data_return_bytes = 32, + .dcn_downspread_percent = 0.5, + .downspread_percent = 0.38, + .dram_page_open_time_ns = 50.0, + .dram_rw_turnaround_time_ns = 17.5, + .dram_return_buffer_per_channel_bytes = 8192, + .round_trip_ping_latency_dcfclk_cycles = 191, + .urgent_out_of_order_return_per_channel_bytes = 4096, + .channel_interleave_bytes = 256, + .num_banks = 8, + .num_chans = 4, + .gpuvm_min_page_size_bytes = 4096, + .hostvm_min_page_size_bytes = 4096, + .dram_clock_change_latency_us = 23.84, + .writeback_dram_clock_change_latency_us = 23.0, + .return_bus_width_bytes = 64, + .dispclk_dppclk_vco_speed_mhz = 3550, + .xfc_bus_transport_time_us = 20, // ? + .xfc_xbuf_latency_tolerance_us = 4, // ? + .use_urgent_burst_bw = 1, // ? + .num_states = 5, + .do_urgent_latency_adjustment = false, + .urgent_latency_adjustment_fabric_clock_component_us = 0, + .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, +}; + enum dcn301_clk_src_array_id { DCN301_CLK_SRC_PLL0, DCN301_CLK_SRC_PLL1, @@ -656,7 +833,7 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = true, .nv12 = true, .fp16 = true, - .p010 = true, + .p010 = false, .ayuv = false, }, @@ -717,13 +894,15 @@ static const struct dc_debug_options debug_defaults_diags = { .use_max_lb = false, }; -static void dcn301_dpp_destroy(struct dpp **dpp) +void dcn301_dpp_destroy(struct dpp **dpp) { kfree(TO_DCN20_DPP(*dpp)); *dpp = NULL; } -static struct dpp *dcn301_dpp_create(struct dc_context *ctx, uint32_t inst) +struct dpp *dcn301_dpp_create( + struct dc_context *ctx, + uint32_t inst) { struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); @@ -739,8 +918,8 @@ static struct dpp *dcn301_dpp_create(struct dc_context *ctx, uint32_t inst) kfree(dpp); return NULL; } -static struct output_pixel_processor *dcn301_opp_create(struct dc_context *ctx, - uint32_t inst) +struct output_pixel_processor *dcn301_opp_create( + struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); @@ -755,7 +934,9 @@ static struct output_pixel_processor *dcn301_opp_create(struct dc_context *ctx, return &opp->base; } -static struct dce_aux *dcn301_aux_engine_create(struct dc_context *ctx, uint32_t inst) +struct dce_aux *dcn301_aux_engine_create( + struct dc_context *ctx, + uint32_t inst) { struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); @@ -789,7 +970,9 @@ static const struct dce_i2c_mask i2c_masks = { I2C_COMMON_MASK_SH_LIST_DCN2(_MASK) }; -static struct dce_i2c_hw *dcn301_i2c_hw_create(struct dc_context *ctx, uint32_t inst) +struct dce_i2c_hw *dcn301_i2c_hw_create( + struct dc_context *ctx, + uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); @@ -823,7 +1006,7 @@ static struct mpc *dcn301_mpc_create( return &mpc30->base; } -static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx) +struct hubbub *dcn301_hubbub_create(struct dc_context *ctx) { int i; @@ -854,8 +1037,9 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx) return &hubbub3->base; } -static struct timing_generator *dcn301_timing_generator_create( - struct dc_context *ctx, uint32_t instance) +struct timing_generator *dcn301_timing_generator_create( + struct dc_context *ctx, + uint32_t instance) { struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL); @@ -887,7 +1071,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_TPS4_CAPABLE = true }; -static struct link_encoder *dcn301_link_encoder_create( +struct link_encoder *dcn301_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = @@ -908,7 +1092,7 @@ static struct link_encoder *dcn301_link_encoder_create( return &enc20->enc10.base; } -static struct panel_cntl *dcn301_panel_cntl_create(const struct panel_cntl_init_data *init_data) +struct panel_cntl *dcn301_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn301_panel_cntl *panel_cntl = kzalloc(sizeof(struct dcn301_panel_cntl), GFP_KERNEL); @@ -990,8 +1174,9 @@ static struct afmt *dcn301_afmt_create( return &afmt3->base; } -static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id, - struct dc_context *ctx) +struct stream_encoder *dcn301_stream_encoder_create( + enum engine_id eng_id, + struct dc_context *ctx) { struct dcn10_stream_encoder *enc1; struct vpg *vpg; @@ -1010,12 +1195,8 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id vpg = dcn301_vpg_create(ctx, vpg_inst); afmt = dcn301_afmt_create(ctx, afmt_inst); - if (!enc1 || !vpg || !afmt) { - kfree(enc1); - kfree(vpg); - kfree(afmt); + if (!enc1 || !vpg || !afmt) return NULL; - } dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, @@ -1025,7 +1206,8 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id return &enc1->base; } -static struct dce_hwseq *dcn301_hwseq_create(struct dc_context *ctx) +struct dce_hwseq *dcn301_hwseq_create( + struct dc_context *ctx) { struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); @@ -1173,7 +1355,9 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool) dcn_dccg_destroy(&pool->base.dccg); } -static struct hubp *dcn301_hubp_create(struct dc_context *ctx, uint32_t inst) +struct hubp *dcn301_hubp_create( + struct dc_context *ctx, + uint32_t inst) { struct dcn20_hubp *hubp2 = kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); @@ -1190,7 +1374,7 @@ static struct hubp *dcn301_hubp_create(struct dc_context *ctx, uint32_t inst) return NULL; } -static bool dcn301_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) +bool dcn301_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) { int i; uint32_t pipe_count = pool->res_cap->num_dwb; @@ -1215,7 +1399,7 @@ static bool dcn301_dwbc_create(struct dc_context *ctx, struct resource_pool *poo return true; } -static bool dcn301_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) +bool dcn301_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) { int i; uint32_t pipe_count = pool->res_cap->num_dwb; @@ -1292,6 +1476,8 @@ static struct dc_cap_funcs cap_funcs = { .get_dcc_compression_cap = dcn20_get_dcc_compression_cap }; +#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) +#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) static bool is_soc_bounding_box_valid(struct dc *dc) { @@ -1318,24 +1504,26 @@ static bool init_soc_bounding_box(struct dc *dc, loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; loaded_ip->max_num_dpp = pool->base.pipe_count; - DC_FP_START(); dcn20_patch_bounding_box(dc, loaded_bb); - DC_FP_END(); if (dc->ctx->dc_bios->funcs->get_soc_bb_info) { struct bp_soc_bb_info bb_info = {0}; if (dc->ctx->dc_bios->funcs->get_soc_bb_info(dc->ctx->dc_bios, &bb_info) == BP_RESULT_OK) { - DC_FP_START(); - dcn301_fpu_init_soc_bounding_box(bb_info); - DC_FP_END(); + if (bb_info.dram_clock_change_latency_100ns > 0) + dcn3_01_soc.dram_clock_change_latency_us = bb_info.dram_clock_change_latency_100ns * 10; + + if (bb_info.dram_sr_enter_exit_latency_100ns > 0) + dcn3_01_soc.sr_enter_plus_exit_time_us = bb_info.dram_sr_enter_exit_latency_100ns * 10; + + if (bb_info.dram_sr_exit_latency_100ns > 0) + dcn3_01_soc.sr_exit_time_us = bb_info.dram_sr_exit_latency_100ns * 10; } } return true; } - static void set_wm_ranges( struct pp_smu_funcs *pp_smu, struct _vcs_dpi_soc_bounding_box_st *loaded_bb) @@ -1358,9 +1546,9 @@ static void set_wm_ranges( ranges.reader_wm_sets[i].wm_inst = i; ranges.reader_wm_sets[i].min_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN; ranges.reader_wm_sets[i].max_drain_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; - DC_FP_START(); - dcn301_fpu_set_wm_ranges(i, &ranges, loaded_bb); - DC_FP_END(); + ranges.reader_wm_sets[i].min_fill_clk_mhz = (i > 0) ? (loaded_bb->clock_limits[i - 1].dram_speed_mts / 16) + 1 : 0; + ranges.reader_wm_sets[i].max_fill_clk_mhz = loaded_bb->clock_limits[i].dram_speed_mts / 16; + ranges.num_reader_wm_sets = i + 1; } @@ -1380,15 +1568,152 @@ static void set_wm_ranges( pp_smu->nv_funcs.set_wm_ranges(&pp_smu->nv_funcs.pp_smu, &ranges); } +static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) +{ + struct dcn301_resource_pool *pool = TO_DCN301_RES_POOL(dc->res_pool); + struct clk_limit_table *clk_table = &bw_params->clk_table; + struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; + unsigned int i, closest_clk_lvl; + int j; + + // Default clock levels are used for diags, which may lead to overclocking. + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { + dcn3_01_ip.max_num_otg = pool->base.res_cap->num_timing_generator; + dcn3_01_ip.max_num_dpp = pool->base.pipe_count; + dcn3_01_soc.num_chans = bw_params->num_channels; + + ASSERT(clk_table->num_entries); + for (i = 0; i < clk_table->num_entries; i++) { + /* loop backwards*/ + for (closest_clk_lvl = 0, j = dcn3_01_soc.num_states - 1; j >= 0; j--) { + if ((unsigned int) dcn3_01_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { + closest_clk_lvl = j; + break; + } + } + + clock_limits[i].state = i; + clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; + clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; + clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; + clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; + + clock_limits[i].dispclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dispclk_mhz; + clock_limits[i].dppclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dppclk_mhz; + clock_limits[i].dram_bw_per_chan_gbps = dcn3_01_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; + clock_limits[i].dscclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dscclk_mhz; + clock_limits[i].dtbclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; + clock_limits[i].phyclk_d18_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; + clock_limits[i].phyclk_mhz = dcn3_01_soc.clock_limits[closest_clk_lvl].phyclk_mhz; + } + for (i = 0; i < clk_table->num_entries; i++) + dcn3_01_soc.clock_limits[i] = clock_limits[i]; + if (clk_table->num_entries) { + dcn3_01_soc.num_states = clk_table->num_entries; + /* duplicate last level */ + dcn3_01_soc.clock_limits[dcn3_01_soc.num_states] = dcn3_01_soc.clock_limits[dcn3_01_soc.num_states - 1]; + dcn3_01_soc.clock_limits[dcn3_01_soc.num_states].state = dcn3_01_soc.num_states; + } + } + + dcn3_01_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; + dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; + + dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30); +} + +static void calculate_wm_set_for_vlevel( + int vlevel, + struct wm_range_table_entry *table_entry, + struct dcn_watermarks *wm_set, + struct display_mode_lib *dml, + display_e2e_pipe_params_st *pipes, + int pipe_cnt) +{ + double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us; + + ASSERT(vlevel < dml->soc.num_states); + /* only pipe 0 is read for voltage and dcf/soc clocks */ + pipes[0].clks_cfg.voltage = vlevel; + pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz; + pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz; + + dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us; + dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us; + dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us; + + wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000; + wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000; + wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000; + wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000; + wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000; + wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000; + wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000; + wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000; + dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached; + +} + static void dcn301_calculate_wm_and_dlg( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, int pipe_cnt, - int vlevel) + int vlevel_req) { - DC_FP_START(); - dcn301_calculate_wm_and_dlg_fp(dc, context, pipes, pipe_cnt, vlevel); - DC_FP_END(); + int i, pipe_idx; + int vlevel, vlevel_max; + struct wm_range_table_entry *table_entry; + struct clk_bw_params *bw_params = dc->clk_mgr->bw_params; + + ASSERT(bw_params); + + vlevel_max = bw_params->clk_table.num_entries - 1; + + /* WM Set D */ + table_entry = &bw_params->wm_table.entries[WM_D]; + if (table_entry->wm_type == WM_TYPE_RETRAINING) + vlevel = 0; + else + vlevel = vlevel_max; + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d, + &context->bw_ctx.dml, pipes, pipe_cnt); + /* WM Set C */ + table_entry = &bw_params->wm_table.entries[WM_C]; + vlevel = min(max(vlevel_req, 2), vlevel_max); + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, + &context->bw_ctx.dml, pipes, pipe_cnt); + /* WM Set B */ + table_entry = &bw_params->wm_table.entries[WM_B]; + vlevel = min(max(vlevel_req, 1), vlevel_max); + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, + &context->bw_ctx.dml, pipes, pipe_cnt); + + /* WM Set A */ + table_entry = &bw_params->wm_table.entries[WM_A]; + vlevel = min(vlevel_req, vlevel_max); + calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a, + &context->bw_ctx.dml, pipes, pipe_cnt); + + for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { + if (!context->res_ctx.pipe_ctx[i].stream) + continue; + + pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); + pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); + + if (dc->config.forced_clocks) { + pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; + pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; + } + if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000) + pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0; + if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000) + pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0; + + pipe_idx++; + } + + dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); } static struct resource_funcs dcn301_res_pool_funcs = { @@ -1449,7 +1774,9 @@ static bool dcn301_resource_construct( dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.extended_aux_timeout_support = true; +#ifdef CONFIG_DRM_AMD_DC_DMUB dc->caps.dmcub_support = true; +#endif /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; @@ -1485,23 +1812,6 @@ static bool dcn301_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - /* read VBIOS LTTPR caps */ - if (ctx->dc_bios->funcs->get_lttpr_caps) { - enum bp_result bp_query_result; - uint8_t is_vbios_lttpr_enable = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable); - dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable; - } - - if (ctx->dc_bios->funcs->get_lttpr_interop) { - enum bp_result bp_query_result; - uint8_t is_vbios_interop_enabled = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios, &is_vbios_interop_enabled); - dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled; - } - if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h index ae8672680c..17e4e91ff4 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.h @@ -32,9 +32,6 @@ struct dc; struct resource_pool; struct _vcs_dpi_display_pipe_params_st; -extern struct _vcs_dpi_ip_params_st dcn3_01_ip; -extern struct _vcs_dpi_soc_bounding_box_st dcn3_01_soc; - struct dcn301_resource_pool { struct resource_pool base; }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c index eb375f30f5..d88b9011c5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_init.c @@ -29,8 +29,6 @@ #include "dc.h" -#include "dcn302_init.h" - void dcn302_hw_sequencer_construct(struct dc *dc) { dcn30_hw_sequencer_construct(dc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c index 2e9cbfa766..2292bb8202 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c @@ -276,7 +276,7 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = true, .nv12 = true, .fp16 = true, - .p010 = true, + .p010 = false, .ayuv = false, }, .max_upscale_factor = { @@ -542,12 +542,8 @@ static struct stream_encoder *dcn302_stream_encoder_create(enum engine_id eng_id vpg = dcn302_vpg_create(ctx, vpg_inst); afmt = dcn302_afmt_create(ctx, afmt_inst); - if (!enc1 || !vpg || !afmt) { - kfree(enc1); - kfree(vpg); - kfree(afmt); + if (!enc1 || !vpg || !afmt) return NULL; - } dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id], &se_shift, &se_mask); @@ -1466,7 +1462,7 @@ static const struct dccg_mask dccg_mask = { }; #define abm_regs(id)\ - [id] = { ABM_DCN302_REG_LIST(id) } + [id] = { ABM_DCN301_REG_LIST(id) } static const struct dce_abm_registers abm_regs[] = { abm_regs(0), @@ -1557,24 +1553,6 @@ static bool dcn302_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - /* read VBIOS LTTPR caps */ - if (ctx->dc_bios->funcs->get_lttpr_caps) { - enum bp_result bp_query_result; - uint8_t is_vbios_lttpr_enable = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable); - dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable; - } - - if (ctx->dc_bios->funcs->get_lttpr_interop) { - enum bp_result bp_query_result; - uint8_t is_vbios_interop_enabled = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios, - &is_vbios_interop_enabled); - dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled; - } - if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h index 294bd757bc..a79c54bbc8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_dccg.h @@ -15,11 +15,7 @@ SR(DPPCLK_DTO_CTRL),\ DCCG_SRII(DTO_PARAM, DPPCLK, 0),\ DCCG_SRII(DTO_PARAM, DPPCLK, 1),\ - SR(REFCLK_CNTL),\ - SR(DISPCLK_FREQ_CHANGE_CNTL),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\ - DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1) - + SR(REFCLK_CNTL) #define DCCG_MASK_SH_LIST_DCN3_03(mask_sh) \ DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\ @@ -29,18 +25,6 @@ DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_PHASE, mask_sh),\ DCCG_SF(DPPCLK0_DTO_PARAM, DPPCLK0_DTO_MODULO, mask_sh),\ DCCG_SF(REFCLK_CNTL, REFCLK_CLOCK_EN, mask_sh),\ - DCCG_SF(REFCLK_CNTL, REFCLK_SRC_SEL, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_STEP_DELAY, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_STEP_SIZE, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_FREQ_RAMP_DONE, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_MAX_ERRDET_CYCLES, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_RESET, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_STATE, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DCCG_FIFO_ERRDET_OVR_EN, mask_sh),\ - DCCG_SF(DISPCLK_FREQ_CHANGE_CNTL, DISPCLK_CHG_FWD_CORR_DISABLE, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 0, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh) + DCCG_SF(REFCLK_CNTL, REFCLK_SRC_SEL, mask_sh) #endif //__DCN303_DCCG_H__ diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c index f499f8ab5e..aa5dbbade2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_init.c @@ -9,8 +9,6 @@ #include "dcn30/dcn30_init.h" #include "dc.h" -#include "dcn303_init.h" - void dcn303_hw_sequencer_construct(struct dc *dc) { dcn30_hw_sequencer_construct(dc); diff --git a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c index 2de687f64c..589ddab61c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c @@ -254,7 +254,7 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = true, .nv12 = true, .fp16 = true, - .p010 = true, + .p010 = false, .ayuv = false, }, .max_upscale_factor = { @@ -1344,20 +1344,6 @@ void dcn303_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param dcn3_03_soc.clock_limits[i].phyclk_d18_mhz = dcn3_03_soc.clock_limits[0].phyclk_d18_mhz; dcn3_03_soc.clock_limits[i].dscclk_mhz = dcn3_03_soc.clock_limits[0].dscclk_mhz; } - - // WA: patch strobe modes to compensate for DCN303 BW issue - if (dcn3_03_soc.num_chans <= 4) { - for (i = 0; i < dcn3_03_soc.num_states; i++) { - if (dcn3_03_soc.clock_limits[i].dram_speed_mts > 1700) - break; - - if (dcn3_03_soc.clock_limits[i].dram_speed_mts >= 1500) { - dcn3_03_soc.clock_limits[i].dcfclk_mhz = 100; - dcn3_03_soc.clock_limits[i].fabricclk_mhz = 100; - } - } - } - /* re-init DML with updated bb */ dml_init_instance(&dc->dml, &dcn3_03_soc, &dcn3_03_ip, DML_PROJECT_DCN30); if (dc->current_state) @@ -1408,7 +1394,7 @@ static const struct dccg_mask dccg_mask = { }; #define abm_regs(id)\ - [id] = { ABM_DCN302_REG_LIST(id) } + [id] = { ABM_DCN301_REG_LIST(id) } static const struct dce_abm_registers abm_regs[] = { abm_regs(0), @@ -1500,23 +1486,6 @@ static bool dcn303_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - /* read VBIOS LTTPR caps */ - if (ctx->dc_bios->funcs->get_lttpr_caps) { - enum bp_result bp_query_result; - uint8_t is_vbios_lttpr_enable = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable); - dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable; - } - - if (ctx->dc_bios->funcs->get_lttpr_interop) { - enum bp_result bp_query_result; - uint8_t is_vbios_interop_enabled = 0; - - bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios, &is_vbios_interop_enabled); - dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled; - } - if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; else diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile index d20e3b8ccc..4bab97acb1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn31/Makefile @@ -11,9 +11,7 @@ # Makefile for dcn31. DCN31 = dcn31_resource.o dcn31_hubbub.o dcn31_hwseq.o dcn31_init.o dcn31_hubp.o \ - dcn31_dccg.o dcn31_optc.o dcn31_dio_link_encoder.o dcn31_panel_cntl.o \ - dcn31_apg.o dcn31_hpo_dp_stream_encoder.o dcn31_hpo_dp_link_encoder.o \ - dcn31_afmt.o dcn31_vpg.o + dcn31_dccg.o dcn31_optc.o dcn31_dio_link_encoder.o dcn31_panel_cntl.o ifdef CONFIG_X86 CFLAGS_$(AMDDALPATH)/dc/dcn31/dcn31_resource.o := -msse diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index ea4f8e06b0..696c930771 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -26,7 +26,6 @@ #include "reg_helper.h" #include "core_types.h" #include "dcn31_dccg.h" -#include "dal_asic_id.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -43,358 +42,6 @@ #define DC_LOGGER \ dccg->ctx->logger -static void dccg31_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - if (dccg->ref_dppclk && req_dppclk) { - int ref_dppclk = dccg->ref_dppclk; - int modulo, phase; - - // phase / modulo = dpp pipe clk / dpp global clk - modulo = 0xff; // use FF at the end - phase = ((modulo * req_dppclk) + ref_dppclk - 1) / ref_dppclk; - - if (phase > 0xff) { - ASSERT(false); - phase = 0xff; - } - - REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, - DPPCLK0_DTO_PHASE, phase, - DPPCLK0_DTO_MODULO, modulo); - REG_UPDATE(DPPCLK_DTO_CTRL, - DPPCLK_DTO_ENABLE[dpp_inst], 1); - } else { - //DTO must be enabled to generate a 0Hz clock output - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpp) { - REG_UPDATE(DPPCLK_DTO_CTRL, - DPPCLK_DTO_ENABLE[dpp_inst], 1); - REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0, - DPPCLK0_DTO_PHASE, 0, - DPPCLK0_DTO_MODULO, 1); - } else { - REG_UPDATE(DPPCLK_DTO_CTRL, - DPPCLK_DTO_ENABLE[dpp_inst], 0); - } - } - dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; -} - -static enum phyd32clk_clock_source get_phy_mux_symclk( - struct dcn_dccg *dccg_dcn, - enum phyd32clk_clock_source src) -{ - if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { - if (src == PHYD32CLKC) - src = PHYD32CLKF; - if (src == PHYD32CLKD) - src = PHYD32CLKG; - } - return src; -} - -static void dccg31_enable_dpstreamclk(struct dccg *dccg, int otg_inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - /* enabled to select one of the DTBCLKs for pipe */ - switch (otg_inst) { - case 0: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE0_EN, 1); - break; - case 1: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE1_EN, 1); - break; - case 2: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE2_EN, 1); - break; - case 3: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE3_EN, 1); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - DPSTREAMCLK_ROOT_GATE_DISABLE, 1); -} - -static void dccg31_disable_dpstreamclk(struct dccg *dccg, int otg_inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - DPSTREAMCLK_ROOT_GATE_DISABLE, 0); - - switch (otg_inst) { - case 0: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE0_EN, 0); - break; - case 1: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE1_EN, 0); - break; - case 2: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE2_EN, 0); - break; - case 3: - REG_UPDATE(DPSTREAMCLK_CNTL, - DPSTREAMCLK_PIPE3_EN, 0); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -void dccg31_set_dpstreamclk( - struct dccg *dccg, - enum hdmistreamclk_source src, - int otg_inst) -{ - if (src == REFCLK) - dccg31_disable_dpstreamclk(dccg, otg_inst); - else - dccg31_enable_dpstreamclk(dccg, otg_inst); -} - -void dccg31_enable_symclk32_se( - struct dccg *dccg, - int hpo_se_inst, - enum phyd32clk_clock_source phyd32clk) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); - - /* select one of the PHYD32CLKs as the source for symclk32_se */ - switch (hpo_se_inst) { - case 0: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE0_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE0_SRC_SEL, phyd32clk, - SYMCLK32_SE0_EN, 1); - break; - case 1: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE1_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE1_SRC_SEL, phyd32clk, - SYMCLK32_SE1_EN, 1); - break; - case 2: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE2_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE2_SRC_SEL, phyd32clk, - SYMCLK32_SE2_EN, 1); - break; - case 3: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE3_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE3_SRC_SEL, phyd32clk, - SYMCLK32_SE3_EN, 1); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -void dccg31_disable_symclk32_se( - struct dccg *dccg, - int hpo_se_inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - /* set refclk as the source for symclk32_se */ - switch (hpo_se_inst) { - case 0: - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE0_SRC_SEL, 0, - SYMCLK32_SE0_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE0_GATE_DISABLE, 0); - break; - case 1: - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE1_SRC_SEL, 0, - SYMCLK32_SE1_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE1_GATE_DISABLE, 0); - break; - case 2: - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE2_SRC_SEL, 0, - SYMCLK32_SE2_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE2_GATE_DISABLE, 0); - break; - case 3: - REG_UPDATE_2(SYMCLK32_SE_CNTL, - SYMCLK32_SE3_SRC_SEL, 0, - SYMCLK32_SE3_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_SE3_GATE_DISABLE, 0); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -void dccg31_enable_symclk32_le( - struct dccg *dccg, - int hpo_le_inst, - enum phyd32clk_clock_source phyd32clk) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - phyd32clk = get_phy_mux_symclk(dccg_dcn, phyd32clk); - - /* select one of the PHYD32CLKs as the source for symclk32_le */ - switch (hpo_le_inst) { - case 0: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_LE0_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_LE_CNTL, - SYMCLK32_LE0_SRC_SEL, phyd32clk, - SYMCLK32_LE0_EN, 1); - break; - case 1: - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_LE1_GATE_DISABLE, 1); - REG_UPDATE_2(SYMCLK32_LE_CNTL, - SYMCLK32_LE1_SRC_SEL, phyd32clk, - SYMCLK32_LE1_EN, 1); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -void dccg31_disable_symclk32_le( - struct dccg *dccg, - int hpo_le_inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - /* set refclk as the source for symclk32_le */ - switch (hpo_le_inst) { - case 0: - REG_UPDATE_2(SYMCLK32_LE_CNTL, - SYMCLK32_LE0_SRC_SEL, 0, - SYMCLK32_LE0_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_LE0_GATE_DISABLE, 0); - break; - case 1: - REG_UPDATE_2(SYMCLK32_LE_CNTL, - SYMCLK32_LE1_SRC_SEL, 0, - SYMCLK32_LE1_EN, 0); - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) - REG_UPDATE(DCCG_GATE_DISABLE_CNTL3, - SYMCLK32_ROOT_LE1_GATE_DISABLE, 0); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -static void dccg31_disable_dscclk(struct dccg *dccg, int inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) - return; - //DTO must be enabled to generate a 0 Hz clock output - switch (inst) { - case 0: - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK0_DTO_ENABLE, 1); - REG_UPDATE_2(DSCCLK0_DTO_PARAM, - DSCCLK0_DTO_PHASE, 0, - DSCCLK0_DTO_MODULO, 1); - break; - case 1: - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK1_DTO_ENABLE, 1); - REG_UPDATE_2(DSCCLK1_DTO_PARAM, - DSCCLK1_DTO_PHASE, 0, - DSCCLK1_DTO_MODULO, 1); - break; - case 2: - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK2_DTO_ENABLE, 1); - REG_UPDATE_2(DSCCLK2_DTO_PARAM, - DSCCLK2_DTO_PHASE, 0, - DSCCLK2_DTO_MODULO, 1); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - -static void dccg31_enable_dscclk(struct dccg *dccg, int inst) -{ - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc) - return; - //Disable DTO - switch (inst) { - case 0: - REG_UPDATE_2(DSCCLK0_DTO_PARAM, - DSCCLK0_DTO_PHASE, 0, - DSCCLK0_DTO_MODULO, 0); - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK0_DTO_ENABLE, 0); - break; - case 1: - REG_UPDATE_2(DSCCLK1_DTO_PARAM, - DSCCLK1_DTO_PHASE, 0, - DSCCLK1_DTO_MODULO, 0); - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK1_DTO_ENABLE, 0); - break; - case 2: - REG_UPDATE_2(DSCCLK2_DTO_PARAM, - DSCCLK2_DTO_PHASE, 0, - DSCCLK2_DTO_MODULO, 0); - REG_UPDATE(DSCCLK_DTO_CTRL, - DSCCLK2_DTO_ENABLE, 0); - break; - default: - BREAK_TO_DEBUGGER(); - return; - } -} - void dccg31_set_physymclk( struct dccg *dccg, int phy_inst, @@ -462,7 +109,7 @@ void dccg31_set_physymclk( } /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ -static void dccg31_set_dtbclk_dto( +void dccg31_set_dtbclk_dto( struct dccg *dccg, int dtbclk_inst, int req_dtbclk_khz, @@ -594,44 +241,16 @@ static void dccg31_set_dispclk_change_mode( void dccg31_init(struct dccg *dccg) { - /* Set HPO stream encoder to use refclk to avoid case where PHY is - * disabled and SYMCLK32 for HPO SE is sourced from PHYD32CLK which - * will cause DCN to hang. - */ - dccg31_disable_symclk32_se(dccg, 0); - dccg31_disable_symclk32_se(dccg, 1); - dccg31_disable_symclk32_se(dccg, 2); - dccg31_disable_symclk32_se(dccg, 3); - - if (dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le) { - dccg31_disable_symclk32_le(dccg, 0); - dccg31_disable_symclk32_le(dccg, 1); - } - - if (dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream) { - dccg31_disable_dpstreamclk(dccg, 0); - dccg31_disable_dpstreamclk(dccg, 1); - dccg31_disable_dpstreamclk(dccg, 2); - dccg31_disable_dpstreamclk(dccg, 3); - } - } static const struct dccg_funcs dccg31_funcs = { - .update_dpp_dto = dccg31_update_dpp_dto, + .update_dpp_dto = dccg2_update_dpp_dto, .get_dccg_ref_freq = dccg31_get_dccg_ref_freq, .dccg_init = dccg31_init, - .set_dpstreamclk = dccg31_set_dpstreamclk, - .enable_symclk32_se = dccg31_enable_symclk32_se, - .disable_symclk32_se = dccg31_disable_symclk32_se, - .enable_symclk32_le = dccg31_enable_symclk32_le, - .disable_symclk32_le = dccg31_disable_symclk32_le, .set_physymclk = dccg31_set_physymclk, .set_dtbclk_dto = dccg31_set_dtbclk_dto, .set_audio_dtbclk_dto = dccg31_set_audio_dtbclk_dto, .set_dispclk_change_mode = dccg31_set_dispclk_change_mode, - .disable_dsc = dccg31_disable_dscclk, - .enable_dsc = dccg31_enable_dscclk, }; struct dccg *dccg31_create( diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h index a013a32bba..706ad80ba8 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.h @@ -61,13 +61,7 @@ SR(DCCG_AUDIO_DTBCLK_DTO_MODULO),\ SR(DCCG_AUDIO_DTBCLK_DTO_PHASE),\ SR(DCCG_AUDIO_DTO_SOURCE),\ - SR(DENTIST_DISPCLK_CNTL),\ - SR(DSCCLK0_DTO_PARAM),\ - SR(DSCCLK1_DTO_PARAM),\ - SR(DSCCLK2_DTO_PARAM),\ - SR(DSCCLK_DTO_CTRL),\ - SR(DCCG_GATE_DISABLE_CNTL3),\ - SR(HDMISTREAMCLK0_DTO_PARAM) + SR(DENTIST_DISPCLK_CNTL) #define DCCG_MASK_SH_LIST_DCN31(mask_sh) \ @@ -125,26 +119,7 @@ DCCG_SFII(OTG, PIXEL_RATE_CNTL, DTBCLK_DTO, DIV, 3, mask_sh),\ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\ DCCG_SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\ - DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh), \ - DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_PHASE, mask_sh),\ - DCCG_SF(DSCCLK0_DTO_PARAM, DSCCLK0_DTO_MODULO, mask_sh),\ - DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_PHASE, mask_sh),\ - DCCG_SF(DSCCLK1_DTO_PARAM, DSCCLK1_DTO_MODULO, mask_sh),\ - DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_PHASE, mask_sh),\ - DCCG_SF(DSCCLK2_DTO_PARAM, DSCCLK2_DTO_MODULO, mask_sh),\ - DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK0_DTO_ENABLE, mask_sh),\ - DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK1_DTO_ENABLE, mask_sh),\ - DCCG_SF(DSCCLK_DTO_CTRL, DSCCLK2_DTO_ENABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_ROOT_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, DPSTREAMCLK_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE0_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE1_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE2_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_SE3_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE0_GATE_DISABLE, mask_sh),\ - DCCG_SF(DCCG_GATE_DISABLE_CNTL3, SYMCLK32_ROOT_LE1_GATE_DISABLE, mask_sh),\ - DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_PHASE, mask_sh),\ - DCCG_SF(HDMISTREAMCLK0_DTO_PARAM, HDMISTREAMCLK0_DTO_MODULO, mask_sh) + DCCG_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_MODE, mask_sh) struct dccg *dccg31_create( @@ -155,29 +130,6 @@ struct dccg *dccg31_create( void dccg31_init(struct dccg *dccg); -void dccg31_set_dpstreamclk( - struct dccg *dccg, - enum hdmistreamclk_source src, - int otg_inst); - -void dccg31_enable_symclk32_se( - struct dccg *dccg, - int hpo_se_inst, - enum phyd32clk_clock_source phyd32clk); - -void dccg31_disable_symclk32_se( - struct dccg *dccg, - int hpo_se_inst); - -void dccg31_enable_symclk32_le( - struct dccg *dccg, - int hpo_le_inst, - enum phyd32clk_clock_source phyd32clk); - -void dccg31_disable_symclk32_le( - struct dccg *dccg, - int hpo_le_inst); - void dccg31_set_physymclk( struct dccg *dccg, int phy_inst, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c index 8b9b1a5309..b0892443fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c @@ -67,68 +67,6 @@ #define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) #endif -static uint8_t phy_id_from_transmitter(enum transmitter t) -{ - uint8_t phy_id; - - switch (t) { - case TRANSMITTER_UNIPHY_A: - phy_id = 0; - break; - case TRANSMITTER_UNIPHY_B: - phy_id = 1; - break; - case TRANSMITTER_UNIPHY_C: - phy_id = 2; - break; - case TRANSMITTER_UNIPHY_D: - phy_id = 3; - break; - case TRANSMITTER_UNIPHY_E: - phy_id = 4; - break; - case TRANSMITTER_UNIPHY_F: - phy_id = 5; - break; - case TRANSMITTER_UNIPHY_G: - phy_id = 6; - break; - default: - phy_id = 0; - break; - } - return phy_id; -} - -static bool has_query_dp_alt(struct link_encoder *enc) -{ - struct dc_dmub_srv *dc_dmub_srv = enc->ctx->dmub_srv; - - /* Supports development firmware and firmware >= 4.0.11 */ - return dc_dmub_srv && - !(dc_dmub_srv->dmub->fw_version >= DMUB_FW_VERSION(4, 0, 0) && - dc_dmub_srv->dmub->fw_version <= DMUB_FW_VERSION(4, 0, 10)); -} - -static bool query_dp_alt_from_dmub(struct link_encoder *enc, - union dmub_rb_cmd *cmd) -{ - struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - struct dc_dmub_srv *dc_dmub_srv = enc->ctx->dmub_srv; - - memset(cmd, 0, sizeof(*cmd)); - cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS; - cmd->query_dp_alt.header.sub_type = - DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT; - cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data); - cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter); - - if (!dc_dmub_srv_cmd_with_reply_data(dc_dmub_srv, cmd)) - return false; - - return true; -} - void dcn31_link_encoder_set_dio_phy_mux( struct link_encoder *enc, enum encoder_type_select sel, @@ -203,7 +141,7 @@ void dcn31_link_encoder_set_dio_phy_mux( } } -static void enc31_hw_init(struct link_encoder *enc) +void enc31_hw_init(struct link_encoder *enc) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); @@ -387,10 +325,6 @@ void dcn31_link_encoder_construct( enc10->base.features.flags.bits.IS_HBR3_CAPABLE = bp_cap_info.DP_HBR3_EN; enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; - enc10->base.features.flags.bits.IS_DP2_CAPABLE = bp_cap_info.IS_DP2_CAPABLE; - enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; - enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; - enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN; enc10->base.features.flags.bits.DP_IS_USB_C = bp_cap_info.DP_IS_USB_C; } else { @@ -428,79 +362,19 @@ void dcn31_link_encoder_construct_minimal( SIGNAL_TYPE_EDP; } -/* DPIA equivalent of link_transmitter_control. */ -static bool link_dpia_control(struct dc_context *dc_ctx, - struct dmub_cmd_dig_dpia_control_data *dpia_control) -{ - union dmub_rb_cmd cmd; - struct dc_dmub_srv *dmub = dc_ctx->dmub_srv; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.dig1_dpia_control.header.type = DMUB_CMD__DPIA; - cmd.dig1_dpia_control.header.sub_type = - DMUB_CMD__DPIA_DIG1_DPIA_CONTROL; - cmd.dig1_dpia_control.header.payload_bytes = - sizeof(cmd.dig1_dpia_control) - - sizeof(cmd.dig1_dpia_control.header); - - cmd.dig1_dpia_control.dpia_control = *dpia_control; - - dc_dmub_srv_cmd_queue(dmub, &cmd); - dc_dmub_srv_cmd_execute(dmub); - dc_dmub_srv_wait_idle(dmub); - - return true; -} - -static void link_encoder_disable(struct dcn10_link_encoder *enc10) -{ - /* reset training complete */ - REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0); -} - void dcn31_link_encoder_enable_dp_output( struct link_encoder *enc, const struct dc_link_settings *link_settings, enum clock_source_id clock_source) { - struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - /* Enable transmitter and encoder. */ - if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) { + if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) { dcn20_link_encoder_enable_dp_output(enc, link_settings, clock_source); } else { - struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 }; - struct dc_link *link; - - link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine); - - enc1_configure_encoder(enc10, link_settings); - - dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE; - dpia_control.enc_id = enc->preferred_engine; - dpia_control.mode_laneset.digmode = 0; /* 0 for SST; 5 for MST */ - dpia_control.lanenum = (uint8_t)link_settings->lane_count; - dpia_control.symclk_10khz = link_settings->link_rate * - LINK_RATE_REF_FREQ_IN_KHZ / 10; - /* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin - * unused by DPIA. - */ - dpia_control.hpdsel = 6; - - if (link) { - dpia_control.dpia_id = link->ddc_hw_inst; - dpia_control.fec_rdy = dc_link_should_enable_fec(link); - } else { - DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__); - BREAK_TO_DEBUGGER(); - return; - } - - link_dpia_control(enc->ctx, &dpia_control); + /** @todo Handle transmitter with programmable mapping to link encoder. */ } } @@ -509,43 +383,14 @@ void dcn31_link_encoder_enable_dp_mst_output( const struct dc_link_settings *link_settings, enum clock_source_id clock_source) { - struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - /* Enable transmitter and encoder. */ - if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) { + if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) { dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source); } else { - struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 }; - struct dc_link *link; - - link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine); - - enc1_configure_encoder(enc10, link_settings); - - dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE; - dpia_control.enc_id = enc->preferred_engine; - dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */ - dpia_control.lanenum = (uint8_t)link_settings->lane_count; - dpia_control.symclk_10khz = link_settings->link_rate * - LINK_RATE_REF_FREQ_IN_KHZ / 10; - /* DIG_BE_CNTL.DIG_HPD_SELECT set to 5 (hpdsel - 1) to indicate HPD pin - * unused by DPIA. - */ - dpia_control.hpdsel = 6; - - if (link) { - dpia_control.dpia_id = link->ddc_hw_inst; - dpia_control.fec_rdy = dc_link_should_enable_fec(link); - } else { - DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__); - BREAK_TO_DEBUGGER(); - return; - } - - link_dpia_control(enc->ctx, &dpia_control); + /** @todo Handle transmitter with programmable mapping to link encoder. */ } } @@ -553,135 +398,71 @@ void dcn31_link_encoder_disable_output( struct link_encoder *enc, enum signal_type signal) { - struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - /* Disable transmitter and encoder. */ - if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) { + if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc->current_state, enc)) { dcn10_link_encoder_disable_output(enc, signal); } else { - struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 }; - struct dc_link *link; - - if (!dcn10_is_dig_enabled(enc)) - return; - - link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine); - - dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_DISABLE; - dpia_control.enc_id = enc->preferred_engine; - if (signal == SIGNAL_TYPE_DISPLAY_PORT) { - dpia_control.mode_laneset.digmode = 0; /* 0 for SST; 5 for MST */ - } else if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - dpia_control.mode_laneset.digmode = 5; /* 0 for SST; 5 for MST */ - } else { - DC_LOG_ERROR("%s: USB4 DPIA only supports DisplayPort.\n", __func__); - BREAK_TO_DEBUGGER(); - } - - if (link) { - dpia_control.dpia_id = link->ddc_hw_inst; - } else { - DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__); - BREAK_TO_DEBUGGER(); - return; - } - - link_dpia_control(enc->ctx, &dpia_control); - - link_encoder_disable(enc10); + /** @todo Handle transmitter with programmable mapping to link encoder. */ } } bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - union dmub_rb_cmd cmd; uint32_t dp_alt_mode_disable; + bool is_usb_c_alt_mode = false; - /* Only applicable to USB-C PHY. */ - if (!enc->features.flags.bits.DP_IS_USB_C) - return false; - - /* - * Use the new interface from DMCUB if available. - * Avoids hanging the RDCPSPIPE if DMCUB wasn't already running. - */ - if (has_query_dp_alt(enc)) { - if (!query_dp_alt_from_dmub(enc, &cmd)) - return false; - - return (cmd.query_dp_alt.data.is_dp_alt_disable == 0); - } - - /* Legacy path, avoid if possible. */ - if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { - REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, - &dp_alt_mode_disable); - } else { + if (enc->features.flags.bits.DP_IS_USB_C) { + if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { + // [Note] no need to check hw_internal_rev once phy mux selection is ready + REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); + } else { /* * B0 phys use a new set of registers to check whether alt mode is disabled. * if value == 1 alt mode is disabled, otherwise it is enabled. */ - if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) || - (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) || - (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { - REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, - &dp_alt_mode_disable); - } else { - REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, - &dp_alt_mode_disable); + if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) + || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) + || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { + REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); + } else { + // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready + REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); + } } + + is_usb_c_alt_mode = (dp_alt_mode_disable == 0); } - return (dp_alt_mode_disable == 0); + return is_usb_c_alt_mode; } -void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, struct dc_link_settings *link_settings) +void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, + struct dc_link_settings *link_settings) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - union dmub_rb_cmd cmd; uint32_t is_in_usb_c_dp4_mode = 0; dcn10_link_encoder_get_max_link_cap(enc, link_settings); - /* Take the link cap directly if not USB */ - if (!enc->features.flags.bits.DP_IS_USB_C) - return; - - /* - * Use the new interface from DMCUB if available. - * Avoids hanging the RDCPSPIPE if DMCUB wasn't already running. - */ - if (has_query_dp_alt(enc)) { - if (!query_dp_alt_from_dmub(enc, &cmd)) - return; - - if (cmd.query_dp_alt.data.is_usb && - cmd.query_dp_alt.data.is_dp4 == 0) - link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); - - return; - } - - /* Legacy path, avoid if possible. */ - if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { - REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, - &is_in_usb_c_dp4_mode); - } else { - if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) || - (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) || - (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { - REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, - &is_in_usb_c_dp4_mode); + /* in usb c dp2 mode, max lane count is 2 */ + if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) { + if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) { + // [Note] no need to check hw_internal_rev once phy mux selection is ready + REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); } else { - REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, - &is_in_usb_c_dp4_mode); + if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) + || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) + || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) { + REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); + } else { + REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); + } } + if (!is_in_usb_c_dp4_mode) + link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); } - - if (!is_in_usb_c_dp4_mode) - link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 4206ce5bf9..3afa1159a5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -48,9 +48,6 @@ #include "dc_link_dp.h" #include "inc/link_dpcd.h" #include "dcn10/dcn10_hw_sequencer.h" -#include "inc/link_enc_cfg.h" -#include "dcn30/dcn30_vpg.h" -#include "dce/dce_i2c_hw.h" #define DC_LOGGER_INIT(logger) @@ -66,45 +63,6 @@ #define FN(reg_name, field_name) \ hws->shifts->field_name, hws->masks->field_name -static void enable_memory_low_power(struct dc *dc) -{ - struct dce_hwseq *hws = dc->hwseq; - int i; - - if (dc->debug.enable_mem_low_power.bits.dmcu) { - // Force ERAM to shutdown if DMCU is not enabled - if (dc->debug.disable_dmcu || dc->config.disable_dmcu) { - REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3); - } - } - - // Set default OPTC memory power states - if (dc->debug.enable_mem_low_power.bits.optc) { - // Shutdown when unassigned and light sleep in VBLANK - REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1); - } - - if (dc->debug.enable_mem_low_power.bits.vga) { - // Power down VGA memory - REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1); - } - - if (dc->debug.enable_mem_low_power.bits.mpc) - dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc); - - - if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) { - // Power down VPGs - for (i = 0; i < dc->res_pool->stream_enc_count; i++) - dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg); -#if defined(CONFIG_DRM_AMD_DC_DCN) - for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) - dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg); -#endif - } - -} - void dcn31_init_hw(struct dc *dc) { struct abm **abms = dc->res_pool->multiple_abms; @@ -112,7 +70,8 @@ void dcn31_init_hw(struct dc *dc) struct dc_bios *dcb = dc->ctx->dc_bios; struct resource_pool *res_pool = dc->res_pool; uint32_t backlight = MAX_BACKLIGHT_LEVEL; - int i; + int i, j; + int edp_num; if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); @@ -147,7 +106,23 @@ void dcn31_init_hw(struct dc *dc) if (res_pool->dccg->funcs->dccg_init) res_pool->dccg->funcs->dccg_init(res_pool->dccg); - enable_memory_low_power(dc); + if (dc->debug.enable_mem_low_power.bits.dmcu) { + // Force ERAM to shutdown if DMCU is not enabled + if (dc->debug.disable_dmcu || dc->config.disable_dmcu) { + REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3); + } + } + + // Set default OPTC memory power states + if (dc->debug.enable_mem_low_power.bits.optc) { + // Shutdown when unassigned and light sleep in VBLANK + REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1); + } + + if (dc->debug.enable_mem_low_power.bits.vga) { + // Power down VGA memory + REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1); + } if (dc->ctx->dc_bios->fw_info_valid) { res_pool->ref_clocks.xtalin_clock_inKhz = @@ -181,9 +156,6 @@ void dcn31_init_hw(struct dc *dc) */ struct dc_link *link = dc->links[i]; - if (link->ep_type != DISPLAY_ENDPOINT_PHY) - continue; - link->link_enc->funcs->hw_init(link->link_enc); /* Check for enabled DIG to identify enabled display */ @@ -192,13 +164,45 @@ void dcn31_init_hw(struct dc *dc) link->link_status.link_active = true; } - /* Enables outbox notifications for usb4 dpia */ - if (dc->res_pool->usb4_dpia_count) - dmub_enable_outbox_notification(dc); + /* Power gate DSCs */ + for (i = 0; i < res_pool->res_cap->num_dsc; i++) + if (hws->funcs.dsc_pg_control != NULL) + hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); /* we want to turn off all dp displays before doing detection */ - if (dc->config.power_down_display_on_boot) - dc_link_blank_all_dp_displays(dc); + if (dc->config.power_down_display_on_boot) { + uint8_t dpcd_power_state = '\0'; + enum dc_status status = DC_ERROR_UNEXPECTED; + + for (i = 0; i < dc->link_count; i++) { + if (dc->links[i]->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) + continue; + + /* if any of the displays are lit up turn them off */ + status = core_link_read_dpcd(dc->links[i], DP_SET_POWER, + &dpcd_power_state, sizeof(dpcd_power_state)); + if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) { + /* blank dp stream before power off receiver*/ + if (dc->links[i]->link_enc->funcs->get_dig_frontend) { + unsigned int fe; + + fe = dc->links[i]->link_enc->funcs->get_dig_frontend( + dc->links[i]->link_enc); + if (fe == ENGINE_ID_UNKNOWN) + continue; + + for (j = 0; j < dc->res_pool->stream_enc_count; j++) { + if (fe == dc->res_pool->stream_enc[j]->id) { + dc->res_pool->stream_enc[j]->funcs->dp_blank( + dc->res_pool->stream_enc[j]); + break; + } + } + } + dp_receiver_power_ctrl(dc->links[i], false); + } + } + } /* If taking control over from VBIOS, we may want to optimize our first * mode set, so we need to skip powering down pipes until we know which @@ -213,6 +217,47 @@ void dcn31_init_hw(struct dc *dc) !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter); } + /* In headless boot cases, DIG may be turned + * on which causes HW/SW discrepancies. + * To avoid this, power down hardware on boot + * if DIG is turned on and seamless boot not enabled + */ + if (dc->config.power_down_display_on_boot) { + struct dc_link *edp_links[MAX_NUM_EDP]; + struct dc_link *edp_link; + bool power_down = false; + + get_edp_links(dc, edp_links, &edp_num); + if (edp_num) { + for (i = 0; i < edp_num; i++) { + edp_link = edp_links[i]; + if (edp_link->link_enc->funcs->is_dig_enabled && + edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && + dc->hwss.edp_backlight_control && + dc->hwss.power_down && + dc->hwss.edp_power_control) { + dc->hwss.edp_backlight_control(edp_link, false); + dc->hwss.power_down(dc); + dc->hwss.edp_power_control(edp_link, false); + power_down = true; + } + } + } + if (!power_down) { + for (i = 0; i < dc->link_count; i++) { + struct dc_link *link = dc->links[i]; + + if (link->link_enc->funcs->is_dig_enabled && + link->link_enc->funcs->is_dig_enabled(link->link_enc) && + dc->hwss.power_down) { + dc->hwss.power_down(dc); + break; + } + + } + } + } + for (i = 0; i < res_pool->audio_count; i++) { struct audio *audio = res_pool->audios[i]; @@ -234,13 +279,6 @@ void dcn31_init_hw(struct dc *dc) /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ REG_WRITE(DIO_MEM_PWR_CTRL, 0); - // Set i2c to light sleep until engine is setup - if (dc->debug.enable_mem_low_power.bits.i2c) - REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1); - - if (hws->funcs.setup_hpo_hw_control) - hws->funcs.setup_hpo_hw_control(hws, false); - if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); @@ -264,10 +302,8 @@ void dcn31_init_hw(struct dc *dc) if (dc->res_pool->hubbub->funcs->force_pstate_change_control) dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub, false, false); -#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc->res_pool->hubbub->funcs->init_crb) dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); -#endif } void dcn31_dsc_pg_control( @@ -282,12 +318,6 @@ void dcn31_dsc_pg_control( if (hws->ctx->dc->debug.disable_dsc_power_gate) return; - if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc && - hws->ctx->dc->res_pool->dccg->funcs->enable_dsc && - power_on) - hws->ctx->dc->res_pool->dccg->funcs->enable_dsc( - hws->ctx->dc->res_pool->dccg, dsc_inst); - REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); if (org_ip_request_cntl == 0) REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -324,13 +354,6 @@ void dcn31_dsc_pg_control( if (org_ip_request_cntl == 0) REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); - - if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) { - if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on) - hws->ctx->dc->res_pool->dccg->funcs->disable_dsc( - hws->ctx->dc->res_pool->dccg, dsc_inst); - } - } @@ -396,7 +419,7 @@ void dcn31_z10_save_init(struct dc *dc) dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); } -void dcn31_z10_restore(const struct dc *dc) +void dcn31_z10_restore(struct dc *dc) { union dmub_rb_cmd cmd; @@ -565,18 +588,24 @@ void dcn31_reset_hw_ctx_wrap( dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state); if (hws->funcs.enable_stream_gating) - hws->funcs.enable_stream_gating(dc, pipe_ctx_old); + hws->funcs.enable_stream_gating(dc, pipe_ctx); if (old_clk) old_clk->funcs->cs_power_down(old_clk); } } - - /* New dc_state in the process of being applied to hardware. */ - dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_TRANSIENT; } -void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable) +bool dcn31_is_abm_supported(struct dc *dc, + struct dc_state *context, struct dc_stream_state *stream) { - if (hws->ctx->dc->debug.hpo_optimization) - REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable); + int i; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + + if (pipe_ctx->stream == stream && + (pipe_ctx->prev_odm_pipe == NULL && pipe_ctx->next_odm_pipe == NULL)) + return true; + } + return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h index edfc01d6ad..140435e4f7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.h @@ -43,7 +43,7 @@ void dcn31_enable_power_gating_plane( void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx); -void dcn31_z10_restore(const struct dc *dc); +void dcn31_z10_restore(struct dc *dc); void dcn31_z10_save_init(struct dc *dc); void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on); @@ -54,6 +54,5 @@ void dcn31_reset_hw_ctx_wrap( bool dcn31_is_abm_supported(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream); void dcn31_init_pipes(struct dc *dc, struct dc_state *context); -void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable); #endif /* __DC_HWSS_DCN31_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c index d7559e5a99..4e9fe090b7 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_init.c @@ -31,12 +31,9 @@ #include "dcn301/dcn301_hwseq.h" #include "dcn31/dcn31_hwseq.h" -#include "dcn31_init.h" - static const struct hw_sequencer_funcs dcn31_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn31_init_hw, - .power_down_on_boot = dcn10_power_down_on_boot, .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, @@ -96,12 +93,12 @@ static const struct hw_sequencer_funcs dcn31_funcs = { .set_flip_control_gsl = dcn20_set_flip_control_gsl, .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, .calc_vupdate_position = dcn10_calc_vupdate_position, - .power_down = dce110_power_down, .set_backlight_level = dcn21_set_backlight_level, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .set_pipe = dcn21_set_pipe, .z10_restore = dcn31_z10_restore, .z10_save_init = dcn31_z10_save_init, + .is_abm_supported = dcn31_is_abm_supported, .set_disp_pattern_generator = dcn30_set_disp_pattern_generator, .optimize_pwr_state = dcn21_optimize_pwr_state, .exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state, @@ -141,7 +138,6 @@ static const struct hwseq_private_funcs dcn31_private_funcs = { .dccg_init = dcn20_dccg_init, .set_blend_lut = dcn30_set_blend_lut, .set_shaper_3dlut = dcn20_set_shaper_3dlut, - .setup_hpo_hw_control = dcn31_setup_hpo_hw_control, }; void dcn31_hw_sequencer_construct(struct dc *dc) @@ -153,9 +149,4 @@ void dcn31_hw_sequencer_construct(struct dc *dc) dc->hwss.init_hw = dcn20_fpga_init_hw; dc->hwseq->funcs.init_pipes = NULL; } - if (dc->debug.disable_z10) { - /*hw not support z10 or sw disable it*/ - dc->hwss.z10_restore = NULL; - dc->hwss.z10_save_init = NULL; - } } diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c index e8562fa113..a4b1d98f00 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_optc.c @@ -256,7 +256,6 @@ static struct timing_generator_funcs dcn31_tg_funcs = { .get_crc = optc1_get_crc, .configure_crc = optc2_configure_crc, .set_dsc_config = optc3_set_dsc_config, - .get_dsc_status = optc2_get_dsc_status, .set_dwb_source = NULL, .set_odm_bypass = optc3_set_odm_bypass, .set_odm_combine = optc31_set_odm_combine, diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c index 83ece02380..3b37213865 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_panel_cntl.c @@ -65,7 +65,7 @@ static uint32_t dcn31_get_16_bit_backlight_from_pwm(struct panel_cntl *panel_cnt return cmd.panel_cntl.data.current_backlight; } -static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl) +uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl) { struct dcn31_panel_cntl *dcn31_panel_cntl = TO_DCN31_PANEL_CNTL(panel_cntl); struct dc_dmub_srv *dc_dmub_srv = panel_cntl->ctx->dmub_srv; @@ -96,7 +96,7 @@ static uint32_t dcn31_panel_cntl_hw_init(struct panel_cntl *panel_cntl) return cmd.panel_cntl.data.current_backlight; } -static void dcn31_panel_cntl_destroy(struct panel_cntl **panel_cntl) +void dcn31_panel_cntl_destroy(struct panel_cntl **panel_cntl) { struct dcn31_panel_cntl *dcn31_panel_cntl = TO_DCN31_PANEL_CNTL(*panel_cntl); @@ -104,7 +104,7 @@ static void dcn31_panel_cntl_destroy(struct panel_cntl **panel_cntl) *panel_cntl = NULL; } -static bool dcn31_is_panel_backlight_on(struct panel_cntl *panel_cntl) +bool dcn31_is_panel_backlight_on(struct panel_cntl *panel_cntl) { union dmub_rb_cmd cmd; @@ -114,7 +114,7 @@ static bool dcn31_is_panel_backlight_on(struct panel_cntl *panel_cntl) return cmd.panel_cntl.data.is_backlight_on; } -static bool dcn31_is_panel_powered_on(struct panel_cntl *panel_cntl) +bool dcn31_is_panel_powered_on(struct panel_cntl *panel_cntl) { union dmub_rb_cmd cmd; @@ -124,7 +124,7 @@ static bool dcn31_is_panel_powered_on(struct panel_cntl *panel_cntl) return cmd.panel_cntl.data.is_powered_on; } -static void dcn31_store_backlight_level(struct panel_cntl *panel_cntl) +void dcn31_store_backlight_level(struct panel_cntl *panel_cntl) { union dmub_rb_cmd cmd; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index 8d64187478..d4fe535242 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -52,12 +52,7 @@ #include "dcn30/dcn30_vpg.h" #include "dcn30/dcn30_afmt.h" #include "dcn30/dcn30_dio_stream_encoder.h" -#include "dcn31/dcn31_hpo_dp_stream_encoder.h" -#include "dcn31/dcn31_hpo_dp_link_encoder.h" -#include "dcn31/dcn31_apg.h" #include "dcn31/dcn31_dio_link_encoder.h" -#include "dcn31/dcn31_vpg.h" -#include "dcn31/dcn31_afmt.h" #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" @@ -101,6 +96,8 @@ #include "link_enc_cfg.h" #define DC_LOGGER_INIT(logger) +#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) +#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) #define DCN3_1_DEFAULT_DET_SIZE 384 @@ -374,7 +371,7 @@ static const struct dce110_clk_src_mask cs_mask = { #define abm_regs(id)\ [id] = {\ - ABM_DCN302_REG_LIST(id)\ + ABM_DCN301_REG_LIST(id)\ } static const struct dce_abm_registers abm_regs[] = { @@ -422,10 +419,10 @@ static const struct dce_audio_mask audio_mask = { #define vpg_regs(id)\ [id] = {\ - VPG_DCN31_REG_LIST(id)\ + VPG_DCN3_REG_LIST(id)\ } -static const struct dcn31_vpg_registers vpg_regs[] = { +static const struct dcn30_vpg_registers vpg_regs[] = { vpg_regs(0), vpg_regs(1), vpg_regs(2), @@ -438,20 +435,20 @@ static const struct dcn31_vpg_registers vpg_regs[] = { vpg_regs(9), }; -static const struct dcn31_vpg_shift vpg_shift = { - DCN31_VPG_MASK_SH_LIST(__SHIFT) +static const struct dcn30_vpg_shift vpg_shift = { + DCN3_VPG_MASK_SH_LIST(__SHIFT) }; -static const struct dcn31_vpg_mask vpg_mask = { - DCN31_VPG_MASK_SH_LIST(_MASK) +static const struct dcn30_vpg_mask vpg_mask = { + DCN3_VPG_MASK_SH_LIST(_MASK) }; #define afmt_regs(id)\ [id] = {\ - AFMT_DCN31_REG_LIST(id)\ + AFMT_DCN3_REG_LIST(id)\ } -static const struct dcn31_afmt_registers afmt_regs[] = { +static const struct dcn30_afmt_registers afmt_regs[] = { afmt_regs(0), afmt_regs(1), afmt_regs(2), @@ -460,32 +457,12 @@ static const struct dcn31_afmt_registers afmt_regs[] = { afmt_regs(5) }; -static const struct dcn31_afmt_shift afmt_shift = { - DCN31_AFMT_MASK_SH_LIST(__SHIFT) +static const struct dcn30_afmt_shift afmt_shift = { + DCN3_AFMT_MASK_SH_LIST(__SHIFT) }; -static const struct dcn31_afmt_mask afmt_mask = { - DCN31_AFMT_MASK_SH_LIST(_MASK) -}; - -#define apg_regs(id)\ -[id] = {\ - APG_DCN31_REG_LIST(id)\ -} - -static const struct dcn31_apg_registers apg_regs[] = { - apg_regs(0), - apg_regs(1), - apg_regs(2), - apg_regs(3) -}; - -static const struct dcn31_apg_shift apg_shift = { - DCN31_APG_MASK_SH_LIST(__SHIFT) -}; - -static const struct dcn31_apg_mask apg_mask = { - DCN31_APG_MASK_SH_LIST(_MASK) +static const struct dcn30_afmt_mask afmt_mask = { + DCN3_AFMT_MASK_SH_LIST(_MASK) }; #define stream_enc_regs(id)\ @@ -570,49 +547,6 @@ static const struct dcn10_link_enc_mask le_mask = { DPCS_DCN31_MASK_SH_LIST(_MASK) }; -#define hpo_dp_stream_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\ -} - -static const struct dcn31_hpo_dp_stream_encoder_registers hpo_dp_stream_enc_regs[] = { - hpo_dp_stream_encoder_reg_list(0), - hpo_dp_stream_encoder_reg_list(1), - hpo_dp_stream_encoder_reg_list(2), - hpo_dp_stream_encoder_reg_list(3), -}; - -static const struct dcn31_hpo_dp_stream_encoder_shift hpo_dp_se_shift = { - DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(__SHIFT) -}; - -static const struct dcn31_hpo_dp_stream_encoder_mask hpo_dp_se_mask = { - DCN3_1_HPO_DP_STREAM_ENC_MASK_SH_LIST(_MASK) -}; - -#define hpo_dp_link_encoder_reg_list(id)\ -[id] = {\ - DCN3_1_HPO_DP_LINK_ENC_REG_LIST(id),\ - DCN3_1_RDPCSTX_REG_LIST(0),\ - DCN3_1_RDPCSTX_REG_LIST(1),\ - DCN3_1_RDPCSTX_REG_LIST(2),\ - DCN3_1_RDPCSTX_REG_LIST(3),\ - DCN3_1_RDPCSTX_REG_LIST(4)\ -} - -static const struct dcn31_hpo_dp_link_encoder_registers hpo_dp_link_enc_regs[] = { - hpo_dp_link_encoder_reg_list(0), - hpo_dp_link_encoder_reg_list(1), -}; - -static const struct dcn31_hpo_dp_link_encoder_shift hpo_dp_le_shift = { - DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(__SHIFT) -}; - -static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = { - DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK) -}; - #define dpp_regs(id)\ [id] = {\ DPP_REG_LIST_DCN30(id),\ @@ -869,8 +803,7 @@ static const struct dccg_mask dccg_mask = { SR(D6VGA_CONTROL), \ SR(DC_IP_REQUEST_CNTL), \ SR(AZALIA_AUDIO_DTO), \ - SR(AZALIA_CONTROLLER_CLOCK_GATING), \ - SR(HPO_TOP_HW_CONTROL) + SR(AZALIA_CONTROLLER_CLOCK_GATING) static const struct dce_hwseq_registers hwseq_reg = { HWSEQ_DCN31_REG_LIST() @@ -907,9 +840,7 @@ static const struct dce_hwseq_registers hwseq_reg = { HWS_SF(, DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, mask_sh), \ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_UNASSIGNED_PWR_MODE, mask_sh), \ HWS_SF(, ODM_MEM_PWR_CTRL3, ODM_MEM_VBLANK_PWR_MODE, mask_sh), \ - HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh), \ - HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh), \ - HWS_SF(, HPO_TOP_HW_CONTROL, HPO_IO_EN, mask_sh) + HWS_SF(, MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, mask_sh) static const struct dce_hwseq_shift hwseq_shift = { HWSEQ_DCN31_MASK_SH_LIST(__SHIFT) @@ -957,8 +888,6 @@ static const struct resource_caps res_cap_dcn31 = { .num_audio = 5, .num_stream_encoder = 5, .num_dig_link_enc = 5, - .num_hpo_dp_stream_encoder = 4, - .num_hpo_dp_link_encoder = 2, .num_pll = 5, .num_dwb = 1, .num_ddc = 5, @@ -977,7 +906,7 @@ static const struct dc_plane_cap plane_cap = { .argb8888 = true, .nv12 = true, .fp16 = true, - .p010 = true, + .p010 = false, .ayuv = false, }, @@ -1019,20 +948,17 @@ static const struct dc_debug_options debug_defaults_drv = { .use_max_lb = true, .enable_mem_low_power = { .bits = { - .vga = true, - .i2c = true, + .vga = false, + .i2c = false, .dmcu = false, // This is previously known to cause hang on S3 cycles if enabled - .dscl = true, - .cm = true, - .mpc = true, - .optc = true, - .vpg = true, - .afmt = true, + .dscl = false, + .cm = false, + .mpc = false, + .optc = false, } }, .optimize_edp_link_rate = true, .enable_sw_cntl_psr = true, - .apply_vendor_specific_lttpr_wa = true, }; static const struct dc_debug_options debug_defaults_diags = { @@ -1280,7 +1206,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( return &enc20->enc10.base; } -static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) +struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); @@ -1313,53 +1239,34 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); - if (!vpg31) + if (!vpg3) return NULL; - vpg31_construct(vpg31, ctx, inst, + vpg3_construct(vpg3, ctx, inst, &vpg_regs[inst], &vpg_shift, &vpg_mask); - return &vpg31->base; + return &vpg3->base; } static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); - if (!afmt31) + if (!afmt3) return NULL; - afmt31_construct(afmt31, ctx, inst, + afmt3_construct(afmt3, ctx, inst, &afmt_regs[inst], &afmt_shift, &afmt_mask); - // Light sleep by default, no need to power down here - - return &afmt31->base; -} - -static struct apg *dcn31_apg_create( - struct dc_context *ctx, - uint32_t inst) -{ - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); - - if (!apg31) - return NULL; - - apg31_construct(apg31, ctx, inst, - &apg_regs[inst], - &apg_shift, - &apg_mask); - - return &apg31->base; + return &afmt3->base; } static struct stream_encoder *dcn31_stream_encoder_create( @@ -1383,12 +1290,8 @@ static struct stream_encoder *dcn31_stream_encoder_create( vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); - if (!enc1 || !vpg || !afmt) { - kfree(enc1); - kfree(vpg); - kfree(afmt); + if (!enc1 || !vpg || !afmt) return NULL; - } if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { @@ -1404,72 +1307,6 @@ static struct stream_encoder *dcn31_stream_encoder_create( return &enc1->base; } -static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( - enum engine_id eng_id, - struct dc_context *ctx) -{ - struct dcn31_hpo_dp_stream_encoder *hpo_dp_enc31; - struct vpg *vpg; - struct apg *apg; - uint32_t hpo_dp_inst; - uint32_t vpg_inst; - uint32_t apg_inst; - - ASSERT((eng_id >= ENGINE_ID_HPO_DP_0) && (eng_id <= ENGINE_ID_HPO_DP_3)); - hpo_dp_inst = eng_id - ENGINE_ID_HPO_DP_0; - - /* Mapping of VPG register blocks to HPO DP block instance: - * VPG[6] -> HPO_DP[0] - * VPG[7] -> HPO_DP[1] - * VPG[8] -> HPO_DP[2] - * VPG[9] -> HPO_DP[3] - */ - vpg_inst = hpo_dp_inst + 6; - - /* Mapping of APG register blocks to HPO DP block instance: - * APG[0] -> HPO_DP[0] - * APG[1] -> HPO_DP[1] - * APG[2] -> HPO_DP[2] - * APG[3] -> HPO_DP[3] - */ - apg_inst = hpo_dp_inst; - - /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); - vpg = dcn31_vpg_create(ctx, vpg_inst); - apg = dcn31_apg_create(ctx, apg_inst); - - if (!hpo_dp_enc31 || !vpg || !apg) { - kfree(hpo_dp_enc31); - kfree(vpg); - kfree(apg); - return NULL; - } - - dcn31_hpo_dp_stream_encoder_construct(hpo_dp_enc31, ctx, ctx->dc_bios, - hpo_dp_inst, eng_id, vpg, apg, - &hpo_dp_stream_enc_regs[hpo_dp_inst], - &hpo_dp_se_shift, &hpo_dp_se_mask); - - return &hpo_dp_enc31->base; -} - -static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( - uint8_t inst, - struct dc_context *ctx) -{ - struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; - - /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); - - hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst, - &hpo_dp_link_enc_regs[inst], - &hpo_dp_le_shift, &hpo_dp_le_mask); - - return &hpo_dp_enc31->base; -} - static struct dce_hwseq *dcn31_hwseq_create( struct dc_context *ctx) { @@ -1480,13 +1317,6 @@ static struct dce_hwseq *dcn31_hwseq_create( hws->regs = &hwseq_reg; hws->shifts = &hwseq_shift; hws->masks = &hwseq_mask; - /* DCN3.1 FPGA Workaround - * Need to enable HPO DP Stream Encoder before setting OTG master enable. - * To do so, move calling function enable_stream_timing to only be done AFTER calling - * function core_link_enable_stream - */ - if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) - hws->wa.dp_hpo_and_otg_sequence = true; } return hws; } @@ -1494,8 +1324,6 @@ static const struct resource_create_funcs res_create_funcs = { .read_dce_straps = read_dce_straps, .create_audio = dcn31_create_audio, .create_stream_encoder = dcn31_stream_encoder_create, - .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create, - .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create, .create_hwseq = dcn31_hwseq_create, }; @@ -1503,8 +1331,6 @@ static const struct resource_create_funcs res_create_maximus_funcs = { .read_dce_straps = NULL, .create_audio = NULL, .create_stream_encoder = NULL, - .create_hpo_dp_stream_encoder = dcn31_hpo_dp_stream_encoder_create, - .create_hpo_dp_link_encoder = dcn31_hpo_dp_link_encoder_create, .create_hwseq = dcn31_hwseq_create, }; @@ -1527,28 +1353,6 @@ static void dcn31_resource_destruct(struct dcn31_resource_pool *pool) } } - for (i = 0; i < pool->base.hpo_dp_stream_enc_count; i++) { - if (pool->base.hpo_dp_stream_enc[i] != NULL) { - if (pool->base.hpo_dp_stream_enc[i]->vpg != NULL) { - kfree(DCN30_VPG_FROM_VPG(pool->base.hpo_dp_stream_enc[i]->vpg)); - pool->base.hpo_dp_stream_enc[i]->vpg = NULL; - } - if (pool->base.hpo_dp_stream_enc[i]->apg != NULL) { - kfree(DCN31_APG_FROM_APG(pool->base.hpo_dp_stream_enc[i]->apg)); - pool->base.hpo_dp_stream_enc[i]->apg = NULL; - } - kfree(DCN3_1_HPO_DP_STREAM_ENC_FROM_HPO_STREAM_ENC(pool->base.hpo_dp_stream_enc[i])); - pool->base.hpo_dp_stream_enc[i] = NULL; - } - } - - for (i = 0; i < pool->base.hpo_dp_link_enc_count; i++) { - if (pool->base.hpo_dp_link_enc[i] != NULL) { - kfree(DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(pool->base.hpo_dp_link_enc[i])); - pool->base.hpo_dp_link_enc[i] = NULL; - } - } - for (i = 0; i < pool->base.res_cap->num_dsc; i++) { if (pool->base.dscs[i] != NULL) dcn20_dsc_destroy(&pool->base.dscs[i]); @@ -1784,7 +1588,6 @@ static int dcn31_populate_dml_pipes_from_context( int i, pipe_cnt; struct resource_context *res_ctx = &context->res_ctx; struct pipe_ctx *pipe; - bool upscaled = false; dcn20_populate_dml_pipes_from_context(dc, context, pipes, fast_validate); @@ -1796,11 +1599,6 @@ static int dcn31_populate_dml_pipes_from_context( pipe = &res_ctx->pipe_ctx[i]; timing = &pipe->stream->timing; - if (pipe->plane_state && - (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height || - pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width)) - upscaled = true; - /* * Immediate flip can be set dynamically after enabling the plane. * We need to require support for immediate flip or underflow can be @@ -1845,17 +1643,12 @@ static int dcn31_populate_dml_pipes_from_context( context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; pipes[0].pipe.src.unbounded_req_mode = true; } - } else if (context->stream_count >= dc->debug.crb_alloc_policy_min_disp_count - && dc->debug.crb_alloc_policy > DET_SIZE_DEFAULT) { - context->bw_ctx.dml.ip.det_buffer_size_kbytes = dc->debug.crb_alloc_policy * 64; - } else if (context->stream_count >= 3 && upscaled) { - context->bw_ctx.dml.ip.det_buffer_size_kbytes = 192; } return pipe_cnt; } -void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) +static void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context) { if (dc->clk_mgr->bw_params->wm_table.entries[WM_A].valid) { context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.entries[WM_A].pstate_latency_us; @@ -1876,15 +1669,6 @@ static void dcn31_calculate_wm_and_dlg_fp( if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk) dcfclk = context->bw_ctx.dml.soc.min_dcfclk; - /* We don't recalculate clocks for 0 pipe configs, which can block - * S0i3 as high clocks will block low power states - * Override any clocks that can block S0i3 to min here - */ - if (pipe_cnt == 0) { - context->bw_ctx.bw.dcn.clk.dcfclk_khz = dcfclk; // always should be vlevel 0 - return; - } - pipes[0].clks_cfg.voltage = vlevel; pipes[0].clks_cfg.dcfclk_mhz = dcfclk; pipes[0].clks_cfg.socclk_mhz = context->bw_ctx.dml.soc.clock_limits[vlevel].socclk_mhz; @@ -1984,7 +1768,7 @@ static void dcn31_calculate_wm_and_dlg_fp( pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt); pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx); - if (dc->config.forced_clocks || dc->debug.max_disp_clk) { + if (dc->config.forced_clocks) { pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz; pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz; } @@ -1999,7 +1783,7 @@ static void dcn31_calculate_wm_and_dlg_fp( dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); } -void dcn31_calculate_wm_and_dlg( +static void dcn31_calculate_wm_and_dlg( struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes, int pipe_cnt, @@ -2010,58 +1794,6 @@ void dcn31_calculate_wm_and_dlg( DC_FP_END(); } -bool dcn31_validate_bandwidth(struct dc *dc, - struct dc_state *context, - bool fast_validate) -{ - bool out = false; - - BW_VAL_TRACE_SETUP(); - - int vlevel = 0; - int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); - DC_LOGGER_INIT(dc->ctx->logger); - - BW_VAL_TRACE_COUNT(); - - out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate); - - // Disable fast_validate to set min dcfclk in alculate_wm_and_dlg - if (pipe_cnt == 0) - fast_validate = false; - - if (!out) - goto validate_fail; - - BW_VAL_TRACE_END_VOLTAGE_LEVEL(); - - if (fast_validate) { - BW_VAL_TRACE_SKIP(fast); - goto validate_out; - } - - dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); - - BW_VAL_TRACE_END_WATERMARKS(); - - goto validate_out; - -validate_fail: - DC_LOG_WARNING("Mode Validation Warning: %s failed validation.\n", - dml_get_status_message(context->bw_ctx.dml.vba.ValidationStatus[context->bw_ctx.dml.vba.soc.num_states])); - - BW_VAL_TRACE_SKIP(fail); - out = false; - -validate_out: - kfree(pipes); - - BW_VAL_TRACE_FINISH(); - - return out; -} - static struct dc_cap_funcs cap_funcs = { .get_dcc_compression_cap = dcn20_get_dcc_compression_cap }; @@ -2144,7 +1876,7 @@ static struct resource_funcs dcn31_res_pool_funcs = { .link_encs_assign = link_enc_cfg_link_encs_assign, .link_enc_unassign = link_enc_cfg_link_enc_unassign, .panel_cntl_create = dcn31_panel_cntl_create, - .validate_bandwidth = dcn31_validate_bandwidth, + .validate_bandwidth = dcn30_validate_bandwidth, .calculate_wm_and_dlg = dcn31_calculate_wm_and_dlg, .update_soc_for_wm_a = dcn31_update_soc_for_wm_a, .populate_dml_pipes = dcn31_populate_dml_pipes_from_context, @@ -2219,9 +1951,6 @@ static bool dcn31_resource_construct( dc->caps.max_slave_rgb_planes = 1; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; - dc->caps.dp_hpo = true; - dc->caps.hdmi_frl_pcon_support = true; - dc->caps.edp_dsc_support = true; dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; dc->caps.is_apu = true; @@ -2260,9 +1989,6 @@ static bool dcn31_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1; - /* Use pipe context based otg sync logic */ - dc->config.use_pipe_ctx_sync_logic = true; - /* read VBIOS LTTPR caps */ { if (ctx->dc_bios->funcs->get_lttpr_caps) { @@ -2476,13 +2202,6 @@ static bool dcn31_resource_construct( pool->base.sw_i2cs[i] = NULL; } - if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && - dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 && - !dc->debug.dpia_debug.bits.disable_dpia) { - /* YELLOW CARP B0 has 4 DPIA's */ - pool->base.usb4_dpia_count = 4; - } - /* Audio, Stream Encoders including HPO and virtual, MPC 3D LUTs */ if (!resource_construct(num_virtual_links, dc, &pool->base, (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) ? @@ -2499,8 +2218,6 @@ static bool dcn31_resource_construct( dc->cap_funcs = cap_funcs; - dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp; - DC_FP_END(); return true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h index a513363b33..cc4bed6755 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.h @@ -35,16 +35,6 @@ struct dcn31_resource_pool { struct resource_pool base; }; -bool dcn31_validate_bandwidth(struct dc *dc, - struct dc_state *context, - bool fast_validate); -void dcn31_calculate_wm_and_dlg( - struct dc *dc, struct dc_state *context, - display_e2e_pipe_params_st *pipes, - int pipe_cnt, - int vlevel); -void dcn31_update_soc_for_wm_a(struct dc *dc, struct dc_state *context); - struct resource_pool *dcn31_create_resource_pool( const struct dc_init_data *init_data, struct dc *dc); diff --git a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h index 4229369c57..a9170b9f84 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h +++ b/drivers/gpu/drm/amd/display/dc/dm_cp_psp.h @@ -34,12 +34,9 @@ struct cp_psp_stream_config { uint8_t dig_fe; uint8_t link_enc_idx; uint8_t stream_enc_idx; - uint8_t dio_output_idx; uint8_t phy_idx; uint8_t assr_enabled; uint8_t mst_enabled; - uint8_t dp2_enabled; - uint8_t usb4_enabled; void *dm_stream_ctx; bool dpms_off; }; diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 7f94e3f70d..9ab854293a 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -59,7 +59,7 @@ void dm_helpers_free_gpu_mem( void *pvMem); enum dc_edid_status dm_helpers_parse_edid_caps( - struct dc_link *link, + struct dc_context *ctx, const struct dc_edid *edid, struct dc_edid_caps *edid_caps); @@ -160,12 +160,6 @@ void dm_set_dcn_clocks( struct dc_context *ctx, struct dc_clocks *clks); -#if defined(CONFIG_DRM_AMD_DC_DCN) -void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable); -#endif - -void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz); - bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enable); void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigned int param, unsigned int timeout_us); @@ -179,9 +173,4 @@ int dm_helper_dmub_aux_transfer_sync( const struct dc_link *link, struct aux_payload *payload, enum aux_return_code_type *operation_result); -enum set_config_status; -int dm_helpers_dmub_set_config_sync(struct dc_context *ctx, - const struct dc_link *link, - struct set_config_cmd_payload *payload, - enum set_config_status *operation_result); #endif /* __DM_HELPERS__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index eee6672bd3..9009b92490 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -58,7 +58,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) ifdef CONFIG_DRM_AMD_DC_DCN CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) -CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/dcn20_fpu.o := $(dml_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags) @@ -70,7 +70,6 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_ccflags) $(fram CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(frame_warn_flag) CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags) -CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_ccflags) CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags) @@ -85,7 +84,6 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_mode_vba_30.o := $(dml_rcflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn30/display_rq_dlg_calc_30.o := $(dml_rcflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_rcflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_rcflags) -CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_rcflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_rcflags) CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dsc/rc_calc_fpu.o := $(dml_rcflags) endif @@ -97,13 +95,12 @@ CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_rcflags) DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \ ifdef CONFIG_DRM_AMD_DC_DCN -DML += dcn20/dcn20_fpu.o DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o +DML += dcn2x/dcn2x.o DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o DML += dcn31/display_mode_vba_31.o dcn31/display_rq_dlg_calc_31.o -DML += dcn301/dcn301_fpu.o DML += dsc/rc_calc_fpu.o endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 548cdef8a8..8c168f348a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -37,8 +37,8 @@ // static void dml20_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, - display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param); + display_rq_params_st * rq_param, + const display_pipe_source_params_st pipe_src_param); // Function: dml20_rq_dlg_get_dlg_params // Calculate deadline related parameters @@ -49,8 +49,8 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en); /* @@ -164,52 +164,52 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, - const display_data_rq_sizing_params_st *rq_sizing) + const display_data_rq_sizing_params_st rq_sizing) { dml_print("DML_DLG: %s: rq_sizing param\n", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_rq_params_st *rq_param) + const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); - rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_l.dpte_row_height), + rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3; - if (rq_param->yuv420) { - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); - rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_c.dpte_row_height), + if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3; } - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); // TODO: take the max between luma, chroma chunk size? // okay for now, as we are setting chunk_bytes to 8kb anyways - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -218,9 +218,9 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, rq_regs->mrq_expansion_mode = 1; rq_regs->crq_expansion_mode = 1; - if (rq_param->yuv420) { - if ((double) rq_param->misc.rq_l.stored_swath_bytes - / (double) rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma } else { detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), @@ -233,7 +233,7 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -242,8 +242,8 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, unsigned int full_swath_bytes_packed_c = 0; bool req128_l = false; bool req128_c = false; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -685,7 +685,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st *rq_sizing_param, display_data_rq_dlg_params_st *rq_dlg_param, display_data_rq_misc_params_st *rq_misc_param, - const display_pipe_source_params_st *pipe_src_param, + const display_pipe_source_params_st pipe_src_param, bool is_chroma) { bool mode_422 = false; @@ -697,15 +697,15 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, // TODO check if ppe apply for both luma and chroma in 422 case if (is_chroma) { - vp_width = pipe_src_param->viewport_width_c / ppe; - vp_height = pipe_src_param->viewport_height_c; - data_pitch = pipe_src_param->data_pitch_c; - meta_pitch = pipe_src_param->meta_pitch_c; + vp_width = pipe_src_param.viewport_width_c / ppe; + vp_height = pipe_src_param.viewport_height_c; + data_pitch = pipe_src_param.data_pitch_c; + meta_pitch = pipe_src_param.meta_pitch_c; } else { - vp_width = pipe_src_param->viewport_width / ppe; - vp_height = pipe_src_param->viewport_height; - data_pitch = pipe_src_param->data_pitch; - meta_pitch = pipe_src_param->meta_pitch; + vp_width = pipe_src_param.viewport_width / ppe; + vp_height = pipe_src_param.viewport_height; + data_pitch = pipe_src_param.data_pitch; + meta_pitch = pipe_src_param.meta_pitch; } rq_sizing_param->chunk_bytes = 8192; @@ -728,21 +728,21 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, vp_height, data_pitch, meta_pitch, - pipe_src_param->source_format, - pipe_src_param->sw_mode, - pipe_src_param->macro_tile_size, - pipe_src_param->source_scan, + pipe_src_param.source_format, + pipe_src_param.sw_mode, + pipe_src_param.macro_tile_size, + pipe_src_param.source_scan, is_chroma); } static void dml20_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { // get param for luma surface - rq_param->yuv420 = pipe_src_param->source_format == dm_420_8 - || pipe_src_param->source_format == dm_420_10; - rq_param->yuv420_10bpc = pipe_src_param->source_format == dm_420_10; + rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 + || pipe_src_param.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), @@ -751,7 +751,7 @@ static void dml20_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, pipe_src_param, 0); - if (is_dual_plane((enum source_format_class)(pipe_src_param->source_format))) { + if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) { // get param for chroma surface get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), @@ -763,7 +763,7 @@ static void dml20_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, // calculate how to split the det buffer space between luma and chroma handle_det_buf_split(mode_lib, rq_param, pipe_src_param); - print__rq_params_st(mode_lib, rq_param); + print__rq_params_st(mode_lib, *rq_param); } void dml20_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, @@ -773,10 +773,10 @@ void dml20_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_params_st rq_param = {0}; memset(rq_regs, 0, sizeof(*rq_regs)); - dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, &pipe_param->src); - extract_rq_regs(mode_lib, rq_regs, &rq_param); + dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); + extract_rq_regs(mode_lib, rq_regs, rq_param); - print__rq_regs_st(mode_lib, rq_regs); + print__rq_regs_st(mode_lib, *rq_regs); } // Note: currently taken in as is. @@ -787,8 +787,8 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en) { @@ -935,7 +935,7 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, * (double) ref_freq_to_pix_freq); ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); - min_dcfclk_mhz = dlg_sys_param->deepsleep_dcfclk_mhz; + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); @@ -995,20 +995,20 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, // vinit_bot_l = scl.vinit_bot; // vinit_bot_c = scl.vinit_bot_c; -// unsigned int swath_height_l = rq_dlg_param->rq_l.swath_height; - swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; -// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param->rq_l.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; -// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param->rq_l.meta_pte_bytes_per_frame_ub; -// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param->rq_l.meta_bytes_per_row_ub; +// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; +// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; +// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; +// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; -// unsigned int swath_height_c = rq_dlg_param->rq_c.swath_height; - swath_width_ub_c = rq_dlg_param->rq_c.swath_width_ub; - // dpte_bytes_per_row_ub_c = rq_dlg_param->rq_c.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_c = rq_dlg_param->rq_c.dpte_groups_per_row_ub; +// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; - meta_chunks_per_row_ub_l = rq_dlg_param->rq_l.meta_chunks_per_row_ub; - meta_chunks_per_row_ub_c = rq_dlg_param->rq_c.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; vupdate_offset = dst->vupdate_offset; vupdate_width = dst->vupdate_width; vready_offset = dst->vready_offset; @@ -1137,16 +1137,16 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); // Active - req_per_swath_ub_l = rq_dlg_param->rq_l.req_per_swath_ub; - req_per_swath_ub_c = rq_dlg_param->rq_c.req_per_swath_ub; - meta_row_height_l = rq_dlg_param->rq_l.meta_row_height; - meta_row_height_c = rq_dlg_param->rq_c.meta_row_height; + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; scaler_rec_in_width_c = 0; - dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; - dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; if (mode_422) { swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element @@ -1542,8 +1542,8 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, @@ -1576,21 +1576,23 @@ void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency + / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated - print__dlg_sys_params_st(mode_lib, &dlg_sys_param); + print__dlg_sys_params_st(mode_lib, dlg_sys_param); // system parameter calculation done dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); - dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe.src); + dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src); dml20_rq_dlg_get_dlg_params(mode_lib, e2e_pipe_param, num_pipes, pipe_idx, dlg_regs, ttu_regs, - &rq_param.dlg, - &dlg_sys_param, + rq_param.dlg, + dlg_sys_param, cstate_en, pstate_en); dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index 0fc9f3e3ff..26ececfd40 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -38,7 +38,7 @@ static void dml20v2_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, display_rq_params_st * rq_param, - const display_pipe_source_params_st *pipe_src_param); + const display_pipe_source_params_st pipe_src_param); // Function: dml20v2_rq_dlg_get_dlg_params // Calculate deadline related parameters @@ -49,8 +49,8 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en); /* @@ -164,52 +164,52 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, - const display_data_rq_sizing_params_st *rq_sizing) + const display_data_rq_sizing_params_st rq_sizing) { dml_print("DML_DLG: %s: rq_sizing param\n", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_rq_params_st *rq_param) + const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); - rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_l.dpte_row_height), + rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3; - if (rq_param->yuv420) { - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); - rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_c.dpte_row_height), + if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3; } - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); // TODO: take the max between luma, chroma chunk size? // okay for now, as we are setting chunk_bytes to 8kb anyways - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -218,9 +218,9 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, rq_regs->mrq_expansion_mode = 1; rq_regs->crq_expansion_mode = 1; - if (rq_param->yuv420) { - if ((double) rq_param->misc.rq_l.stored_swath_bytes - / (double) rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma } else { detile_buf_plane1_addr = dml_round_to_multiple((unsigned int) ((2.0 * detile_buf_size_in_bytes) / 3.0), @@ -233,7 +233,7 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -242,8 +242,8 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, unsigned int full_swath_bytes_packed_c = 0; bool req128_l = false; bool req128_c = false; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -685,7 +685,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st *rq_sizing_param, display_data_rq_dlg_params_st *rq_dlg_param, display_data_rq_misc_params_st *rq_misc_param, - const display_pipe_source_params_st *pipe_src_param, + const display_pipe_source_params_st pipe_src_param, bool is_chroma) { bool mode_422 = false; @@ -697,15 +697,15 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, // TODO check if ppe apply for both luma and chroma in 422 case if (is_chroma) { - vp_width = pipe_src_param->viewport_width_c / ppe; - vp_height = pipe_src_param->viewport_height_c; - data_pitch = pipe_src_param->data_pitch_c; - meta_pitch = pipe_src_param->meta_pitch_c; + vp_width = pipe_src_param.viewport_width_c / ppe; + vp_height = pipe_src_param.viewport_height_c; + data_pitch = pipe_src_param.data_pitch_c; + meta_pitch = pipe_src_param.meta_pitch_c; } else { - vp_width = pipe_src_param->viewport_width / ppe; - vp_height = pipe_src_param->viewport_height; - data_pitch = pipe_src_param->data_pitch; - meta_pitch = pipe_src_param->meta_pitch; + vp_width = pipe_src_param.viewport_width / ppe; + vp_height = pipe_src_param.viewport_height; + data_pitch = pipe_src_param.data_pitch; + meta_pitch = pipe_src_param.meta_pitch; } rq_sizing_param->chunk_bytes = 8192; @@ -728,21 +728,21 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, vp_height, data_pitch, meta_pitch, - pipe_src_param->source_format, - pipe_src_param->sw_mode, - pipe_src_param->macro_tile_size, - pipe_src_param->source_scan, + pipe_src_param.source_format, + pipe_src_param.sw_mode, + pipe_src_param.macro_tile_size, + pipe_src_param.source_scan, is_chroma); } static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { // get param for luma surface - rq_param->yuv420 = pipe_src_param->source_format == dm_420_8 - || pipe_src_param->source_format == dm_420_10; - rq_param->yuv420_10bpc = pipe_src_param->source_format == dm_420_10; + rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 + || pipe_src_param.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), @@ -751,7 +751,7 @@ static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, pipe_src_param, 0); - if (is_dual_plane((enum source_format_class)(pipe_src_param->source_format))) { + if (is_dual_plane((enum source_format_class)(pipe_src_param.source_format))) { // get param for chroma surface get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), @@ -763,7 +763,7 @@ static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, // calculate how to split the det buffer space between luma and chroma handle_det_buf_split(mode_lib, rq_param, pipe_src_param); - print__rq_params_st(mode_lib, rq_param); + print__rq_params_st(mode_lib, *rq_param); } void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, @@ -773,10 +773,10 @@ void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_params_st rq_param = {0}; memset(rq_regs, 0, sizeof(*rq_regs)); - dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, &pipe_param->src); - extract_rq_regs(mode_lib, rq_regs, &rq_param); + dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); + extract_rq_regs(mode_lib, rq_regs, rq_param); - print__rq_regs_st(mode_lib, rq_regs); + print__rq_regs_st(mode_lib, *rq_regs); } // Note: currently taken in as is. @@ -787,8 +787,8 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en) { @@ -935,7 +935,7 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, * (double) ref_freq_to_pix_freq); ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int) dml_pow(2, 13)); - min_dcfclk_mhz = dlg_sys_param->deepsleep_dcfclk_mhz; + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); @@ -996,20 +996,20 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, // vinit_bot_l = scl.vinit_bot; // vinit_bot_c = scl.vinit_bot_c; -// unsigned int swath_height_l = rq_dlg_param->rq_l.swath_height; - swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; -// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param->rq_l.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; -// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param->rq_l.meta_pte_bytes_per_frame_ub; -// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param->rq_l.meta_bytes_per_row_ub; +// unsigned int swath_height_l = rq_dlg_param.rq_l.swath_height; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; +// unsigned int dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; +// unsigned int meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; +// unsigned int meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; -// unsigned int swath_height_c = rq_dlg_param->rq_c.swath_height; - swath_width_ub_c = rq_dlg_param->rq_c.swath_width_ub; - // dpte_bytes_per_row_ub_c = rq_dlg_param->rq_c.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_c = rq_dlg_param->rq_c.dpte_groups_per_row_ub; +// unsigned int swath_height_c = rq_dlg_param.rq_c.swath_height; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + // dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; - meta_chunks_per_row_ub_l = rq_dlg_param->rq_l.meta_chunks_per_row_ub; - meta_chunks_per_row_ub_c = rq_dlg_param->rq_c.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; vupdate_offset = dst->vupdate_offset; vupdate_width = dst->vupdate_width; vready_offset = dst->vready_offset; @@ -1138,16 +1138,16 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); // Active - req_per_swath_ub_l = rq_dlg_param->rq_l.req_per_swath_ub; - req_per_swath_ub_c = rq_dlg_param->rq_c.req_per_swath_ub; - meta_row_height_l = rq_dlg_param->rq_l.meta_row_height; - meta_row_height_c = rq_dlg_param->rq_c.meta_row_height; + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; scaler_rec_in_width_c = 0; - dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; - dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; if (mode_422) { swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element @@ -1543,8 +1543,8 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, @@ -1577,21 +1577,23 @@ void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency + / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated - print__dlg_sys_params_st(mode_lib, &dlg_sys_param); + print__dlg_sys_params_st(mode_lib, dlg_sys_param); // system parameter calculation done dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); - dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe.src); + dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe.src); dml20v2_rq_dlg_get_dlg_params(mode_lib, e2e_pipe_param, num_pipes, pipe_idx, dlg_regs, ttu_regs, - &rq_param.dlg, - &dlg_sys_param, + rq_param.dlg, + dlg_sys_param, cstate_en, pstate_en); dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index 8a7485e21d..4136eb8256 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -3394,127 +3394,6 @@ static unsigned int TruncToValidBPP( } } - -static noinline void CalculatePrefetchSchedulePerPlane( - struct display_mode_lib *mode_lib, - int i, - unsigned j, - unsigned k) -{ - struct vba_vars_st *locals = &mode_lib->vba; - Pipe myPipe; - HostVM myHostVM; - - if (mode_lib->vba.XFCEnabled[k] == true) { - mode_lib->vba.XFCRemoteSurfaceFlipDelay = - CalculateRemoteSurfaceFlipDelay( - mode_lib, - mode_lib->vba.VRatio[k], - locals->SwathWidthYThisState[k], - dml_ceil(locals->BytePerPixelInDETY[k], 1.0), - mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], - mode_lib->vba.XFCTSlvVupdateOffset, - mode_lib->vba.XFCTSlvVupdateWidth, - mode_lib->vba.XFCTSlvVreadyOffset, - mode_lib->vba.XFCXBUFLatencyTolerance, - mode_lib->vba.XFCFillBWOverhead, - mode_lib->vba.XFCSlvChunkSize, - mode_lib->vba.XFCBusTransportTime, - mode_lib->vba.TimeCalc, - mode_lib->vba.TWait, - &mode_lib->vba.SrcActiveDrainRate, - &mode_lib->vba.TInitXFill, - &mode_lib->vba.TslvChk); - } else { - mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0; - } - - myPipe.DPPCLK = locals->RequiredDPPCLK[i][j][k]; - myPipe.DISPCLK = locals->RequiredDISPCLK[i][j]; - myPipe.PixelClock = mode_lib->vba.PixelClock[k]; - myPipe.DCFCLKDeepSleep = mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0]; - myPipe.DPPPerPlane = locals->NoOfDPP[i][j][k]; - myPipe.ScalerEnabled = mode_lib->vba.ScalerEnabled[k]; - myPipe.SourceScan = mode_lib->vba.SourceScan[k]; - myPipe.BlockWidth256BytesY = locals->Read256BlockWidthY[k]; - myPipe.BlockHeight256BytesY = locals->Read256BlockHeightY[k]; - myPipe.BlockWidth256BytesC = locals->Read256BlockWidthC[k]; - myPipe.BlockHeight256BytesC = locals->Read256BlockHeightC[k]; - myPipe.InterlaceEnable = mode_lib->vba.Interlace[k]; - myPipe.NumberOfCursors = mode_lib->vba.NumberOfCursors[k]; - myPipe.VBlank = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]; - myPipe.HTotal = mode_lib->vba.HTotal[k]; - - - myHostVM.Enable = mode_lib->vba.HostVMEnable; - myHostVM.MaxPageTableLevels = mode_lib->vba.HostVMMaxPageTableLevels; - myHostVM.CachedPageTableLevels = mode_lib->vba.HostVMCachedPageTableLevels; - - - mode_lib->vba.IsErrorResult[i][j][k] = CalculatePrefetchSchedule( - mode_lib, - mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, - mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, - &myPipe, - locals->DSCDelayPerState[i][k], - mode_lib->vba.DPPCLKDelaySubtotal, - mode_lib->vba.DPPCLKDelaySCL, - mode_lib->vba.DPPCLKDelaySCLLBOnly, - mode_lib->vba.DPPCLKDelayCNVCFormater, - mode_lib->vba.DPPCLKDelayCNVCCursor, - mode_lib->vba.DISPCLKDelaySubtotal, - locals->SwathWidthYThisState[k] / mode_lib->vba.HRatio[k], - mode_lib->vba.OutputFormat[k], - mode_lib->vba.MaxInterDCNTileRepeaters, - dml_min(mode_lib->vba.MaxVStartup, locals->MaximumVStartup[0][0][k]), - locals->MaximumVStartup[0][0][k], - mode_lib->vba.GPUVMMaxPageTableLevels, - mode_lib->vba.GPUVMEnable, - &myHostVM, - mode_lib->vba.DynamicMetadataEnable[k], - mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], - mode_lib->vba.DynamicMetadataTransmittedBytes[k], - mode_lib->vba.DCCEnable[k], - mode_lib->vba.UrgentLatency, - mode_lib->vba.ExtraLatency, - mode_lib->vba.TimeCalc, - locals->PDEAndMetaPTEBytesPerFrame[0][0][k], - locals->MetaRowBytes[0][0][k], - locals->DPTEBytesPerRow[0][0][k], - locals->PrefetchLinesY[0][0][k], - locals->SwathWidthYThisState[k], - locals->BytePerPixelInDETY[k], - locals->PrefillY[k], - locals->MaxNumSwY[k], - locals->PrefetchLinesC[0][0][k], - locals->BytePerPixelInDETC[k], - locals->PrefillC[k], - locals->MaxNumSwC[k], - locals->SwathHeightYThisState[k], - locals->SwathHeightCThisState[k], - mode_lib->vba.TWait, - mode_lib->vba.XFCEnabled[k], - mode_lib->vba.XFCRemoteSurfaceFlipDelay, - mode_lib->vba.ProgressiveToInterlaceUnitInOPP, - &locals->dst_x_after_scaler, - &locals->dst_y_after_scaler, - &locals->LineTimesForPrefetch[k], - &locals->PrefetchBW[k], - &locals->LinesForMetaPTE[k], - &locals->LinesForMetaAndDPTERow[k], - &locals->VRatioPreY[i][j][k], - &locals->VRatioPreC[i][j][k], - &locals->RequiredPrefetchPixelDataBWLuma[i][j][k], - &locals->RequiredPrefetchPixelDataBWChroma[i][j][k], - &locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, - &locals->Tno_bw[k], - &locals->prefetch_vmrow_bw[k], - locals->swath_width_luma_ub, - locals->swath_width_chroma_ub, - &mode_lib->vba.VUpdateOffsetPix[k], - &mode_lib->vba.VUpdateWidthPix[k], - &mode_lib->vba.VReadyOffsetPix[k]); -} void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) { struct vba_vars_st *locals = &mode_lib->vba; @@ -4797,9 +4676,120 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l mode_lib->vba.DRAMClockChangeLatency, mode_lib->vba.UrgentLatency, mode_lib->vba.SREnterPlusExitTime); - for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) - CalculatePrefetchSchedulePerPlane(mode_lib, i, j, k); + for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { + Pipe myPipe; + HostVM myHostVM; + if (mode_lib->vba.XFCEnabled[k] == true) { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = + CalculateRemoteSurfaceFlipDelay( + mode_lib, + mode_lib->vba.VRatio[k], + locals->SwathWidthYThisState[k], + dml_ceil(locals->BytePerPixelInDETY[k], 1.0), + mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k], + mode_lib->vba.XFCTSlvVupdateOffset, + mode_lib->vba.XFCTSlvVupdateWidth, + mode_lib->vba.XFCTSlvVreadyOffset, + mode_lib->vba.XFCXBUFLatencyTolerance, + mode_lib->vba.XFCFillBWOverhead, + mode_lib->vba.XFCSlvChunkSize, + mode_lib->vba.XFCBusTransportTime, + mode_lib->vba.TimeCalc, + mode_lib->vba.TWait, + &mode_lib->vba.SrcActiveDrainRate, + &mode_lib->vba.TInitXFill, + &mode_lib->vba.TslvChk); + } else { + mode_lib->vba.XFCRemoteSurfaceFlipDelay = 0.0; + } + + myPipe.DPPCLK = locals->RequiredDPPCLK[i][j][k]; + myPipe.DISPCLK = locals->RequiredDISPCLK[i][j]; + myPipe.PixelClock = mode_lib->vba.PixelClock[k]; + myPipe.DCFCLKDeepSleep = mode_lib->vba.ProjectedDCFCLKDeepSleep[0][0]; + myPipe.DPPPerPlane = locals->NoOfDPP[i][j][k]; + myPipe.ScalerEnabled = mode_lib->vba.ScalerEnabled[k]; + myPipe.SourceScan = mode_lib->vba.SourceScan[k]; + myPipe.BlockWidth256BytesY = locals->Read256BlockWidthY[k]; + myPipe.BlockHeight256BytesY = locals->Read256BlockHeightY[k]; + myPipe.BlockWidth256BytesC = locals->Read256BlockWidthC[k]; + myPipe.BlockHeight256BytesC = locals->Read256BlockHeightC[k]; + myPipe.InterlaceEnable = mode_lib->vba.Interlace[k]; + myPipe.NumberOfCursors = mode_lib->vba.NumberOfCursors[k]; + myPipe.VBlank = mode_lib->vba.VTotal[k] - mode_lib->vba.VActive[k]; + myPipe.HTotal = mode_lib->vba.HTotal[k]; + + + myHostVM.Enable = mode_lib->vba.HostVMEnable; + myHostVM.MaxPageTableLevels = mode_lib->vba.HostVMMaxPageTableLevels; + myHostVM.CachedPageTableLevels = mode_lib->vba.HostVMCachedPageTableLevels; + + + mode_lib->vba.IsErrorResult[i][j][k] = CalculatePrefetchSchedule( + mode_lib, + mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyPixelMixedWithVMData, + mode_lib->vba.PercentOfIdealDRAMFabricAndSDPPortBWReceivedAfterUrgLatencyVMDataOnly, + &myPipe, + locals->DSCDelayPerState[i][k], + mode_lib->vba.DPPCLKDelaySubtotal, + mode_lib->vba.DPPCLKDelaySCL, + mode_lib->vba.DPPCLKDelaySCLLBOnly, + mode_lib->vba.DPPCLKDelayCNVCFormater, + mode_lib->vba.DPPCLKDelayCNVCCursor, + mode_lib->vba.DISPCLKDelaySubtotal, + locals->SwathWidthYThisState[k] / mode_lib->vba.HRatio[k], + mode_lib->vba.OutputFormat[k], + mode_lib->vba.MaxInterDCNTileRepeaters, + dml_min(mode_lib->vba.MaxVStartup, locals->MaximumVStartup[0][0][k]), + locals->MaximumVStartup[0][0][k], + mode_lib->vba.GPUVMMaxPageTableLevels, + mode_lib->vba.GPUVMEnable, + &myHostVM, + mode_lib->vba.DynamicMetadataEnable[k], + mode_lib->vba.DynamicMetadataLinesBeforeActiveRequired[k], + mode_lib->vba.DynamicMetadataTransmittedBytes[k], + mode_lib->vba.DCCEnable[k], + mode_lib->vba.UrgentLatency, + mode_lib->vba.ExtraLatency, + mode_lib->vba.TimeCalc, + locals->PDEAndMetaPTEBytesPerFrame[0][0][k], + locals->MetaRowBytes[0][0][k], + locals->DPTEBytesPerRow[0][0][k], + locals->PrefetchLinesY[0][0][k], + locals->SwathWidthYThisState[k], + locals->BytePerPixelInDETY[k], + locals->PrefillY[k], + locals->MaxNumSwY[k], + locals->PrefetchLinesC[0][0][k], + locals->BytePerPixelInDETC[k], + locals->PrefillC[k], + locals->MaxNumSwC[k], + locals->SwathHeightYThisState[k], + locals->SwathHeightCThisState[k], + mode_lib->vba.TWait, + mode_lib->vba.XFCEnabled[k], + mode_lib->vba.XFCRemoteSurfaceFlipDelay, + mode_lib->vba.ProgressiveToInterlaceUnitInOPP, + &locals->dst_x_after_scaler, + &locals->dst_y_after_scaler, + &locals->LineTimesForPrefetch[k], + &locals->PrefetchBW[k], + &locals->LinesForMetaPTE[k], + &locals->LinesForMetaAndDPTERow[k], + &locals->VRatioPreY[i][j][k], + &locals->VRatioPreC[i][j][k], + &locals->RequiredPrefetchPixelDataBWLuma[i][j][k], + &locals->RequiredPrefetchPixelDataBWChroma[i][j][k], + &locals->VStartupRequiredWhenNotEnoughTimeForDynamicMetadata, + &locals->Tno_bw[k], + &locals->prefetch_vmrow_bw[k], + locals->swath_width_luma_ub, + locals->swath_width_chroma_ub, + &mode_lib->vba.VUpdateOffsetPix[k], + &mode_lib->vba.VUpdateWidthPix[k], + &mode_lib->vba.VReadyOffsetPix[k]); + } mode_lib->vba.MaximumReadBandwidthWithoutPrefetch = 0.0; mode_lib->vba.MaximumReadBandwidthWithPrefetch = 0.0; for (k = 0; k <= mode_lib->vba.NumberOfActivePlanes - 1; k++) { diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c index 618f4b682a..736978c4d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -141,55 +141,55 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si static void extract_rq_sizing_regs( struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, - const display_data_rq_sizing_params_st *rq_sizing) + const display_data_rq_sizing_params_st rq_sizing) { dml_print("DML_DLG: %s: rq_sizing param\n", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } static void extract_rq_regs( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_rq_params_st *rq_param) + const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); rq_regs->rq_regs_l.pte_row_height_linear = dml_floor( - dml_log2(rq_param->dlg.rq_l.dpte_row_height), + dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3; - if (rq_param->yuv420) { - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); + if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); rq_regs->rq_regs_c.pte_row_height_linear = dml_floor( - dml_log2(rq_param->dlg.rq_c.dpte_row_height), + dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3; } - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); // FIXME: take the max between luma, chroma chunk size? // okay for now, as we are setting chunk_bytes to 8kb anyways - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -198,9 +198,9 @@ static void extract_rq_regs( rq_regs->mrq_expansion_mode = 1; rq_regs->crq_expansion_mode = 1; - if (rq_param->yuv420) { - if ((double) rq_param->misc.rq_l.stored_swath_bytes - / (double) rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma } else { detile_buf_plane1_addr = dml_round_to_multiple( @@ -215,7 +215,7 @@ static void extract_rq_regs( static void handle_det_buf_split( struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -224,8 +224,8 @@ static void handle_det_buf_split( unsigned int full_swath_bytes_packed_c = 0; bool req128_l = false; bool req128_c = false; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -806,8 +806,8 @@ static void dml_rq_dlg_get_rq_params( } // calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, &pipe_param->src); - print__rq_params_st(mode_lib, rq_param); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); + print__rq_params_st(mode_lib, *rq_param); } void dml21_rq_dlg_get_rq_reg( @@ -819,9 +819,9 @@ void dml21_rq_dlg_get_rq_reg( memset(rq_regs, 0, sizeof(*rq_regs)); dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param); - extract_rq_regs(mode_lib, rq_regs, &rq_param); + extract_rq_regs(mode_lib, rq_regs, rq_param); - print__rq_regs_st(mode_lib, rq_regs); + print__rq_regs_st(mode_lib, *rq_regs); } // Note: currently taken in as is. @@ -833,8 +833,8 @@ static void dml_rq_dlg_get_dlg_params( const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en) { @@ -981,7 +981,7 @@ static void dml_rq_dlg_get_dlg_params( * (double) ref_freq_to_pix_freq); ASSERT(disp_dlg_regs->refcyc_h_blank_end < (unsigned int)dml_pow(2, 13)); - min_dcfclk_mhz = dlg_sys_param->deepsleep_dcfclk_mhz; + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; t_calc_us = get_tcalc(mode_lib, e2e_pipe_param, num_pipes); min_ttu_vblank = get_min_ttu_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); @@ -1042,13 +1042,13 @@ static void dml_rq_dlg_get_dlg_params( scl_enable = scl->scl_enable; line_time_in_us = (htotal / pclk_freq_in_mhz); - swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; - dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; - swath_width_ub_c = rq_dlg_param->rq_c.swath_width_ub; - dpte_groups_per_row_ub_c = rq_dlg_param->rq_c.dpte_groups_per_row_ub; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; - meta_chunks_per_row_ub_l = rq_dlg_param->rq_l.meta_chunks_per_row_ub; - meta_chunks_per_row_ub_c = rq_dlg_param->rq_c.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; vupdate_offset = dst->vupdate_offset; vupdate_width = dst->vupdate_width; vready_offset = dst->vready_offset; @@ -1189,16 +1189,16 @@ static void dml_rq_dlg_get_dlg_params( dml_print("DML_DLG: %s: vratio_pre_c=%3.2f\n", __func__, vratio_pre_c); // Active - req_per_swath_ub_l = rq_dlg_param->rq_l.req_per_swath_ub; - req_per_swath_ub_c = rq_dlg_param->rq_c.req_per_swath_ub; - meta_row_height_l = rq_dlg_param->rq_l.meta_row_height; - meta_row_height_c = rq_dlg_param->rq_c.meta_row_height; + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; scaler_rec_in_width_c = 0; - dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; - dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; if (mode_422) { swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element @@ -1650,8 +1650,8 @@ static void dml_rq_dlg_get_dlg_params( disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } void dml21_rq_dlg_get_dlg_reg( @@ -1688,8 +1688,10 @@ void dml21_rq_dlg_get_dlg_reg( mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency + / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated - print__dlg_sys_params_st(mode_lib, &dlg_sys_param); + print__dlg_sys_params_st(mode_lib, dlg_sys_param); // system parameter calculation done @@ -1702,13 +1704,21 @@ void dml21_rq_dlg_get_dlg_reg( pipe_idx, dlg_regs, ttu_regs, - &rq_param.dlg, - &dlg_sys_param, + rq_param.dlg, + dlg_sys_param, cstate_en, pstate_en); dml_print("DML_DLG: Calculation for pipe[%d] end\n", pipe_idx); } +void dml_rq_dlg_get_arb_params(struct display_mode_lib *mode_lib, display_arb_params_st *arb_param) +{ + memset(arb_param, 0, sizeof(*arb_param)); + arb_param->max_req_outstanding = 256; + arb_param->min_req_outstanding = 68; + arb_param->sat_level_us = 60; +} + static void calculate_ttu_cursor( struct display_mode_lib *mode_lib, double *refcyc_per_req_delivery_pre_cur, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index f47d82da11..e3d9f1decd 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -3576,9 +3576,16 @@ static double TruncToValidBPP( MinDSCBPP = 8; MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16; } else { - NonDSCBPP0 = 16; - NonDSCBPP1 = 20; - NonDSCBPP2 = 24; + if (Output == dm_hdmi) { + NonDSCBPP0 = 24; + NonDSCBPP1 = 24; + NonDSCBPP2 = 24; + } + else { + NonDSCBPP0 = 16; + NonDSCBPP1 = 20; + NonDSCBPP2 = 24; + } if (Format == dm_n422) { MinDSCBPP = 7; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 747167083d..2120e0941a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -89,52 +89,52 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, - const display_data_rq_sizing_params_st *rq_sizing) + const display_data_rq_sizing_params_st rq_sizing) { dml_print("DML_DLG: %s: rq_sizing param\n", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_rq_params_st *rq_param) + const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); - rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_l.dpte_row_height), + rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3; - if (rq_param->yuv420) { - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); - rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_c.dpte_row_height), + if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3; } - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); // FIXME: take the max between luma, chroma chunk size? // okay for now, as we are setting chunk_bytes to 8kb anyways - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param->yuv420 && rq_param->sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param.yuv420 && rq_param.sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -143,9 +143,9 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, rq_regs->mrq_expansion_mode = 1; rq_regs->crq_expansion_mode = 1; - if (rq_param->yuv420) { - if ((double)rq_param->misc.rq_l.stored_swath_bytes - / (double)rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double)rq_param.misc.rq_l.stored_swath_bytes + / (double)rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); // half to chroma } else { detile_buf_plane1_addr = dml_round_to_multiple((unsigned int)((2.0 * detile_buf_size_in_bytes) / 3.0), @@ -158,7 +158,7 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_source_params_st *pipe_src_param) + const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -167,8 +167,8 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, unsigned int full_swath_bytes_packed_c = 0; bool req128_l = false; bool req128_c = false; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -871,8 +871,8 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, } // calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, &pipe_param->src); - print__rq_params_st(mode_lib, rq_param); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); + print__rq_params_st(mode_lib, *rq_param); } void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, @@ -883,9 +883,9 @@ void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, memset(rq_regs, 0, sizeof(*rq_regs)); dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param); - extract_rq_regs(mode_lib, rq_regs, &rq_param); + extract_rq_regs(mode_lib, rq_regs, rq_param); - print__rq_regs_st(mode_lib, rq_regs); + print__rq_regs_st(mode_lib, *rq_regs); } static void calculate_ttu_cursor(struct display_mode_lib *mode_lib, @@ -1824,8 +1824,8 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, @@ -1858,8 +1858,10 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, e2e_pipe_param, num_pipes); + dlg_sys_param.t_srx_delay_us = mode_lib->ip.dcfclk_cstate_latency + / dlg_sys_param.deepsleep_dcfclk_mhz; // TODO: Deprecated - print__dlg_sys_params_st(mode_lib, &dlg_sys_param); + print__dlg_sys_params_st(mode_lib, dlg_sys_param); // system parameter calculation done diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c index 6feb23432f..d58925cff4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -422,8 +422,62 @@ static void CalculateUrgentBurstFactor( static void UseMinimumDCFCLK( struct display_mode_lib *mode_lib, + int MaxInterDCNTileRepeaters, int MaxPrefetchMode, - int ReorderingBytes); + double FinalDRAMClockChangeLatency, + double SREnterPlusExitTime, + int ReturnBusWidth, + int RoundTripPingLatencyCycles, + int ReorderingBytes, + int PixelChunkSizeInKByte, + int MetaChunkSize, + bool GPUVMEnable, + int GPUVMMaxPageTableLevels, + bool HostVMEnable, + int NumberOfActivePlanes, + double HostVMMinPageSize, + int HostVMMaxNonCachedPageTableLevels, + bool DynamicMetadataVMEnabled, + enum immediate_flip_requirement ImmediateFlipRequirement, + bool ProgressiveToInterlaceUnitInOPP, + double MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation, + double PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency, + int VTotal[], + int VActive[], + int DynamicMetadataTransmittedBytes[], + int DynamicMetadataLinesBeforeActiveRequired[], + bool Interlace[], + double RequiredDPPCLK[][2][DC__NUM_DPP__MAX], + double RequiredDISPCLK[][2], + double UrgLatency[], + unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX], + double ProjectedDCFCLKDeepSleep[][2], + double MaximumVStartup[][2][DC__NUM_DPP__MAX], + double TotalVActivePixelBandwidth[][2], + double TotalVActiveCursorBandwidth[][2], + double TotalMetaRowBandwidth[][2], + double TotalDPTERowBandwidth[][2], + unsigned int TotalNumberOfActiveDPP[][2], + unsigned int TotalNumberOfDCCActiveDPP[][2], + int dpte_group_bytes[], + double PrefetchLinesY[][2][DC__NUM_DPP__MAX], + double PrefetchLinesC[][2][DC__NUM_DPP__MAX], + int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX], + int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX], + int BytePerPixelY[], + int BytePerPixelC[], + int HTotal[], + double PixelClock[], + double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX], + double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX], + double MetaRowBytes[][2][DC__NUM_DPP__MAX], + bool DynamicMetadataEnable[], + double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX], + double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX], + double ReadBandwidthLuma[], + double ReadBandwidthChroma[], + double DCFCLKPerState[], + double DCFCLKState[][2]); static void CalculatePixelDeliveryTimes( unsigned int NumberOfActivePlanes, @@ -3838,11 +3892,15 @@ static double TruncToValidBPP( MinDSCBPP = 8; MaxDSCBPP = 3 * DSCInputBitPerComponent - 1.0 / 16; } else { - - NonDSCBPP0 = 16; - NonDSCBPP1 = 20; - NonDSCBPP2 = 24; - + if (Output == dm_hdmi) { + NonDSCBPP0 = 24; + NonDSCBPP1 = 24; + NonDSCBPP2 = 24; + } else { + NonDSCBPP0 = 16; + NonDSCBPP1 = 20; + NonDSCBPP2 = 24; + } if (Format == dm_n422) { MinDSCBPP = 7; MaxDSCBPP = 2 * DSCInputBitPerComponent - 1.0 / 16.0; @@ -3895,102 +3953,6 @@ static double TruncToValidBPP( return BPP_INVALID; } -static noinline void CalculatePrefetchSchedulePerPlane( - struct display_mode_lib *mode_lib, - double HostVMInefficiencyFactor, - int i, - unsigned j, - unsigned k) -{ - struct vba_vars_st *v = &mode_lib->vba; - Pipe myPipe; - - myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k]; - myPipe.DISPCLK = v->RequiredDISPCLK[i][j]; - myPipe.PixelClock = v->PixelClock[k]; - myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j]; - myPipe.DPPPerPlane = v->NoOfDPP[i][j][k]; - myPipe.ScalerEnabled = v->ScalerEnabled[k]; - myPipe.SourceScan = v->SourceScan[k]; - myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k]; - myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k]; - myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k]; - myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k]; - myPipe.InterlaceEnable = v->Interlace[k]; - myPipe.NumberOfCursors = v->NumberOfCursors[k]; - myPipe.VBlank = v->VTotal[k] - v->VActive[k]; - myPipe.HTotal = v->HTotal[k]; - myPipe.DCCEnable = v->DCCEnable[k]; - myPipe.ODMCombineIsEnabled = v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1 - || v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1; - myPipe.SourcePixelFormat = v->SourcePixelFormat[k]; - myPipe.BytePerPixelY = v->BytePerPixelY[k]; - myPipe.BytePerPixelC = v->BytePerPixelC[k]; - myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP; - v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule( - mode_lib, - HostVMInefficiencyFactor, - &myPipe, - v->DSCDelayPerState[i][k], - v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater, - v->DPPCLKDelaySCL, - v->DPPCLKDelaySCLLBOnly, - v->DPPCLKDelayCNVCCursor, - v->DISPCLKDelaySubtotal, - v->SwathWidthYThisState[k] / v->HRatio[k], - v->OutputFormat[k], - v->MaxInterDCNTileRepeaters, - dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]), - v->MaximumVStartup[i][j][k], - v->GPUVMMaxPageTableLevels, - v->GPUVMEnable, - v->HostVMEnable, - v->HostVMMaxNonCachedPageTableLevels, - v->HostVMMinPageSize, - v->DynamicMetadataEnable[k], - v->DynamicMetadataVMEnabled, - v->DynamicMetadataLinesBeforeActiveRequired[k], - v->DynamicMetadataTransmittedBytes[k], - v->UrgLatency[i], - v->ExtraLatency, - v->TimeCalc, - v->PDEAndMetaPTEBytesPerFrame[i][j][k], - v->MetaRowBytes[i][j][k], - v->DPTEBytesPerRow[i][j][k], - v->PrefetchLinesY[i][j][k], - v->SwathWidthYThisState[k], - v->PrefillY[k], - v->MaxNumSwY[k], - v->PrefetchLinesC[i][j][k], - v->SwathWidthCThisState[k], - v->PrefillC[k], - v->MaxNumSwC[k], - v->swath_width_luma_ub_this_state[k], - v->swath_width_chroma_ub_this_state[k], - v->SwathHeightYThisState[k], - v->SwathHeightCThisState[k], - v->TWait, - &v->DSTXAfterScaler[k], - &v->DSTYAfterScaler[k], - &v->LineTimesForPrefetch[k], - &v->PrefetchBW[k], - &v->LinesForMetaPTE[k], - &v->LinesForMetaAndDPTERow[k], - &v->VRatioPreY[i][j][k], - &v->VRatioPreC[i][j][k], - &v->RequiredPrefetchPixelDataBWLuma[i][j][k], - &v->RequiredPrefetchPixelDataBWChroma[i][j][k], - &v->NoTimeForDynamicMetadata[i][j][k], - &v->Tno_bw[k], - &v->prefetch_vmrow_bw[k], - &v->dummy7[k], - &v->dummy8[k], - &v->dummy13[k], - &v->VUpdateOffsetPix[k], - &v->VUpdateWidthPix[k], - &v->VReadyOffsetPix[k]); -} - void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib) { struct vba_vars_st *v = &mode_lib->vba; @@ -5121,8 +5083,66 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } } - if (v->UseMinimumRequiredDCFCLK == true) - UseMinimumDCFCLK(mode_lib, MaxPrefetchMode, ReorderingBytes); + if (v->UseMinimumRequiredDCFCLK == true) { + UseMinimumDCFCLK( + mode_lib, + v->MaxInterDCNTileRepeaters, + MaxPrefetchMode, + v->DRAMClockChangeLatency, + v->SREnterPlusExitTime, + v->ReturnBusWidth, + v->RoundTripPingLatencyCycles, + ReorderingBytes, + v->PixelChunkSizeInKByte, + v->MetaChunkSize, + v->GPUVMEnable, + v->GPUVMMaxPageTableLevels, + v->HostVMEnable, + v->NumberOfActivePlanes, + v->HostVMMinPageSize, + v->HostVMMaxNonCachedPageTableLevels, + v->DynamicMetadataVMEnabled, + v->ImmediateFlipRequirement[0], + v->ProgressiveToInterlaceUnitInOPP, + v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation, + v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency, + v->VTotal, + v->VActive, + v->DynamicMetadataTransmittedBytes, + v->DynamicMetadataLinesBeforeActiveRequired, + v->Interlace, + v->RequiredDPPCLK, + v->RequiredDISPCLK, + v->UrgLatency, + v->NoOfDPP, + v->ProjectedDCFCLKDeepSleep, + v->MaximumVStartup, + v->TotalVActivePixelBandwidth, + v->TotalVActiveCursorBandwidth, + v->TotalMetaRowBandwidth, + v->TotalDPTERowBandwidth, + v->TotalNumberOfActiveDPP, + v->TotalNumberOfDCCActiveDPP, + v->dpte_group_bytes, + v->PrefetchLinesY, + v->PrefetchLinesC, + v->swath_width_luma_ub_all_states, + v->swath_width_chroma_ub_all_states, + v->BytePerPixelY, + v->BytePerPixelC, + v->HTotal, + v->PixelClock, + v->PDEAndMetaPTEBytesPerFrame, + v->DPTEBytesPerRow, + v->MetaRowBytes, + v->DynamicMetadataEnable, + v->VActivePixelBandwidth, + v->VActiveCursorBandwidth, + v->ReadBandwidthLuma, + v->ReadBandwidthChroma, + v->DCFCLKPerState, + v->DCFCLKState); + } for (i = 0; i < v->soc.num_states; ++i) { for (j = 0; j <= 1; ++j) { @@ -5260,9 +5280,92 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l v->SREnterPlusExitTime); for (k = 0; k < v->NumberOfActivePlanes; k++) { - CalculatePrefetchSchedulePerPlane(mode_lib, - HostVMInefficiencyFactor, - i, j, k); + Pipe myPipe; + + myPipe.DPPCLK = v->RequiredDPPCLK[i][j][k]; + myPipe.DISPCLK = v->RequiredDISPCLK[i][j]; + myPipe.PixelClock = v->PixelClock[k]; + myPipe.DCFCLKDeepSleep = v->ProjectedDCFCLKDeepSleep[i][j]; + myPipe.DPPPerPlane = v->NoOfDPP[i][j][k]; + myPipe.ScalerEnabled = v->ScalerEnabled[k]; + myPipe.SourceScan = v->SourceScan[k]; + myPipe.BlockWidth256BytesY = v->Read256BlockWidthY[k]; + myPipe.BlockHeight256BytesY = v->Read256BlockHeightY[k]; + myPipe.BlockWidth256BytesC = v->Read256BlockWidthC[k]; + myPipe.BlockHeight256BytesC = v->Read256BlockHeightC[k]; + myPipe.InterlaceEnable = v->Interlace[k]; + myPipe.NumberOfCursors = v->NumberOfCursors[k]; + myPipe.VBlank = v->VTotal[k] - v->VActive[k]; + myPipe.HTotal = v->HTotal[k]; + myPipe.DCCEnable = v->DCCEnable[k]; + myPipe.ODMCombineIsEnabled = v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1 + || v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1; + myPipe.SourcePixelFormat = v->SourcePixelFormat[k]; + myPipe.BytePerPixelY = v->BytePerPixelY[k]; + myPipe.BytePerPixelC = v->BytePerPixelC[k]; + myPipe.ProgressiveToInterlaceUnitInOPP = v->ProgressiveToInterlaceUnitInOPP; + v->NoTimeForPrefetch[i][j][k] = CalculatePrefetchSchedule( + mode_lib, + HostVMInefficiencyFactor, + &myPipe, + v->DSCDelayPerState[i][k], + v->DPPCLKDelaySubtotal + v->DPPCLKDelayCNVCFormater, + v->DPPCLKDelaySCL, + v->DPPCLKDelaySCLLBOnly, + v->DPPCLKDelayCNVCCursor, + v->DISPCLKDelaySubtotal, + v->SwathWidthYThisState[k] / v->HRatio[k], + v->OutputFormat[k], + v->MaxInterDCNTileRepeaters, + dml_min(v->MaxVStartup, v->MaximumVStartup[i][j][k]), + v->MaximumVStartup[i][j][k], + v->GPUVMMaxPageTableLevels, + v->GPUVMEnable, + v->HostVMEnable, + v->HostVMMaxNonCachedPageTableLevels, + v->HostVMMinPageSize, + v->DynamicMetadataEnable[k], + v->DynamicMetadataVMEnabled, + v->DynamicMetadataLinesBeforeActiveRequired[k], + v->DynamicMetadataTransmittedBytes[k], + v->UrgLatency[i], + v->ExtraLatency, + v->TimeCalc, + v->PDEAndMetaPTEBytesPerFrame[i][j][k], + v->MetaRowBytes[i][j][k], + v->DPTEBytesPerRow[i][j][k], + v->PrefetchLinesY[i][j][k], + v->SwathWidthYThisState[k], + v->PrefillY[k], + v->MaxNumSwY[k], + v->PrefetchLinesC[i][j][k], + v->SwathWidthCThisState[k], + v->PrefillC[k], + v->MaxNumSwC[k], + v->swath_width_luma_ub_this_state[k], + v->swath_width_chroma_ub_this_state[k], + v->SwathHeightYThisState[k], + v->SwathHeightCThisState[k], + v->TWait, + &v->DSTXAfterScaler[k], + &v->DSTYAfterScaler[k], + &v->LineTimesForPrefetch[k], + &v->PrefetchBW[k], + &v->LinesForMetaPTE[k], + &v->LinesForMetaAndDPTERow[k], + &v->VRatioPreY[i][j][k], + &v->VRatioPreC[i][j][k], + &v->RequiredPrefetchPixelDataBWLuma[i][j][k], + &v->RequiredPrefetchPixelDataBWChroma[i][j][k], + &v->NoTimeForDynamicMetadata[i][j][k], + &v->Tno_bw[k], + &v->prefetch_vmrow_bw[k], + &v->dummy7[k], + &v->dummy8[k], + &v->dummy13[k], + &v->VUpdateOffsetPix[k], + &v->VUpdateWidthPix[k], + &v->VReadyOffsetPix[k]); } for (k = 0; k < v->NumberOfActivePlanes; k++) { @@ -7150,15 +7253,69 @@ static double CalculateUrgentLatency( static void UseMinimumDCFCLK( struct display_mode_lib *mode_lib, + int MaxInterDCNTileRepeaters, int MaxPrefetchMode, - int ReorderingBytes) + double FinalDRAMClockChangeLatency, + double SREnterPlusExitTime, + int ReturnBusWidth, + int RoundTripPingLatencyCycles, + int ReorderingBytes, + int PixelChunkSizeInKByte, + int MetaChunkSize, + bool GPUVMEnable, + int GPUVMMaxPageTableLevels, + bool HostVMEnable, + int NumberOfActivePlanes, + double HostVMMinPageSize, + int HostVMMaxNonCachedPageTableLevels, + bool DynamicMetadataVMEnabled, + enum immediate_flip_requirement ImmediateFlipRequirement, + bool ProgressiveToInterlaceUnitInOPP, + double MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation, + double PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency, + int VTotal[], + int VActive[], + int DynamicMetadataTransmittedBytes[], + int DynamicMetadataLinesBeforeActiveRequired[], + bool Interlace[], + double RequiredDPPCLK[][2][DC__NUM_DPP__MAX], + double RequiredDISPCLK[][2], + double UrgLatency[], + unsigned int NoOfDPP[][2][DC__NUM_DPP__MAX], + double ProjectedDCFCLKDeepSleep[][2], + double MaximumVStartup[][2][DC__NUM_DPP__MAX], + double TotalVActivePixelBandwidth[][2], + double TotalVActiveCursorBandwidth[][2], + double TotalMetaRowBandwidth[][2], + double TotalDPTERowBandwidth[][2], + unsigned int TotalNumberOfActiveDPP[][2], + unsigned int TotalNumberOfDCCActiveDPP[][2], + int dpte_group_bytes[], + double PrefetchLinesY[][2][DC__NUM_DPP__MAX], + double PrefetchLinesC[][2][DC__NUM_DPP__MAX], + int swath_width_luma_ub_all_states[][2][DC__NUM_DPP__MAX], + int swath_width_chroma_ub_all_states[][2][DC__NUM_DPP__MAX], + int BytePerPixelY[], + int BytePerPixelC[], + int HTotal[], + double PixelClock[], + double PDEAndMetaPTEBytesPerFrame[][2][DC__NUM_DPP__MAX], + double DPTEBytesPerRow[][2][DC__NUM_DPP__MAX], + double MetaRowBytes[][2][DC__NUM_DPP__MAX], + bool DynamicMetadataEnable[], + double VActivePixelBandwidth[][2][DC__NUM_DPP__MAX], + double VActiveCursorBandwidth[][2][DC__NUM_DPP__MAX], + double ReadBandwidthLuma[], + double ReadBandwidthChroma[], + double DCFCLKPerState[], + double DCFCLKState[][2]) { struct vba_vars_st *v = &mode_lib->vba; int dummy1, i, j, k; double NormalEfficiency, dummy2, dummy3; double TotalMaxPrefetchFlipDPTERowBandwidth[DC__VOLTAGE_STATES][2]; - NormalEfficiency = v->PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0; + NormalEfficiency = PercentOfIdealFabricAndSDPPortBWReceivedAfterUrgLatency / 100.0; for (i = 0; i < v->soc.num_states; ++i) { for (j = 0; j <= 1; ++j) { double PixelDCFCLKCyclesRequiredInPrefetch[DC__NUM_DPP__MAX]; @@ -7176,61 +7333,61 @@ static void UseMinimumDCFCLK( double MinimumTvmPlus2Tr0; TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = 0; - for (k = 0; k < v->NumberOfActivePlanes; ++k) { + for (k = 0; k < NumberOfActivePlanes; ++k) { TotalMaxPrefetchFlipDPTERowBandwidth[i][j] = TotalMaxPrefetchFlipDPTERowBandwidth[i][j] - + v->NoOfDPP[i][j][k] * v->DPTEBytesPerRow[i][j][k] / (15.75 * v->HTotal[k] / v->PixelClock[k]); + + NoOfDPP[i][j][k] * DPTEBytesPerRow[i][j][k] / (15.75 * HTotal[k] / PixelClock[k]); } - for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) { - NoOfDPPState[k] = v->NoOfDPP[i][j][k]; + for (k = 0; k <= NumberOfActivePlanes - 1; ++k) { + NoOfDPPState[k] = NoOfDPP[i][j][k]; } - MinimumTWait = CalculateTWait(MaxPrefetchMode, v->FinalDRAMClockChangeLatency, v->UrgLatency[i], v->SREnterPlusExitTime); - NonDPTEBandwidth = v->TotalVActivePixelBandwidth[i][j] + v->TotalVActiveCursorBandwidth[i][j] + v->TotalMetaRowBandwidth[i][j]; - DPTEBandwidth = (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) ? - TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : v->TotalDPTERowBandwidth[i][j]; + MinimumTWait = CalculateTWait(MaxPrefetchMode, FinalDRAMClockChangeLatency, UrgLatency[i], SREnterPlusExitTime); + NonDPTEBandwidth = TotalVActivePixelBandwidth[i][j] + TotalVActiveCursorBandwidth[i][j] + TotalMetaRowBandwidth[i][j]; + DPTEBandwidth = (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) ? + TotalMaxPrefetchFlipDPTERowBandwidth[i][j] : TotalDPTERowBandwidth[i][j]; DCFCLKRequiredForAverageBandwidth = dml_max3( - v->ProjectedDCFCLKDeepSleep[i][j], - (NonDPTEBandwidth + v->TotalDPTERowBandwidth[i][j]) / v->ReturnBusWidth - / (v->MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100), - (NonDPTEBandwidth + DPTEBandwidth / NormalEfficiency) / NormalEfficiency / v->ReturnBusWidth); + ProjectedDCFCLKDeepSleep[i][j], + (NonDPTEBandwidth + TotalDPTERowBandwidth[i][j]) / ReturnBusWidth + / (MaxAveragePercentOfIdealFabricAndSDPPortBWDisplayCanUseInNormalSystemOperation / 100), + (NonDPTEBandwidth + DPTEBandwidth / NormalEfficiency) / NormalEfficiency / ReturnBusWidth); ExtraLatencyBytes = CalculateExtraLatencyBytes( ReorderingBytes, - v->TotalNumberOfActiveDPP[i][j], - v->PixelChunkSizeInKByte, - v->TotalNumberOfDCCActiveDPP[i][j], - v->MetaChunkSize, - v->GPUVMEnable, - v->HostVMEnable, - v->NumberOfActivePlanes, + TotalNumberOfActiveDPP[i][j], + PixelChunkSizeInKByte, + TotalNumberOfDCCActiveDPP[i][j], + MetaChunkSize, + GPUVMEnable, + HostVMEnable, + NumberOfActivePlanes, NoOfDPPState, - v->dpte_group_bytes, + dpte_group_bytes, 1, - v->HostVMMinPageSize, - v->HostVMMaxNonCachedPageTableLevels); - ExtraLatencyCycles = v->RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__ + ExtraLatencyBytes / NormalEfficiency / v->ReturnBusWidth; - for (k = 0; k < v->NumberOfActivePlanes; ++k) { + HostVMMinPageSize, + HostVMMaxNonCachedPageTableLevels); + ExtraLatencyCycles = RoundTripPingLatencyCycles + __DML_ARB_TO_RET_DELAY__ + ExtraLatencyBytes / NormalEfficiency / ReturnBusWidth; + for (k = 0; k < NumberOfActivePlanes; ++k) { double DCFCLKCyclesRequiredInPrefetch; double ExpectedPrefetchBWAcceleration; double PrefetchTime; - PixelDCFCLKCyclesRequiredInPrefetch[k] = (v->PrefetchLinesY[i][j][k] * v->swath_width_luma_ub_all_states[i][j][k] * v->BytePerPixelY[k] - + v->PrefetchLinesC[i][j][k] * v->swath_width_chroma_ub_all_states[i][j][k] * v->BytePerPixelC[k]) / NormalEfficiency / v->ReturnBusWidth; + PixelDCFCLKCyclesRequiredInPrefetch[k] = (PrefetchLinesY[i][j][k] * swath_width_luma_ub_all_states[i][j][k] * BytePerPixelY[k] + + PrefetchLinesC[i][j][k] * swath_width_chroma_ub_all_states[i][j][k] * BytePerPixelC[k]) / NormalEfficiency / ReturnBusWidth; DCFCLKCyclesRequiredInPrefetch = 2 * ExtraLatencyCycles / NoOfDPPState[k] - + v->PDEAndMetaPTEBytesPerFrame[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth * (v->GPUVMMaxPageTableLevels > 2 ? 1 : 0) - + 2 * v->DPTEBytesPerRow[i][j][k] / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth - + 2 * v->MetaRowBytes[i][j][k] / NormalEfficiency / v->ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k]; - PrefetchPixelLinesTime[k] = dml_max(v->PrefetchLinesY[i][j][k], v->PrefetchLinesC[i][j][k]) * v->HTotal[k] / v->PixelClock[k]; - ExpectedPrefetchBWAcceleration = (v->VActivePixelBandwidth[i][j][k] + v->VActiveCursorBandwidth[i][j][k]) - / (v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k]); + + PDEAndMetaPTEBytesPerFrame[i][j][k] / NormalEfficiency / NormalEfficiency / ReturnBusWidth * (GPUVMMaxPageTableLevels > 2 ? 1 : 0) + + 2 * DPTEBytesPerRow[i][j][k] / NormalEfficiency / NormalEfficiency / ReturnBusWidth + + 2 * MetaRowBytes[i][j][k] / NormalEfficiency / ReturnBusWidth + PixelDCFCLKCyclesRequiredInPrefetch[k]; + PrefetchPixelLinesTime[k] = dml_max(PrefetchLinesY[i][j][k], PrefetchLinesC[i][j][k]) * HTotal[k] / PixelClock[k]; + ExpectedPrefetchBWAcceleration = (VActivePixelBandwidth[i][j][k] + VActiveCursorBandwidth[i][j][k]) + / (ReadBandwidthLuma[k] + ReadBandwidthChroma[k]); DynamicMetadataVMExtraLatency[k] = - (v->GPUVMEnable == true && v->DynamicMetadataEnable[k] == true && v->DynamicMetadataVMEnabled == true) ? - v->UrgLatency[i] * v->GPUVMMaxPageTableLevels * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0; - PrefetchTime = (v->MaximumVStartup[i][j][k] - 1) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - - v->UrgLatency[i] - * ((v->GPUVMMaxPageTableLevels <= 2 ? v->GPUVMMaxPageTableLevels : v->GPUVMMaxPageTableLevels - 2) - * (v->HostVMEnable == true ? v->HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) + (GPUVMEnable == true && DynamicMetadataEnable[k] == true && DynamicMetadataVMEnabled == true) ? + UrgLatency[i] * GPUVMMaxPageTableLevels * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) : 0; + PrefetchTime = (MaximumVStartup[i][j][k] - 1) * HTotal[k] / PixelClock[k] - MinimumTWait + - UrgLatency[i] + * ((GPUVMMaxPageTableLevels <= 2 ? GPUVMMaxPageTableLevels : GPUVMMaxPageTableLevels - 2) + * (HostVMEnable == true ? HostVMMaxNonCachedPageTableLevels + 1 : 1) - 1) - DynamicMetadataVMExtraLatency[k]; if (PrefetchTime > 0) { @@ -7239,14 +7396,14 @@ static void UseMinimumDCFCLK( / (PrefetchTime * PixelDCFCLKCyclesRequiredInPrefetch[k] / DCFCLKCyclesRequiredInPrefetch); DCFCLKRequiredForPeakBandwidthPerPlane[k] = NoOfDPPState[k] * PixelDCFCLKCyclesRequiredInPrefetch[k] / PrefetchPixelLinesTime[k] * dml_max(1.0, ExpectedVRatioPrefetch) * dml_max(1.0, ExpectedVRatioPrefetch / 4) * ExpectedPrefetchBWAcceleration; - if (v->HostVMEnable == true || v->ImmediateFlipRequirement[0] == dm_immediate_flip_required) { + if (HostVMEnable == true || ImmediateFlipRequirement == dm_immediate_flip_required) { DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKRequiredForPeakBandwidthPerPlane[k] - + NoOfDPPState[k] * DPTEBandwidth / NormalEfficiency / NormalEfficiency / v->ReturnBusWidth; + + NoOfDPPState[k] * DPTEBandwidth / NormalEfficiency / NormalEfficiency / ReturnBusWidth; } } else { - DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i]; } - if (v->DynamicMetadataEnable[k] == true) { + if (DynamicMetadataEnable[k] == true) { double TSetupPipe; double TdmbfPipe; double TdmsksPipe; @@ -7254,17 +7411,17 @@ static void UseMinimumDCFCLK( double AllowedTimeForUrgentExtraLatency; CalculateVupdateAndDynamicMetadataParameters( - v->MaxInterDCNTileRepeaters, - v->RequiredDPPCLK[i][j][k], - v->RequiredDISPCLK[i][j], - v->ProjectedDCFCLKDeepSleep[i][j], - v->PixelClock[k], - v->HTotal[k], - v->VTotal[k] - v->VActive[k], - v->DynamicMetadataTransmittedBytes[k], - v->DynamicMetadataLinesBeforeActiveRequired[k], - v->Interlace[k], - v->ProgressiveToInterlaceUnitInOPP, + MaxInterDCNTileRepeaters, + RequiredDPPCLK[i][j][k], + RequiredDISPCLK[i][j], + ProjectedDCFCLKDeepSleep[i][j], + PixelClock[k], + HTotal[k], + VTotal[k] - VActive[k], + DynamicMetadataTransmittedBytes[k], + DynamicMetadataLinesBeforeActiveRequired[k], + Interlace[k], + ProgressiveToInterlaceUnitInOPP, &TSetupPipe, &TdmbfPipe, &TdmecPipe, @@ -7272,31 +7429,31 @@ static void UseMinimumDCFCLK( &dummy1, &dummy2, &dummy3); - AllowedTimeForUrgentExtraLatency = v->MaximumVStartup[i][j][k] * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - TSetupPipe - TdmbfPipe - TdmecPipe + AllowedTimeForUrgentExtraLatency = MaximumVStartup[i][j][k] * HTotal[k] / PixelClock[k] - MinimumTWait - TSetupPipe - TdmbfPipe - TdmecPipe - TdmsksPipe - DynamicMetadataVMExtraLatency[k]; if (AllowedTimeForUrgentExtraLatency > 0) { DCFCLKRequiredForPeakBandwidthPerPlane[k] = dml_max( DCFCLKRequiredForPeakBandwidthPerPlane[k], ExtraLatencyCycles / AllowedTimeForUrgentExtraLatency); } else { - DCFCLKRequiredForPeakBandwidthPerPlane[k] = v->DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidthPerPlane[k] = DCFCLKPerState[i]; } } } DCFCLKRequiredForPeakBandwidth = 0; - for (k = 0; k <= v->NumberOfActivePlanes - 1; ++k) { + for (k = 0; k <= NumberOfActivePlanes - 1; ++k) { DCFCLKRequiredForPeakBandwidth = DCFCLKRequiredForPeakBandwidth + DCFCLKRequiredForPeakBandwidthPerPlane[k]; } - MinimumTvmPlus2Tr0 = v->UrgLatency[i] - * (v->GPUVMEnable == true ? - (v->HostVMEnable == true ? - (v->GPUVMMaxPageTableLevels + 2) * (v->HostVMMaxNonCachedPageTableLevels + 1) - 1 : v->GPUVMMaxPageTableLevels + 1) : + MinimumTvmPlus2Tr0 = UrgLatency[i] + * (GPUVMEnable == true ? + (HostVMEnable == true ? + (GPUVMMaxPageTableLevels + 2) * (HostVMMaxNonCachedPageTableLevels + 1) - 1 : GPUVMMaxPageTableLevels + 1) : 0); - for (k = 0; k < v->NumberOfActivePlanes; ++k) { + for (k = 0; k < NumberOfActivePlanes; ++k) { double MaximumTvmPlus2Tr0PlusTsw; - MaximumTvmPlus2Tr0PlusTsw = (v->MaximumVStartup[i][j][k] - 2) * v->HTotal[k] / v->PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k]; + MaximumTvmPlus2Tr0PlusTsw = (MaximumVStartup[i][j][k] - 2) * HTotal[k] / PixelClock[k] - MinimumTWait - DynamicMetadataVMExtraLatency[k]; if (MaximumTvmPlus2Tr0PlusTsw <= MinimumTvmPlus2Tr0 + PrefetchPixelLinesTime[k] / 4) { - DCFCLKRequiredForPeakBandwidth = v->DCFCLKPerState[i]; + DCFCLKRequiredForPeakBandwidth = DCFCLKPerState[i]; } else { DCFCLKRequiredForPeakBandwidth = dml_max3( DCFCLKRequiredForPeakBandwidth, @@ -7304,7 +7461,7 @@ static void UseMinimumDCFCLK( (2 * ExtraLatencyCycles + PixelDCFCLKCyclesRequiredInPrefetch[k]) / (MaximumTvmPlus2Tr0PlusTsw - MinimumTvmPlus2Tr0)); } } - v->DCFCLKState[i][j] = dml_min(v->DCFCLKPerState[i], 1.05 * dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth)); + DCFCLKState[i][j] = dml_min(DCFCLKPerState[i], 1.05 * dml_max(DCFCLKRequiredForAverageBandwidth, DCFCLKRequiredForPeakBandwidth)); } } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c index e0fecf127b..57bd4e3f8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c @@ -175,47 +175,47 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si return (4 * 1024); } -static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, const display_data_rq_sizing_params_st *rq_sizing) +static void extract_rq_sizing_regs(struct display_mode_lib *mode_lib, display_data_rq_regs_st *rq_regs, const display_data_rq_sizing_params_st rq_sizing) { print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } -static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_rq_params_st *rq_param) +static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); - rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_l.dpte_row_height), 1) - 3; + rq_regs->rq_regs_l.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_l.dpte_row_height), 1) - 3; - if (rq_param->yuv420) { - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); - rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param->dlg.rq_c.dpte_row_height), 1) - 3; + if (rq_param.yuv420) { + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); + rq_regs->rq_regs_c.pte_row_height_linear = dml_floor(dml_log2(rq_param.dlg.rq_c.dpte_row_height), 1) - 3; } - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); // FIXME: take the max between luma, chroma chunk size? // okay for now, as we are setting chunk_bytes to 8kb anyways - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param->yuv420 && rq_param->sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024 || (rq_param.yuv420 && rq_param.sizing.rq_c.chunk_bytes >= 32 * 1024)) { //32kb rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -225,8 +225,8 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_s rq_regs->crq_expansion_mode = 1; // Note: detile_buf_plane1_addr is in unit of 1KB - if (rq_param->yuv420) { - if ((double) rq_param->misc.rq_l.stored_swath_bytes / (double) rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 1024.0); // half to chroma #ifdef __DML_RQ_DLG_CALC_DEBUG__ dml_print("DML_DLG: %s: detile_buf_plane1_addr = %0d (1/2 to chroma)\n", __func__, detile_buf_plane1_addr); @@ -244,14 +244,14 @@ static void extract_rq_regs(struct display_mode_lib *mode_lib, display_rq_regs_s dml_print("DML_DLG: %s: detile_buf_size_in_bytes = %0d\n", __func__, detile_buf_size_in_bytes); dml_print("DML_DLG: %s: detile_buf_plane1_addr = %0d\n", __func__, detile_buf_plane1_addr); dml_print("DML_DLG: %s: plane1_base_address = %0d\n", __func__, rq_regs->plane1_base_address); - dml_print("DML_DLG: %s: rq_l.stored_swath_bytes = %0d\n", __func__, rq_param->misc.rq_l.stored_swath_bytes); - dml_print("DML_DLG: %s: rq_c.stored_swath_bytes = %0d\n", __func__, rq_param->misc.rq_c.stored_swath_bytes); - dml_print("DML_DLG: %s: rq_l.swath_height = %0d\n", __func__, rq_param->dlg.rq_l.swath_height); - dml_print("DML_DLG: %s: rq_c.swath_height = %0d\n", __func__, rq_param->dlg.rq_c.swath_height); + dml_print("DML_DLG: %s: rq_l.stored_swath_bytes = %0d\n", __func__, rq_param.misc.rq_l.stored_swath_bytes); + dml_print("DML_DLG: %s: rq_c.stored_swath_bytes = %0d\n", __func__, rq_param.misc.rq_c.stored_swath_bytes); + dml_print("DML_DLG: %s: rq_l.swath_height = %0d\n", __func__, rq_param.dlg.rq_l.swath_height); + dml_print("DML_DLG: %s: rq_c.swath_height = %0d\n", __func__, rq_param.dlg.rq_c.swath_height); #endif } -static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_source_params_st *pipe_src_param) +static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -260,8 +260,8 @@ static void handle_det_buf_split(struct display_mode_lib *mode_lib, display_rq_p unsigned int full_swath_bytes_packed_c = 0; bool req128_l = 0; bool req128_c = 0; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -849,8 +849,8 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_ } // calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, &pipe_param->src); - print__rq_params_st(mode_lib, rq_param); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); + print__rq_params_st(mode_lib, *rq_param); } void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st *pipe_param) @@ -859,9 +859,9 @@ void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_ memset(rq_regs, 0, sizeof(*rq_regs)); dml_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param); - extract_rq_regs(mode_lib, rq_regs, &rq_param); + extract_rq_regs(mode_lib, rq_regs, rq_param); - print__rq_regs_st(mode_lib, rq_regs); + print__rq_regs_st(mode_lib, *rq_regs); } static void calculate_ttu_cursor( @@ -943,8 +943,8 @@ static void dml_rq_dlg_get_dlg_params( const unsigned int pipe_idx, display_dlg_regs_st *disp_dlg_regs, display_ttu_regs_st *disp_ttu_regs, - const display_rq_dlg_params_st *rq_dlg_param, - const display_dlg_sys_params_st *dlg_sys_param, + const display_rq_dlg_params_st rq_dlg_param, + const display_dlg_sys_params_st dlg_sys_param, const bool cstate_en, const bool pstate_en, const bool vm_en, @@ -1112,13 +1112,13 @@ static void dml_rq_dlg_get_dlg_params( vratio_c = scl->vscl_ratio_c; scl_enable = scl->scl_enable; - swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; - dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; - swath_width_ub_c = rq_dlg_param->rq_c.swath_width_ub; - dpte_groups_per_row_ub_c = rq_dlg_param->rq_c.dpte_groups_per_row_ub; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; - meta_chunks_per_row_ub_l = rq_dlg_param->rq_l.meta_chunks_per_row_ub; - meta_chunks_per_row_ub_c = rq_dlg_param->rq_c.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + meta_chunks_per_row_ub_c = rq_dlg_param.rq_c.meta_chunks_per_row_ub; vupdate_offset = dst->vupdate_offset; vupdate_width = dst->vupdate_width; vready_offset = dst->vready_offset; @@ -1239,16 +1239,16 @@ static void dml_rq_dlg_get_dlg_params( dml_print("DML_DLG: %s: vratio_pre_c = %3.2f\n", __func__, vratio_pre_c); // Active - req_per_swath_ub_l = rq_dlg_param->rq_l.req_per_swath_ub; - req_per_swath_ub_c = rq_dlg_param->rq_c.req_per_swath_ub; - meta_row_height_l = rq_dlg_param->rq_l.meta_row_height; - meta_row_height_c = rq_dlg_param->rq_c.meta_row_height; + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; + meta_row_height_c = rq_dlg_param.rq_c.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; scaler_rec_in_width_c = 0; - dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; - dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; if (mode_422) { swath_width_pixels_ub_l = swath_width_ub_l * 2; // *2 for 2 pixel per element @@ -1669,8 +1669,8 @@ static void dml_rq_dlg_get_dlg_params( disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } void dml31_rq_dlg_get_dlg_reg( @@ -1699,7 +1699,7 @@ void dml31_rq_dlg_get_dlg_reg( dlg_sys_param.total_flip_bw = get_total_immediate_flip_bw(mode_lib, e2e_pipe_param, num_pipes); dlg_sys_param.total_flip_bytes = get_total_immediate_flip_bytes(mode_lib, e2e_pipe_param, num_pipes); - print__dlg_sys_params_st(mode_lib, &dlg_sys_param); + print__dlg_sys_params_st(mode_lib, dlg_sys_param); // system parameter calculation done @@ -1712,8 +1712,8 @@ void dml31_rq_dlg_get_dlg_reg( pipe_idx, dlg_regs, ttu_regs, - &rq_param.dlg, - &dlg_sys_param, + rq_param.dlg, + dlg_sys_param, cstate_en, pstate_en, vm_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c index 30db51fbd8..8a5bd919ae 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.c @@ -82,7 +82,6 @@ void dml_init_instance(struct display_mode_lib *lib, lib->project = project; switch (project) { case DML_PROJECT_NAVI10: - case DML_PROJECT_DCN201: lib->funcs = dml20_funcs; break; case DML_PROJECT_NAVI10v2: diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index d76251fd15..72b1957022 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -36,7 +36,6 @@ enum dml_project { DML_PROJECT_RAVEN1, DML_PROJECT_NAVI10, DML_PROJECT_NAVI10v2, - DML_PROJECT_DCN201, DML_PROJECT_DCN21, DML_PROJECT_DCN30, DML_PROJECT_DCN31, @@ -73,7 +72,6 @@ struct display_mode_lib { struct vba_vars_st vba; struct dal_logger *logger; struct dml_funcs funcs; - struct _vcs_dpi_display_e2e_pipe_params_st dml_pipe_state[6]; }; void dml_init_instance(struct display_mode_lib *lib, diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h index 8f9f1d607f..d46a273302 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h @@ -546,6 +546,7 @@ struct _vcs_dpi_display_dlg_sys_params_st { double t_sr_wm_us; double t_extra_us; double mem_trip_us; + double t_srx_delay_us; double deepsleep_dcfclk_mhz; double total_flip_bw; unsigned int total_flip_bytes; diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c index 412e75eb47..e2d82aacd3 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.c @@ -26,368 +26,371 @@ #include "display_rq_dlg_helpers.h" #include "dml_logger.h" -void print__rq_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_params_st *rq_param) +void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param) { dml_print("DML_RQ_DLG_CALC: ***************************\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_PARAM_ST\n"); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_sizing_params_st(mode_lib, &rq_param->sizing.rq_l); + print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_l); dml_print("DML_RQ_DLG_CALC: ===\n"); - print__data_rq_sizing_params_st(mode_lib, &rq_param->sizing.rq_c); + print__data_rq_sizing_params_st(mode_lib, rq_param.sizing.rq_c); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_dlg_params_st(mode_lib, &rq_param->dlg.rq_l); + print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_l); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_dlg_params_st(mode_lib, &rq_param->dlg.rq_c); + print__data_rq_dlg_params_st(mode_lib, rq_param.dlg.rq_c); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_misc_params_st(mode_lib, &rq_param->misc.rq_l); + print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_l); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_misc_params_st(mode_lib, &rq_param->misc.rq_c); + print__data_rq_misc_params_st(mode_lib, rq_param.misc.rq_c); dml_print("DML_RQ_DLG_CALC: ***************************\n"); } -void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing) +void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_SIZING_PARAM_ST\n"); - dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing->chunk_bytes); - dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing->min_chunk_bytes); - dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing->meta_chunk_bytes); + dml_print("DML_RQ_DLG_CALC: chunk_bytes = %0d\n", rq_sizing.chunk_bytes); + dml_print("DML_RQ_DLG_CALC: min_chunk_bytes = %0d\n", rq_sizing.min_chunk_bytes); + dml_print("DML_RQ_DLG_CALC: meta_chunk_bytes = %0d\n", rq_sizing.meta_chunk_bytes); dml_print( "DML_RQ_DLG_CALC: min_meta_chunk_bytes = %0d\n", - rq_sizing->min_meta_chunk_bytes); - dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing->mpte_group_bytes); - dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing->dpte_group_bytes); + rq_sizing.min_meta_chunk_bytes); + dml_print("DML_RQ_DLG_CALC: mpte_group_bytes = %0d\n", rq_sizing.mpte_group_bytes); + dml_print("DML_RQ_DLG_CALC: dpte_group_bytes = %0d\n", rq_sizing.dpte_group_bytes); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param) +void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_DLG_PARAM_ST\n"); dml_print( "DML_RQ_DLG_CALC: swath_width_ub = %0d\n", - rq_dlg_param->swath_width_ub); + rq_dlg_param.swath_width_ub); dml_print( "DML_RQ_DLG_CALC: swath_height = %0d\n", - rq_dlg_param->swath_height); + rq_dlg_param.swath_height); dml_print( "DML_RQ_DLG_CALC: req_per_swath_ub = %0d\n", - rq_dlg_param->req_per_swath_ub); + rq_dlg_param.req_per_swath_ub); dml_print( "DML_RQ_DLG_CALC: meta_pte_bytes_per_frame_ub = %0d\n", - rq_dlg_param->meta_pte_bytes_per_frame_ub); + rq_dlg_param.meta_pte_bytes_per_frame_ub); dml_print( "DML_RQ_DLG_CALC: dpte_req_per_row_ub = %0d\n", - rq_dlg_param->dpte_req_per_row_ub); + rq_dlg_param.dpte_req_per_row_ub); dml_print( "DML_RQ_DLG_CALC: dpte_groups_per_row_ub = %0d\n", - rq_dlg_param->dpte_groups_per_row_ub); + rq_dlg_param.dpte_groups_per_row_ub); dml_print( "DML_RQ_DLG_CALC: dpte_row_height = %0d\n", - rq_dlg_param->dpte_row_height); + rq_dlg_param.dpte_row_height); dml_print( "DML_RQ_DLG_CALC: dpte_bytes_per_row_ub = %0d\n", - rq_dlg_param->dpte_bytes_per_row_ub); + rq_dlg_param.dpte_bytes_per_row_ub); dml_print( "DML_RQ_DLG_CALC: meta_chunks_per_row_ub = %0d\n", - rq_dlg_param->meta_chunks_per_row_ub); + rq_dlg_param.meta_chunks_per_row_ub); dml_print( "DML_RQ_DLG_CALC: meta_req_per_row_ub = %0d\n", - rq_dlg_param->meta_req_per_row_ub); + rq_dlg_param.meta_req_per_row_ub); dml_print( "DML_RQ_DLG_CALC: meta_row_height = %0d\n", - rq_dlg_param->meta_row_height); + rq_dlg_param.meta_row_height); dml_print( "DML_RQ_DLG_CALC: meta_bytes_per_row_ub = %0d\n", - rq_dlg_param->meta_bytes_per_row_ub); + rq_dlg_param.meta_bytes_per_row_ub); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param) +void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_MISC_PARAM_ST\n"); dml_print( "DML_RQ_DLG_CALC: full_swath_bytes = %0d\n", - rq_misc_param->full_swath_bytes); + rq_misc_param.full_swath_bytes); dml_print( "DML_RQ_DLG_CALC: stored_swath_bytes = %0d\n", - rq_misc_param->stored_swath_bytes); - dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param->blk256_width); - dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param->blk256_height); - dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param->req_width); - dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param->req_height); + rq_misc_param.stored_swath_bytes); + dml_print("DML_RQ_DLG_CALC: blk256_width = %0d\n", rq_misc_param.blk256_width); + dml_print("DML_RQ_DLG_CALC: blk256_height = %0d\n", rq_misc_param.blk256_height); + dml_print("DML_RQ_DLG_CALC: req_width = %0d\n", rq_misc_param.req_width); + dml_print("DML_RQ_DLG_CALC: req_height = %0d\n", rq_misc_param.req_height); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param) +void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_dlg_params_st(mode_lib, &rq_dlg_param->rq_l); + print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_l); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_dlg_params_st(mode_lib, &rq_dlg_param->rq_c); + print__data_rq_dlg_params_st(mode_lib, rq_dlg_param.rq_c); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param) +void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_DLG_PARAM_ST\n"); - dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param->t_mclk_wm_us); - dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param->t_urg_wm_us); - dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param->t_sr_wm_us); - dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param->t_extra_us); + dml_print("DML_RQ_DLG_CALC: t_mclk_wm_us = %3.2f\n", dlg_sys_param.t_mclk_wm_us); + dml_print("DML_RQ_DLG_CALC: t_urg_wm_us = %3.2f\n", dlg_sys_param.t_urg_wm_us); + dml_print("DML_RQ_DLG_CALC: t_sr_wm_us = %3.2f\n", dlg_sys_param.t_sr_wm_us); + dml_print("DML_RQ_DLG_CALC: t_extra_us = %3.2f\n", dlg_sys_param.t_extra_us); + dml_print( + "DML_RQ_DLG_CALC: t_srx_delay_us = %3.2f\n", + dlg_sys_param.t_srx_delay_us); dml_print( "DML_RQ_DLG_CALC: deepsleep_dcfclk_mhz = %3.2f\n", - dlg_sys_param->deepsleep_dcfclk_mhz); + dlg_sys_param.deepsleep_dcfclk_mhz); dml_print( "DML_RQ_DLG_CALC: total_flip_bw = %3.2f\n", - dlg_sys_param->total_flip_bw); + dlg_sys_param.total_flip_bw); dml_print( "DML_RQ_DLG_CALC: total_flip_bytes = %i\n", - dlg_sys_param->total_flip_bytes); + dlg_sys_param.total_flip_bytes); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__data_rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_regs_st *rq_regs) +void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st rq_regs) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_DATA_RQ_REGS_ST\n"); - dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs->chunk_size); - dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs->min_chunk_size); - dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs->meta_chunk_size); + dml_print("DML_RQ_DLG_CALC: chunk_size = 0x%0x\n", rq_regs.chunk_size); + dml_print("DML_RQ_DLG_CALC: min_chunk_size = 0x%0x\n", rq_regs.min_chunk_size); + dml_print("DML_RQ_DLG_CALC: meta_chunk_size = 0x%0x\n", rq_regs.meta_chunk_size); dml_print( "DML_RQ_DLG_CALC: min_meta_chunk_size = 0x%0x\n", - rq_regs->min_meta_chunk_size); - dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs->dpte_group_size); - dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs->mpte_group_size); - dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs->swath_height); + rq_regs.min_meta_chunk_size); + dml_print("DML_RQ_DLG_CALC: dpte_group_size = 0x%0x\n", rq_regs.dpte_group_size); + dml_print("DML_RQ_DLG_CALC: mpte_group_size = 0x%0x\n", rq_regs.mpte_group_size); + dml_print("DML_RQ_DLG_CALC: swath_height = 0x%0x\n", rq_regs.swath_height); dml_print( "DML_RQ_DLG_CALC: pte_row_height_linear = 0x%0x\n", - rq_regs->pte_row_height_linear); + rq_regs.pte_row_height_linear); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_regs_st *rq_regs) +void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_RQ_REGS_ST\n"); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_regs_st(mode_lib, &rq_regs->rq_regs_l); + print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_l); dml_print("DML_RQ_DLG_CALC: \n"); - print__data_rq_regs_st(mode_lib, &rq_regs->rq_regs_c); - dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs->drq_expansion_mode); - dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs->prq_expansion_mode); - dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs->mrq_expansion_mode); - dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs->crq_expansion_mode); - dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs->plane1_base_address); + print__data_rq_regs_st(mode_lib, rq_regs.rq_regs_c); + dml_print("DML_RQ_DLG_CALC: drq_expansion_mode = 0x%0x\n", rq_regs.drq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: prq_expansion_mode = 0x%0x\n", rq_regs.prq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: mrq_expansion_mode = 0x%0x\n", rq_regs.mrq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: crq_expansion_mode = 0x%0x\n", rq_regs.crq_expansion_mode); + dml_print("DML_RQ_DLG_CALC: plane1_base_address = 0x%0x\n", rq_regs.plane1_base_address); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__dlg_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_regs_st *dlg_regs) +void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_DLG_REGS_ST\n"); dml_print( "DML_RQ_DLG_CALC: refcyc_h_blank_end = 0x%0x\n", - dlg_regs->refcyc_h_blank_end); + dlg_regs.refcyc_h_blank_end); dml_print( "DML_RQ_DLG_CALC: dlg_vblank_end = 0x%0x\n", - dlg_regs->dlg_vblank_end); + dlg_regs.dlg_vblank_end); dml_print( "DML_RQ_DLG_CALC: min_dst_y_next_start = 0x%0x\n", - dlg_regs->min_dst_y_next_start); + dlg_regs.min_dst_y_next_start); dml_print( "DML_RQ_DLG_CALC: refcyc_per_htotal = 0x%0x\n", - dlg_regs->refcyc_per_htotal); + dlg_regs.refcyc_per_htotal); dml_print( "DML_RQ_DLG_CALC: refcyc_x_after_scaler = 0x%0x\n", - dlg_regs->refcyc_x_after_scaler); + dlg_regs.refcyc_x_after_scaler); dml_print( "DML_RQ_DLG_CALC: dst_y_after_scaler = 0x%0x\n", - dlg_regs->dst_y_after_scaler); + dlg_regs.dst_y_after_scaler); dml_print( "DML_RQ_DLG_CALC: dst_y_prefetch = 0x%0x\n", - dlg_regs->dst_y_prefetch); + dlg_regs.dst_y_prefetch); dml_print( "DML_RQ_DLG_CALC: dst_y_per_vm_vblank = 0x%0x\n", - dlg_regs->dst_y_per_vm_vblank); + dlg_regs.dst_y_per_vm_vblank); dml_print( "DML_RQ_DLG_CALC: dst_y_per_row_vblank = 0x%0x\n", - dlg_regs->dst_y_per_row_vblank); + dlg_regs.dst_y_per_row_vblank); dml_print( "DML_RQ_DLG_CALC: dst_y_per_vm_flip = 0x%0x\n", - dlg_regs->dst_y_per_vm_flip); + dlg_regs.dst_y_per_vm_flip); dml_print( "DML_RQ_DLG_CALC: dst_y_per_row_flip = 0x%0x\n", - dlg_regs->dst_y_per_row_flip); + dlg_regs.dst_y_per_row_flip); dml_print( "DML_RQ_DLG_CALC: ref_freq_to_pix_freq = 0x%0x\n", - dlg_regs->ref_freq_to_pix_freq); + dlg_regs.ref_freq_to_pix_freq); dml_print( "DML_RQ_DLG_CALC: vratio_prefetch = 0x%0x\n", - dlg_regs->vratio_prefetch); + dlg_regs.vratio_prefetch); dml_print( "DML_RQ_DLG_CALC: vratio_prefetch_c = 0x%0x\n", - dlg_regs->vratio_prefetch_c); + dlg_regs.vratio_prefetch_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_l = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_vblank_l); + dlg_regs.refcyc_per_pte_group_vblank_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_vblank_c = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_vblank_c); + dlg_regs.refcyc_per_pte_group_vblank_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_l = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_vblank_l); + dlg_regs.refcyc_per_meta_chunk_vblank_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_vblank_c = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_vblank_c); + dlg_regs.refcyc_per_meta_chunk_vblank_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_l = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_flip_l); + dlg_regs.refcyc_per_pte_group_flip_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_flip_c = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_flip_c); + dlg_regs.refcyc_per_pte_group_flip_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_l = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_flip_l); + dlg_regs.refcyc_per_meta_chunk_flip_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_flip_c = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_flip_c); + dlg_regs.refcyc_per_meta_chunk_flip_c); dml_print( "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_l = 0x%0x\n", - dlg_regs->dst_y_per_pte_row_nom_l); + dlg_regs.dst_y_per_pte_row_nom_l); dml_print( "DML_RQ_DLG_CALC: dst_y_per_pte_row_nom_c = 0x%0x\n", - dlg_regs->dst_y_per_pte_row_nom_c); + dlg_regs.dst_y_per_pte_row_nom_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_l = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_nom_l); + dlg_regs.refcyc_per_pte_group_nom_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_pte_group_nom_c = 0x%0x\n", - dlg_regs->refcyc_per_pte_group_nom_c); + dlg_regs.refcyc_per_pte_group_nom_c); dml_print( "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_l = 0x%0x\n", - dlg_regs->dst_y_per_meta_row_nom_l); + dlg_regs.dst_y_per_meta_row_nom_l); dml_print( "DML_RQ_DLG_CALC: dst_y_per_meta_row_nom_c = 0x%0x\n", - dlg_regs->dst_y_per_meta_row_nom_c); + dlg_regs.dst_y_per_meta_row_nom_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_l = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_nom_l); + dlg_regs.refcyc_per_meta_chunk_nom_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_meta_chunk_nom_c = 0x%0x\n", - dlg_regs->refcyc_per_meta_chunk_nom_c); + dlg_regs.refcyc_per_meta_chunk_nom_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_l = 0x%0x\n", - dlg_regs->refcyc_per_line_delivery_pre_l); + dlg_regs.refcyc_per_line_delivery_pre_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_line_delivery_pre_c = 0x%0x\n", - dlg_regs->refcyc_per_line_delivery_pre_c); + dlg_regs.refcyc_per_line_delivery_pre_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_line_delivery_l = 0x%0x\n", - dlg_regs->refcyc_per_line_delivery_l); + dlg_regs.refcyc_per_line_delivery_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_line_delivery_c = 0x%0x\n", - dlg_regs->refcyc_per_line_delivery_c); + dlg_regs.refcyc_per_line_delivery_c); dml_print( "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur0 = 0x%0x\n", - dlg_regs->chunk_hdl_adjust_cur0); + dlg_regs.chunk_hdl_adjust_cur0); dml_print( "DML_RQ_DLG_CALC: dst_y_offset_cur1 = 0x%0x\n", - dlg_regs->dst_y_offset_cur1); + dlg_regs.dst_y_offset_cur1); dml_print( "DML_RQ_DLG_CALC: chunk_hdl_adjust_cur1 = 0x%0x\n", - dlg_regs->chunk_hdl_adjust_cur1); + dlg_regs.chunk_hdl_adjust_cur1); dml_print( "DML_RQ_DLG_CALC: vready_after_vcount0 = 0x%0x\n", - dlg_regs->vready_after_vcount0); + dlg_regs.vready_after_vcount0); dml_print( "DML_RQ_DLG_CALC: dst_y_delta_drq_limit = 0x%0x\n", - dlg_regs->dst_y_delta_drq_limit); + dlg_regs.dst_y_delta_drq_limit); dml_print( "DML_RQ_DLG_CALC: xfc_reg_transfer_delay = 0x%0x\n", - dlg_regs->xfc_reg_transfer_delay); + dlg_regs.xfc_reg_transfer_delay); dml_print( "DML_RQ_DLG_CALC: xfc_reg_precharge_delay = 0x%0x\n", - dlg_regs->xfc_reg_precharge_delay); + dlg_regs.xfc_reg_precharge_delay); dml_print( "DML_RQ_DLG_CALC: xfc_reg_remote_surface_flip_latency = 0x%0x\n", - dlg_regs->xfc_reg_remote_surface_flip_latency); + dlg_regs.xfc_reg_remote_surface_flip_latency); dml_print( "DML_RQ_DLG_CALC: refcyc_per_vm_dmdata = 0x%0x\n", - dlg_regs->refcyc_per_vm_dmdata); + dlg_regs.refcyc_per_vm_dmdata); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } -void print__ttu_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_ttu_regs_st *ttu_regs) +void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs) { dml_print("DML_RQ_DLG_CALC: =====================================\n"); dml_print("DML_RQ_DLG_CALC: DISPLAY_TTU_REGS_ST\n"); dml_print( "DML_RQ_DLG_CALC: qos_level_low_wm = 0x%0x\n", - ttu_regs->qos_level_low_wm); + ttu_regs.qos_level_low_wm); dml_print( "DML_RQ_DLG_CALC: qos_level_high_wm = 0x%0x\n", - ttu_regs->qos_level_high_wm); + ttu_regs.qos_level_high_wm); dml_print( "DML_RQ_DLG_CALC: min_ttu_vblank = 0x%0x\n", - ttu_regs->min_ttu_vblank); + ttu_regs.min_ttu_vblank); dml_print( "DML_RQ_DLG_CALC: qos_level_flip = 0x%0x\n", - ttu_regs->qos_level_flip); + ttu_regs.qos_level_flip); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_l = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_pre_l); + ttu_regs.refcyc_per_req_delivery_pre_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_l = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_l); + ttu_regs.refcyc_per_req_delivery_l); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_c = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_pre_c); + ttu_regs.refcyc_per_req_delivery_pre_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_c = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_c); + ttu_regs.refcyc_per_req_delivery_c); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur0 = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_cur0); + ttu_regs.refcyc_per_req_delivery_cur0); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur0 = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_pre_cur0); + ttu_regs.refcyc_per_req_delivery_pre_cur0); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_cur1 = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_cur1); + ttu_regs.refcyc_per_req_delivery_cur1); dml_print( "DML_RQ_DLG_CALC: refcyc_per_req_delivery_pre_cur1 = 0x%0x\n", - ttu_regs->refcyc_per_req_delivery_pre_cur1); + ttu_regs.refcyc_per_req_delivery_pre_cur1); dml_print( "DML_RQ_DLG_CALC: qos_level_fixed_l = 0x%0x\n", - ttu_regs->qos_level_fixed_l); + ttu_regs.qos_level_fixed_l); dml_print( "DML_RQ_DLG_CALC: qos_ramp_disable_l = 0x%0x\n", - ttu_regs->qos_ramp_disable_l); + ttu_regs.qos_ramp_disable_l); dml_print( "DML_RQ_DLG_CALC: qos_level_fixed_c = 0x%0x\n", - ttu_regs->qos_level_fixed_c); + ttu_regs.qos_level_fixed_c); dml_print( "DML_RQ_DLG_CALC: qos_ramp_disable_c = 0x%0x\n", - ttu_regs->qos_ramp_disable_c); + ttu_regs.qos_ramp_disable_c); dml_print( "DML_RQ_DLG_CALC: qos_level_fixed_cur0 = 0x%0x\n", - ttu_regs->qos_level_fixed_cur0); + ttu_regs.qos_level_fixed_cur0); dml_print( "DML_RQ_DLG_CALC: qos_ramp_disable_cur0 = 0x%0x\n", - ttu_regs->qos_ramp_disable_cur0); + ttu_regs.qos_ramp_disable_cur0); dml_print( "DML_RQ_DLG_CALC: qos_level_fixed_cur1 = 0x%0x\n", - ttu_regs->qos_level_fixed_cur1); + ttu_regs.qos_level_fixed_cur1); dml_print( "DML_RQ_DLG_CALC: qos_ramp_disable_cur1 = 0x%0x\n", - ttu_regs->qos_ramp_disable_cur1); + ttu_regs.qos_ramp_disable_cur1); dml_print("DML_RQ_DLG_CALC: =====================================\n"); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h index ebcd717744..2555ef0358 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_rq_dlg_helpers.h @@ -31,16 +31,16 @@ /* Function: Printer functions * Print various struct */ -void print__rq_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_params_st *rq_param); -void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing); -void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param); -void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param); -void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param); -void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param); +void print__rq_params_st(struct display_mode_lib *mode_lib, display_rq_params_st rq_param); +void print__data_rq_sizing_params_st(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st rq_sizing); +void print__data_rq_dlg_params_st(struct display_mode_lib *mode_lib, display_data_rq_dlg_params_st rq_dlg_param); +void print__data_rq_misc_params_st(struct display_mode_lib *mode_lib, display_data_rq_misc_params_st rq_misc_param); +void print__rq_dlg_params_st(struct display_mode_lib *mode_lib, display_rq_dlg_params_st rq_dlg_param); +void print__dlg_sys_params_st(struct display_mode_lib *mode_lib, display_dlg_sys_params_st dlg_sys_param); -void print__data_rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_data_rq_regs_st *rq_regs); -void print__rq_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_rq_regs_st *rq_regs); -void print__dlg_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_dlg_regs_st *dlg_regs); -void print__ttu_regs_st(struct display_mode_lib *mode_lib, const struct _vcs_dpi_display_ttu_regs_st *ttu_regs); +void print__data_rq_regs_st(struct display_mode_lib *mode_lib, display_data_rq_regs_st data_rq_regs); +void print__rq_regs_st(struct display_mode_lib *mode_lib, display_rq_regs_st rq_regs); +void print__dlg_regs_st(struct display_mode_lib *mode_lib, display_dlg_regs_st dlg_regs); +void print__ttu_regs_st(struct display_mode_lib *mode_lib, display_ttu_regs_st ttu_regs); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c index 3df559c591..8f2b1684c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c @@ -206,47 +206,47 @@ static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_si static void extract_rq_sizing_regs( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_data_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing) + const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing) { DTRACE("DLG: %s: rq_sizing param", __func__); print__data_rq_sizing_params_st(mode_lib, rq_sizing); - rq_regs->chunk_size = dml_log2(rq_sizing->chunk_bytes) - 10; + rq_regs->chunk_size = dml_log2(rq_sizing.chunk_bytes) - 10; - if (rq_sizing->min_chunk_bytes == 0) + if (rq_sizing.min_chunk_bytes == 0) rq_regs->min_chunk_size = 0; else - rq_regs->min_chunk_size = dml_log2(rq_sizing->min_chunk_bytes) - 8 + 1; + rq_regs->min_chunk_size = dml_log2(rq_sizing.min_chunk_bytes) - 8 + 1; - rq_regs->meta_chunk_size = dml_log2(rq_sizing->meta_chunk_bytes) - 10; - if (rq_sizing->min_meta_chunk_bytes == 0) + rq_regs->meta_chunk_size = dml_log2(rq_sizing.meta_chunk_bytes) - 10; + if (rq_sizing.min_meta_chunk_bytes == 0) rq_regs->min_meta_chunk_size = 0; else - rq_regs->min_meta_chunk_size = dml_log2(rq_sizing->min_meta_chunk_bytes) - 6 + 1; + rq_regs->min_meta_chunk_size = dml_log2(rq_sizing.min_meta_chunk_bytes) - 6 + 1; - rq_regs->dpte_group_size = dml_log2(rq_sizing->dpte_group_bytes) - 6; - rq_regs->mpte_group_size = dml_log2(rq_sizing->mpte_group_bytes) - 6; + rq_regs->dpte_group_size = dml_log2(rq_sizing.dpte_group_bytes) - 6; + rq_regs->mpte_group_size = dml_log2(rq_sizing.mpte_group_bytes) - 6; } void dml1_extract_rq_regs( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_rq_params_st *rq_param) + const struct _vcs_dpi_display_rq_params_st rq_param) { unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; unsigned int detile_buf_plane1_addr = 0; - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), &rq_param->sizing.rq_l); - if (rq_param->yuv420) - extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), &rq_param->sizing.rq_c); + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_l), rq_param.sizing.rq_l); + if (rq_param.yuv420) + extract_rq_sizing_regs(mode_lib, &(rq_regs->rq_regs_c), rq_param.sizing.rq_c); - rq_regs->rq_regs_l.swath_height = dml_log2(rq_param->dlg.rq_l.swath_height); - rq_regs->rq_regs_c.swath_height = dml_log2(rq_param->dlg.rq_c.swath_height); + rq_regs->rq_regs_l.swath_height = dml_log2(rq_param.dlg.rq_l.swath_height); + rq_regs->rq_regs_c.swath_height = dml_log2(rq_param.dlg.rq_c.swath_height); /* TODO: take the max between luma, chroma chunk size? * okay for now, as we are setting chunk_bytes to 8kb anyways */ - if (rq_param->sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */ + if (rq_param.sizing.rq_l.chunk_bytes >= 32 * 1024) { /*32kb */ rq_regs->drq_expansion_mode = 0; } else { rq_regs->drq_expansion_mode = 2; @@ -255,9 +255,9 @@ void dml1_extract_rq_regs( rq_regs->mrq_expansion_mode = 1; rq_regs->crq_expansion_mode = 1; - if (rq_param->yuv420) { - if ((double) rq_param->misc.rq_l.stored_swath_bytes - / (double) rq_param->misc.rq_c.stored_swath_bytes <= 1.5) { + if (rq_param.yuv420) { + if ((double) rq_param.misc.rq_l.stored_swath_bytes + / (double) rq_param.misc.rq_c.stored_swath_bytes <= 1.5) { detile_buf_plane1_addr = (detile_buf_size_in_bytes / 2.0 / 64.0); /* half to chroma */ } else { detile_buf_plane1_addr = dml_round_to_multiple( @@ -272,7 +272,7 @@ void dml1_extract_rq_regs( static void handle_det_buf_split( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st *pipe_src_param) + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) { unsigned int total_swath_bytes = 0; unsigned int swath_bytes_l = 0; @@ -281,8 +281,8 @@ static void handle_det_buf_split( unsigned int full_swath_bytes_packed_c = 0; bool req128_l = 0; bool req128_c = 0; - bool surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - bool surf_vert = (pipe_src_param->source_scan == dm_vert); + bool surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + bool surf_vert = (pipe_src_param.source_scan == dm_vert); unsigned int log2_swath_height_l = 0; unsigned int log2_swath_height_c = 0; unsigned int detile_buf_size_in_bytes = mode_lib->ip.det_buffer_size_kbytes * 1024; @@ -556,7 +556,7 @@ static void get_surf_rq_param( struct _vcs_dpi_display_data_rq_sizing_params_st *rq_sizing_param, struct _vcs_dpi_display_data_rq_dlg_params_st *rq_dlg_param, struct _vcs_dpi_display_data_rq_misc_params_st *rq_misc_param, - const struct _vcs_dpi_display_pipe_source_params_st *pipe_src_param, + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param, bool is_chroma) { bool mode_422 = 0; @@ -622,15 +622,15 @@ static void get_surf_rq_param( /* TODO check if ppe apply for both luma and chroma in 422 case */ if (is_chroma) { - vp_width = pipe_src_param->viewport_width_c / ppe; - vp_height = pipe_src_param->viewport_height_c; - data_pitch = pipe_src_param->data_pitch_c; - meta_pitch = pipe_src_param->meta_pitch_c; + vp_width = pipe_src_param.viewport_width_c / ppe; + vp_height = pipe_src_param.viewport_height_c; + data_pitch = pipe_src_param.data_pitch_c; + meta_pitch = pipe_src_param.meta_pitch_c; } else { - vp_width = pipe_src_param->viewport_width / ppe; - vp_height = pipe_src_param->viewport_height; - data_pitch = pipe_src_param->data_pitch; - meta_pitch = pipe_src_param->meta_pitch; + vp_width = pipe_src_param.viewport_width / ppe; + vp_height = pipe_src_param.viewport_height; + data_pitch = pipe_src_param.data_pitch; + meta_pitch = pipe_src_param.meta_pitch; } rq_sizing_param->chunk_bytes = 8192; @@ -645,11 +645,11 @@ static void get_surf_rq_param( rq_sizing_param->mpte_group_bytes = 2048; - surf_linear = (pipe_src_param->sw_mode == dm_sw_linear); - surf_vert = (pipe_src_param->source_scan == dm_vert); + surf_linear = (pipe_src_param.sw_mode == dm_sw_linear); + surf_vert = (pipe_src_param.source_scan == dm_vert); bytes_per_element = get_bytes_per_element( - (enum source_format_class) pipe_src_param->source_format, + (enum source_format_class) pipe_src_param.source_format, is_chroma); log2_bytes_per_element = dml_log2(bytes_per_element); blk256_width = 0; @@ -671,7 +671,7 @@ static void get_surf_rq_param( log2_blk256_height = dml_log2((double) blk256_height); blk_bytes = surf_linear ? 256 : get_blk_size_bytes( - (enum source_macro_tile_size) pipe_src_param->macro_tile_size); + (enum source_macro_tile_size) pipe_src_param.macro_tile_size); log2_blk_bytes = dml_log2((double) blk_bytes); log2_blk_height = 0; log2_blk_width = 0; @@ -682,7 +682,7 @@ static void get_surf_rq_param( * "/2" is like square root * blk is vertical biased */ - if (pipe_src_param->sw_mode != dm_sw_linear) + if (pipe_src_param.sw_mode != dm_sw_linear) log2_blk_height = log2_blk256_height + dml_ceil((double) (log2_blk_bytes - 8) / 2.0, 1); else @@ -930,10 +930,10 @@ static void get_surf_rq_param( &func_meta_row_height, vp_width, data_pitch, - pipe_src_param->source_format, - pipe_src_param->sw_mode, - pipe_src_param->macro_tile_size, - pipe_src_param->source_scan, + pipe_src_param.source_format, + pipe_src_param.sw_mode, + pipe_src_param.macro_tile_size, + pipe_src_param.source_scan, is_chroma); /* Just a check to make sure this function and the new one give the same @@ -960,12 +960,12 @@ static void get_surf_rq_param( void dml1_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st *pipe_src_param) + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param) { /* get param for luma surface */ - rq_param->yuv420 = pipe_src_param->source_format == dm_420_8 - || pipe_src_param->source_format == dm_420_10; - rq_param->yuv420_10bpc = pipe_src_param->source_format == dm_420_10; + rq_param->yuv420 = pipe_src_param.source_format == dm_420_8 + || pipe_src_param.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_src_param.source_format == dm_420_10; get_surf_rq_param( mode_lib, @@ -975,7 +975,7 @@ void dml1_rq_dlg_get_rq_params( pipe_src_param, 0); - if (is_dual_plane((enum source_format_class) pipe_src_param->source_format)) { + if (is_dual_plane((enum source_format_class) pipe_src_param.source_format)) { /* get param for chroma surface */ get_surf_rq_param( mode_lib, @@ -988,7 +988,7 @@ void dml1_rq_dlg_get_rq_params( /* calculate how to split the det buffer space between luma and chroma */ handle_det_buf_split(mode_lib, rq_param, pipe_src_param); - print__rq_params_st(mode_lib, rq_param); + print__rq_params_st(mode_lib, *rq_param); } /* Note: currently taken in as is. @@ -998,26 +998,26 @@ void dml1_rq_dlg_get_dlg_params( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_dlg_regs_st *disp_dlg_regs, struct _vcs_dpi_display_ttu_regs_st *disp_ttu_regs, - const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param, - const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param, - const struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, + const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, + const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, + const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, const bool cstate_en, const bool pstate_en, const bool vm_en, const bool iflip_en) { /* Timing */ - unsigned int htotal = e2e_pipe_param->pipe.dest.htotal; - unsigned int hblank_end = e2e_pipe_param->pipe.dest.hblank_end; - unsigned int vblank_start = e2e_pipe_param->pipe.dest.vblank_start; - unsigned int vblank_end = e2e_pipe_param->pipe.dest.vblank_end; - bool interlaced = e2e_pipe_param->pipe.dest.interlaced; + unsigned int htotal = e2e_pipe_param.pipe.dest.htotal; + unsigned int hblank_end = e2e_pipe_param.pipe.dest.hblank_end; + unsigned int vblank_start = e2e_pipe_param.pipe.dest.vblank_start; + unsigned int vblank_end = e2e_pipe_param.pipe.dest.vblank_end; + bool interlaced = e2e_pipe_param.pipe.dest.interlaced; unsigned int min_vblank = mode_lib->ip.min_vblank_lines; - double pclk_freq_in_mhz = e2e_pipe_param->pipe.dest.pixel_rate_mhz; - double refclk_freq_in_mhz = e2e_pipe_param->clks_cfg.refclk_mhz; - double dppclk_freq_in_mhz = e2e_pipe_param->clks_cfg.dppclk_mhz; - double dispclk_freq_in_mhz = e2e_pipe_param->clks_cfg.dispclk_mhz; + double pclk_freq_in_mhz = e2e_pipe_param.pipe.dest.pixel_rate_mhz; + double refclk_freq_in_mhz = e2e_pipe_param.clks_cfg.refclk_mhz; + double dppclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dppclk_mhz; + double dispclk_freq_in_mhz = e2e_pipe_param.clks_cfg.dispclk_mhz; double ref_freq_to_pix_freq; double prefetch_xy_calc_in_dcfclk; @@ -1160,13 +1160,13 @@ void dml1_rq_dlg_get_dlg_params( disp_dlg_regs->dlg_vblank_end = interlaced ? (vblank_end / 2) : vblank_end; /* 15 bits */ prefetch_xy_calc_in_dcfclk = 24.0; /* TODO: ip_param */ - min_dcfclk_mhz = dlg_sys_param->deepsleep_dcfclk_mhz; + min_dcfclk_mhz = dlg_sys_param.deepsleep_dcfclk_mhz; t_calc_us = prefetch_xy_calc_in_dcfclk / min_dcfclk_mhz; - min_ttu_vblank = dlg_sys_param->t_urg_wm_us; + min_ttu_vblank = dlg_sys_param.t_urg_wm_us; if (cstate_en) - min_ttu_vblank = dml_max(dlg_sys_param->t_sr_wm_us, min_ttu_vblank); + min_ttu_vblank = dml_max(dlg_sys_param.t_sr_wm_us, min_ttu_vblank); if (pstate_en) - min_ttu_vblank = dml_max(dlg_sys_param->t_mclk_wm_us, min_ttu_vblank); + min_ttu_vblank = dml_max(dlg_sys_param.t_mclk_wm_us, min_ttu_vblank); min_ttu_vblank = min_ttu_vblank + t_calc_us; min_dst_y_ttu_vblank = min_ttu_vblank * pclk_freq_in_mhz / (double) htotal; @@ -1197,59 +1197,59 @@ void dml1_rq_dlg_get_dlg_params( /* ------------------------- */ /* Prefetch Calc */ /* Source */ - dcc_en = e2e_pipe_param->pipe.src.dcc; + dcc_en = e2e_pipe_param.pipe.src.dcc; dual_plane = is_dual_plane( - (enum source_format_class) e2e_pipe_param->pipe.src.source_format); + (enum source_format_class) e2e_pipe_param.pipe.src.source_format); mode_422 = 0; /* TODO */ - access_dir = (e2e_pipe_param->pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ + access_dir = (e2e_pipe_param.pipe.src.source_scan == dm_vert); /* vp access direction: horizontal or vertical accessed */ bytes_per_element_l = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param->pipe.src.source_format, + (enum source_format_class) e2e_pipe_param.pipe.src.source_format, 0); bytes_per_element_c = get_bytes_per_element( - (enum source_format_class) e2e_pipe_param->pipe.src.source_format, + (enum source_format_class) e2e_pipe_param.pipe.src.source_format, 1); - vp_height_l = e2e_pipe_param->pipe.src.viewport_height; - vp_width_l = e2e_pipe_param->pipe.src.viewport_width; - vp_height_c = e2e_pipe_param->pipe.src.viewport_height_c; - vp_width_c = e2e_pipe_param->pipe.src.viewport_width_c; + vp_height_l = e2e_pipe_param.pipe.src.viewport_height; + vp_width_l = e2e_pipe_param.pipe.src.viewport_width; + vp_height_c = e2e_pipe_param.pipe.src.viewport_height_c; + vp_width_c = e2e_pipe_param.pipe.src.viewport_width_c; /* Scaling */ - htaps_l = e2e_pipe_param->pipe.scale_taps.htaps; - htaps_c = e2e_pipe_param->pipe.scale_taps.htaps_c; - hratios_l = e2e_pipe_param->pipe.scale_ratio_depth.hscl_ratio; - hratios_c = e2e_pipe_param->pipe.scale_ratio_depth.hscl_ratio_c; - vratio_l = e2e_pipe_param->pipe.scale_ratio_depth.vscl_ratio; - vratio_c = e2e_pipe_param->pipe.scale_ratio_depth.vscl_ratio_c; + htaps_l = e2e_pipe_param.pipe.scale_taps.htaps; + htaps_c = e2e_pipe_param.pipe.scale_taps.htaps_c; + hratios_l = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; + hratios_c = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio_c; + vratio_l = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio; + vratio_c = e2e_pipe_param.pipe.scale_ratio_depth.vscl_ratio_c; line_time_in_us = (htotal / pclk_freq_in_mhz); - vinit_l = e2e_pipe_param->pipe.scale_ratio_depth.vinit; - vinit_c = e2e_pipe_param->pipe.scale_ratio_depth.vinit_c; - vinit_bot_l = e2e_pipe_param->pipe.scale_ratio_depth.vinit_bot; - vinit_bot_c = e2e_pipe_param->pipe.scale_ratio_depth.vinit_bot_c; + vinit_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit; + vinit_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_c; + vinit_bot_l = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot; + vinit_bot_c = e2e_pipe_param.pipe.scale_ratio_depth.vinit_bot_c; - swath_height_l = rq_dlg_param->rq_l.swath_height; - swath_width_ub_l = rq_dlg_param->rq_l.swath_width_ub; - dpte_bytes_per_row_ub_l = rq_dlg_param->rq_l.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_l = rq_dlg_param->rq_l.dpte_groups_per_row_ub; - meta_pte_bytes_per_frame_ub_l = rq_dlg_param->rq_l.meta_pte_bytes_per_frame_ub; - meta_bytes_per_row_ub_l = rq_dlg_param->rq_l.meta_bytes_per_row_ub; + swath_height_l = rq_dlg_param.rq_l.swath_height; + swath_width_ub_l = rq_dlg_param.rq_l.swath_width_ub; + dpte_bytes_per_row_ub_l = rq_dlg_param.rq_l.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_l = rq_dlg_param.rq_l.dpte_groups_per_row_ub; + meta_pte_bytes_per_frame_ub_l = rq_dlg_param.rq_l.meta_pte_bytes_per_frame_ub; + meta_bytes_per_row_ub_l = rq_dlg_param.rq_l.meta_bytes_per_row_ub; - swath_height_c = rq_dlg_param->rq_c.swath_height; - swath_width_ub_c = rq_dlg_param->rq_c.swath_width_ub; - dpte_bytes_per_row_ub_c = rq_dlg_param->rq_c.dpte_bytes_per_row_ub; - dpte_groups_per_row_ub_c = rq_dlg_param->rq_c.dpte_groups_per_row_ub; + swath_height_c = rq_dlg_param.rq_c.swath_height; + swath_width_ub_c = rq_dlg_param.rq_c.swath_width_ub; + dpte_bytes_per_row_ub_c = rq_dlg_param.rq_c.dpte_bytes_per_row_ub; + dpte_groups_per_row_ub_c = rq_dlg_param.rq_c.dpte_groups_per_row_ub; - meta_chunks_per_row_ub_l = rq_dlg_param->rq_l.meta_chunks_per_row_ub; - vupdate_offset = e2e_pipe_param->pipe.dest.vupdate_offset; - vupdate_width = e2e_pipe_param->pipe.dest.vupdate_width; - vready_offset = e2e_pipe_param->pipe.dest.vready_offset; + meta_chunks_per_row_ub_l = rq_dlg_param.rq_l.meta_chunks_per_row_ub; + vupdate_offset = e2e_pipe_param.pipe.dest.vupdate_offset; + vupdate_width = e2e_pipe_param.pipe.dest.vupdate_width; + vready_offset = e2e_pipe_param.pipe.dest.vready_offset; dppclk_delay_subtotal = mode_lib->ip.dppclk_delay_subtotal; dispclk_delay_subtotal = mode_lib->ip.dispclk_delay_subtotal; pixel_rate_delay_subtotal = dppclk_delay_subtotal * pclk_freq_in_mhz / dppclk_freq_in_mhz + dispclk_delay_subtotal * pclk_freq_in_mhz / dispclk_freq_in_mhz; - vstartup_start = e2e_pipe_param->pipe.dest.vstartup_start; + vstartup_start = e2e_pipe_param.pipe.dest.vstartup_start; if (interlaced) vstartup_start = vstartup_start / 2; @@ -1276,13 +1276,13 @@ void dml1_rq_dlg_get_dlg_params( dst_x_after_scaler = 0; dst_y_after_scaler = 0; - if (e2e_pipe_param->pipe.src.is_hsplit) + if (e2e_pipe_param.pipe.src.is_hsplit) dst_x_after_scaler = pixel_rate_delay_subtotal - + e2e_pipe_param->pipe.dest.recout_width; + + e2e_pipe_param.pipe.dest.recout_width; else dst_x_after_scaler = pixel_rate_delay_subtotal; - if (e2e_pipe_param->dout.output_format == dm_420) + if (e2e_pipe_param.dout.output_format == dm_420) dst_y_after_scaler = 1; else dst_y_after_scaler = 0; @@ -1331,6 +1331,10 @@ void dml1_rq_dlg_get_dlg_params( if (dual_plane) DTRACE("DLG: %s: swath_height_c = %d", __func__, swath_height_c); + DTRACE( + "DLG: %s: t_srx_delay_us = %3.2f", + __func__, + (double) dlg_sys_param.t_srx_delay_us); DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__, (double) line_time_in_us); DTRACE("DLG: %s: vupdate_offset = %d", __func__, vupdate_offset); DTRACE("DLG: %s: vupdate_width = %d", __func__, vupdate_width); @@ -1404,12 +1408,12 @@ void dml1_rq_dlg_get_dlg_params( DTRACE("DLG: %s: dpte_row_bytes = %d", __func__, dpte_row_bytes); prefetch_bw = (vm_bytes + 2 * dpte_row_bytes + 2 * meta_row_bytes + sw_bytes) / t_pre_us; - flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param->total_flip_bw) - / (double) dlg_sys_param->total_flip_bytes; + flip_bw = ((vm_bytes + dpte_row_bytes + meta_row_bytes) * dlg_sys_param.total_flip_bw) + / (double) dlg_sys_param.total_flip_bytes; t_vm_us = line_time_in_us / 4.0; if (vm_en && dcc_en) { t_vm_us = dml_max( - dlg_sys_param->t_extra_us, + dlg_sys_param.t_extra_us, dml_max((double) vm_bytes / prefetch_bw, t_vm_us)); if (iflip_en && !dual_plane) { @@ -1419,12 +1423,12 @@ void dml1_rq_dlg_get_dlg_params( } } - t_r0_us = dml_max(dlg_sys_param->t_extra_us - t_vm_us, line_time_in_us - t_vm_us); + t_r0_us = dml_max(dlg_sys_param.t_extra_us - t_vm_us, line_time_in_us - t_vm_us); if (vm_en || dcc_en) { t_r0_us = dml_max( (double) (dpte_row_bytes + meta_row_bytes) / prefetch_bw, - dlg_sys_param->t_extra_us); + dlg_sys_param.t_extra_us); t_r0_us = dml_max((double) (line_time_in_us - t_vm_us), t_r0_us); if (iflip_en && !dual_plane) { @@ -1546,15 +1550,15 @@ void dml1_rq_dlg_get_dlg_params( disp_dlg_regs->refcyc_per_meta_chunk_vblank_l;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */ /* Active */ - req_per_swath_ub_l = rq_dlg_param->rq_l.req_per_swath_ub; - req_per_swath_ub_c = rq_dlg_param->rq_c.req_per_swath_ub; - meta_row_height_l = rq_dlg_param->rq_l.meta_row_height; + req_per_swath_ub_l = rq_dlg_param.rq_l.req_per_swath_ub; + req_per_swath_ub_c = rq_dlg_param.rq_c.req_per_swath_ub; + meta_row_height_l = rq_dlg_param.rq_l.meta_row_height; swath_width_pixels_ub_l = 0; swath_width_pixels_ub_c = 0; scaler_rec_in_width_l = 0; scaler_rec_in_width_c = 0; - dpte_row_height_l = rq_dlg_param->rq_l.dpte_row_height; - dpte_row_height_c = rq_dlg_param->rq_c.dpte_row_height; + dpte_row_height_l = rq_dlg_param.rq_l.dpte_row_height; + dpte_row_height_c = rq_dlg_param.rq_c.dpte_row_height; disp_dlg_regs->dst_y_per_pte_row_nom_l = (unsigned int) ((double) dpte_row_height_l / (double) vratio_l * dml_pow(2, 2)); @@ -1646,14 +1650,14 @@ void dml1_rq_dlg_get_dlg_params( refcyc_per_req_delivery_cur0 = 0.; full_recout_width = 0; - if (e2e_pipe_param->pipe.src.is_hsplit) { - if (e2e_pipe_param->pipe.dest.full_recout_width == 0) { + if (e2e_pipe_param.pipe.src.is_hsplit) { + if (e2e_pipe_param.pipe.dest.full_recout_width == 0) { DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__); - full_recout_width = e2e_pipe_param->pipe.dest.recout_width * 2; /* assume half split for dcn1 */ + full_recout_width = e2e_pipe_param.pipe.dest.recout_width * 2; /* assume half split for dcn1 */ } else - full_recout_width = e2e_pipe_param->pipe.dest.full_recout_width; + full_recout_width = e2e_pipe_param.pipe.dest.full_recout_width; } else - full_recout_width = e2e_pipe_param->pipe.dest.recout_width; + full_recout_width = e2e_pipe_param.pipe.dest.recout_width; refcyc_per_line_delivery_pre_l = get_refcyc_per_delivery( mode_lib, @@ -1820,9 +1824,9 @@ void dml1_rq_dlg_get_dlg_params( } /* TTU - Cursor */ - hratios_cur0 = e2e_pipe_param->pipe.scale_ratio_depth.hscl_ratio; - cur0_src_width = e2e_pipe_param->pipe.src.cur0_src_width; /* cursor source width */ - cur0_bpp = (enum cursor_bpp) e2e_pipe_param->pipe.src.cur0_bpp; + hratios_cur0 = e2e_pipe_param.pipe.scale_ratio_depth.hscl_ratio; + cur0_src_width = e2e_pipe_param.pipe.src.cur0_src_width; /* cursor source width */ + cur0_bpp = (enum cursor_bpp) e2e_pipe_param.pipe.src.cur0_bpp; cur0_req_size = 0; cur0_req_width = 0; cur0_width_ub = 0.0; @@ -1923,6 +1927,6 @@ void dml1_rq_dlg_get_dlg_params( disp_ttu_regs->min_ttu_vblank = min_ttu_vblank * refclk_freq_in_mhz; ASSERT(disp_ttu_regs->min_ttu_vblank < dml_pow(2, 24)); - print__ttu_regs_st(mode_lib, disp_ttu_regs); - print__dlg_regs_st(mode_lib, disp_dlg_regs); + print__ttu_regs_st(mode_lib, *disp_ttu_regs); + print__dlg_regs_st(mode_lib, *disp_dlg_regs); } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h index e19ee3bde4..9c06913ad7 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.h @@ -33,7 +33,7 @@ struct display_mode_lib; void dml1_extract_rq_regs( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_rq_regs_st *rq_regs, - const struct _vcs_dpi_display_rq_params_st *rq_param); + const struct _vcs_dpi_display_rq_params_st rq_param); /* Function: dml_rq_dlg_get_rq_params * Calculate requestor related parameters that register definition agnostic * (i.e. this layer does try to separate real values from register definition) @@ -45,7 +45,7 @@ void dml1_extract_rq_regs( void dml1_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_rq_params_st *rq_param, - const struct _vcs_dpi_display_pipe_source_params_st *pipe_src_param); + const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param); /* Function: dml_rq_dlg_get_dlg_params @@ -55,9 +55,9 @@ void dml1_rq_dlg_get_dlg_params( struct display_mode_lib *mode_lib, struct _vcs_dpi_display_dlg_regs_st *dlg_regs, struct _vcs_dpi_display_ttu_regs_st *ttu_regs, - const struct _vcs_dpi_display_rq_dlg_params_st *rq_dlg_param, - const struct _vcs_dpi_display_dlg_sys_params_st *dlg_sys_param, - const struct _vcs_dpi_display_e2e_pipe_params_st *e2e_pipe_param, + const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param, + const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param, + const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param, const bool cstate_en, const bool pstate_en, const bool vm_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c index ec636d06e1..3ee858f311 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c @@ -61,6 +61,16 @@ static double dsc_roundf(double num) return (int)(num); } +static double dsc_ceil(double num) +{ + double retval = (int)num; + + if (retval != num && num > 0) + retval = num + 1; + + return (int)retval; +} + static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, enum max_min max_min, float bpp) { @@ -93,7 +103,7 @@ static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, TABLE_CASE(420, 12, min); } - if (!table) + if (table == 0) return; index = (bpp - table[0].bpp) * 2; @@ -258,3 +268,24 @@ void _do_calc_rc_params(struct rc_params *rc, rc->rc_buf_thresh[13] = 8064; } +u32 _do_bytes_per_pixel_calc(int slice_width, + u16 drm_bpp, + bool is_navite_422_or_420) +{ + float bpp; + u32 bytes_per_pixel; + double d_bytes_per_pixel; + + dc_assert_fp_enabled(); + + bpp = ((float)drm_bpp / 16.0); + d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width; + // TODO: Make sure the formula for calculating this is precise (ceiling + // vs. floor, and at what point they should be applied) + if (is_navite_422_or_420) + d_bytes_per_pixel /= 2; + + bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000); + + return bytes_per_pixel; +} diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h index cad244c023..b93b95409f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.h @@ -78,6 +78,10 @@ struct qp_entry { typedef struct qp_entry qp_table[]; +u32 _do_bytes_per_pixel_calc(int slice_width, + u16 drm_bpp, + bool is_navite_422_or_420); + void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_comp bpc, diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index 9c74564cbd..f5b7da0e64 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -40,15 +40,8 @@ static bool dsc_policy_enable_dsc_when_not_needed; static bool dsc_policy_disable_dsc_stream_overhead; -#ifndef MAX -#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) -#endif -#ifndef MIN -#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) -#endif - /* Forward Declerations */ -static bool decide_dsc_bandwidth_range( +static void get_dsc_bandwidth_range( const uint32_t min_bpp_x16, const uint32_t max_bpp_x16, const uint32_t num_slices_h, @@ -83,6 +76,11 @@ static bool setup_dsc_config( int max_dsc_target_bpp_limit_override_x16, struct dc_dsc_config *dsc_cfg); +static struct fixed31_32 compute_dsc_max_bandwidth_overhead( + const struct dc_crtc_timing *timing, + const int num_slices_h, + const bool is_dp); + static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) { @@ -363,7 +361,7 @@ bool dc_dsc_compute_bandwidth_range( dsc_min_slice_height_override, max_bpp_x16, &config); if (is_dsc_possible) - is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, + get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, config.num_slices_h, &dsc_common_caps, timing, range); return is_dsc_possible; @@ -455,7 +453,6 @@ static bool intersect_dsc_caps( if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8); - dsc_common_caps->edp_sink_max_bits_per_pixel = dsc_sink_caps->edp_max_bits_per_pixel; dsc_common_caps->is_dp = dsc_sink_caps->is_dp; return true; } @@ -465,6 +462,32 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value) return (value + 9) / 10; } +static struct fixed31_32 compute_dsc_max_bandwidth_overhead( + const struct dc_crtc_timing *timing, + const int num_slices_h, + const bool is_dp) +{ + struct fixed31_32 max_dsc_overhead; + struct fixed31_32 refresh_rate; + + if (dsc_policy_disable_dsc_stream_overhead || !is_dp) + return dc_fixpt_from_int(0); + + /* use target bpp that can take entire target bandwidth */ + refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz); + refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total); + refresh_rate = dc_fixpt_div_int(refresh_rate, timing->v_total); + refresh_rate = dc_fixpt_mul_int(refresh_rate, 100); + + max_dsc_overhead = dc_fixpt_from_int(num_slices_h); + max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_total); + max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256); + max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000); + max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate); + + return max_dsc_overhead; +} + static uint32_t compute_bpp_x16_from_target_bandwidth( const uint32_t bandwidth_in_kbps, const struct dc_crtc_timing *timing, @@ -472,14 +495,14 @@ static uint32_t compute_bpp_x16_from_target_bandwidth( const uint32_t bpp_increment_div, const bool is_dp) { - uint32_t overhead_in_kbps; + struct fixed31_32 overhead_in_kbps; struct fixed31_32 effective_bandwidth_in_kbps; struct fixed31_32 bpp_x16; - overhead_in_kbps = dc_dsc_stream_bandwidth_overhead_in_kbps( + overhead_in_kbps = compute_dsc_max_bandwidth_overhead( timing, num_slices_h, is_dp); effective_bandwidth_in_kbps = dc_fixpt_from_int(bandwidth_in_kbps); - effective_bandwidth_in_kbps = dc_fixpt_sub_int(effective_bandwidth_in_kbps, + effective_bandwidth_in_kbps = dc_fixpt_sub(effective_bandwidth_in_kbps, overhead_in_kbps); bpp_x16 = dc_fixpt_mul_int(effective_bandwidth_in_kbps, 10); bpp_x16 = dc_fixpt_div_int(bpp_x16, timing->pix_clk_100hz); @@ -489,12 +512,10 @@ static uint32_t compute_bpp_x16_from_target_bandwidth( return dc_fixpt_floor(bpp_x16); } -/* Decide DSC bandwidth range based on signal, timing, specs specific and input min and max - * requirements. - * The range output includes decided min/max target bpp, the respective bandwidth requirements - * and native timing bandwidth requirement when DSC is not used. +/* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock + * and uncompressed bandwidth. */ -static bool decide_dsc_bandwidth_range( +static void get_dsc_bandwidth_range( const uint32_t min_bpp_x16, const uint32_t max_bpp_x16, const uint32_t num_slices_h, @@ -502,52 +523,39 @@ static bool decide_dsc_bandwidth_range( const struct dc_crtc_timing *timing, struct dc_dsc_bw_range *range) { - uint32_t preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; + /* native stream bandwidth */ + range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); - memset(range, 0, sizeof(*range)); - - /* apply signal, timing, specs and explicitly specified DSC range requirements */ - if (preferred_bpp_x16) { - if (preferred_bpp_x16 <= max_bpp_x16 && - preferred_bpp_x16 >= min_bpp_x16) { - range->max_target_bpp_x16 = preferred_bpp_x16; - range->min_target_bpp_x16 = preferred_bpp_x16; - } - } - /* TODO - make this value generic to all signal types */ - else if (dsc_caps->edp_sink_max_bits_per_pixel) { - /* apply max bpp limitation from edp sink */ - range->max_target_bpp_x16 = MIN(dsc_caps->edp_sink_max_bits_per_pixel, - max_bpp_x16); - range->min_target_bpp_x16 = min_bpp_x16; - } - else { - range->max_target_bpp_x16 = max_bpp_x16; - range->min_target_bpp_x16 = min_bpp_x16; + /* max dsc target bpp */ + range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, + max_bpp_x16, num_slices_h, dsc_caps->is_dp); + range->max_target_bpp_x16 = max_bpp_x16; + if (range->max_kbps > range->stream_kbps) { + /* max dsc target bpp is capped to native bandwidth */ + range->max_kbps = range->stream_kbps; + range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( + range->max_kbps, timing, num_slices_h, + dsc_caps->bpp_increment_div, + dsc_caps->is_dp); } - /* populate output structure */ - if (range->max_target_bpp_x16 >= range->min_target_bpp_x16 && range->min_target_bpp_x16 > 0) { - /* native stream bandwidth */ - range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); - - /* max dsc target bpp */ - range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, - range->max_target_bpp_x16, num_slices_h, dsc_caps->is_dp); - - /* min dsc target bpp */ - range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, - range->min_target_bpp_x16, num_slices_h, dsc_caps->is_dp); + /* min dsc target bpp */ + range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing, + min_bpp_x16, num_slices_h, dsc_caps->is_dp); + range->min_target_bpp_x16 = min_bpp_x16; + if (range->min_kbps > range->max_kbps) { + /* min dsc target bpp is capped to max dsc bandwidth*/ + range->min_kbps = range->max_kbps; + range->min_target_bpp_x16 = range->max_target_bpp_x16; } - - return range->max_kbps >= range->min_kbps && range->min_kbps > 0; } /* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy. * * Returns: - * - 'true' if target bpp is decided - * - 'false' if target bpp cannot be decided (e.g. cannot fit even with min DSC bpp), + * - 'true' if DSC was required by policy and was successfully applied + * - 'false' if DSC was not necessary (e.g. if uncompressed stream fits 'target_bandwidth_kbps'), + * or if it couldn't be applied based on DSC policy. */ static bool decide_dsc_target_bpp_x16( const struct dc_dsc_policy *policy, @@ -557,32 +565,43 @@ static bool decide_dsc_target_bpp_x16( const int num_slices_h, int *target_bpp_x16) { + bool should_use_dsc = false; struct dc_dsc_bw_range range; - *target_bpp_x16 = 0; + memset(&range, 0, sizeof(range)); - if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, - num_slices_h, dsc_common_caps, timing, &range)) { - if (target_bandwidth_kbps >= range.stream_kbps) { - if (policy->enable_dsc_when_not_needed) - /* enable max bpp even dsc is not needed */ - *target_bpp_x16 = range.max_target_bpp_x16; - } else if (target_bandwidth_kbps >= range.max_kbps) { - /* use max target bpp allowed */ - *target_bpp_x16 = range.max_target_bpp_x16; - } else if (target_bandwidth_kbps >= range.min_kbps) { - /* use target bpp that can take entire target bandwidth */ - *target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( - target_bandwidth_kbps, timing, num_slices_h, - dsc_common_caps->bpp_increment_div, - dsc_common_caps->is_dp); - } + get_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, + num_slices_h, dsc_common_caps, timing, &range); + if (!policy->enable_dsc_when_not_needed && target_bandwidth_kbps >= range.stream_kbps) { + /* enough bandwidth without dsc */ + *target_bpp_x16 = 0; + should_use_dsc = false; + } else if (policy->preferred_bpp_x16 > 0 && + policy->preferred_bpp_x16 <= range.max_target_bpp_x16 && + policy->preferred_bpp_x16 >= range.min_target_bpp_x16) { + *target_bpp_x16 = policy->preferred_bpp_x16; + should_use_dsc = true; + } else if (target_bandwidth_kbps >= range.max_kbps) { + /* use max target bpp allowed */ + *target_bpp_x16 = range.max_target_bpp_x16; + should_use_dsc = true; + } else if (target_bandwidth_kbps >= range.min_kbps) { + /* use target bpp that can take entire target bandwidth */ + *target_bpp_x16 = compute_bpp_x16_from_target_bandwidth( + target_bandwidth_kbps, timing, num_slices_h, + dsc_common_caps->bpp_increment_div, + dsc_common_caps->is_dp); + should_use_dsc = true; + } else { + /* not enough bandwidth to fulfill minimum requirement */ + *target_bpp_x16 = 0; + should_use_dsc = false; } - return *target_bpp_x16 != 0; + return should_use_dsc; } -#define MIN_AVAILABLE_SLICES_SIZE 6 +#define MIN_AVAILABLE_SLICES_SIZE 4 static int get_available_dsc_slices(union dsc_enc_slice_caps slice_caps, int *available_slices) { @@ -868,10 +887,6 @@ static bool setup_dsc_config( min_slices_h = 0; // DSC TODO: Maybe try increasing the number of slices first? is_dsc_possible = (min_slices_h <= max_slices_h); - - if (min_slices_h == 0 && max_slices_h == 0) - is_dsc_possible = false; - if (!is_dsc_possible) goto done; @@ -979,45 +994,19 @@ bool dc_dsc_compute_config( uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing, uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp) { - uint32_t overhead_in_kbps; + struct fixed31_32 overhead_in_kbps; struct fixed31_32 bpp; struct fixed31_32 actual_bandwidth_in_kbps; - overhead_in_kbps = dc_dsc_stream_bandwidth_overhead_in_kbps( + overhead_in_kbps = compute_dsc_max_bandwidth_overhead( timing, num_slices_h, is_dp); bpp = dc_fixpt_from_fraction(bpp_x16, 16); actual_bandwidth_in_kbps = dc_fixpt_from_fraction(timing->pix_clk_100hz, 10); actual_bandwidth_in_kbps = dc_fixpt_mul(actual_bandwidth_in_kbps, bpp); - actual_bandwidth_in_kbps = dc_fixpt_add_int(actual_bandwidth_in_kbps, overhead_in_kbps); + actual_bandwidth_in_kbps = dc_fixpt_add(actual_bandwidth_in_kbps, overhead_in_kbps); return dc_fixpt_ceil(actual_bandwidth_in_kbps); } -uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps( - const struct dc_crtc_timing *timing, - const int num_slices_h, - const bool is_dp) -{ - struct fixed31_32 max_dsc_overhead; - struct fixed31_32 refresh_rate; - - if (dsc_policy_disable_dsc_stream_overhead || !is_dp) - return 0; - - /* use target bpp that can take entire target bandwidth */ - refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz); - refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total); - refresh_rate = dc_fixpt_div_int(refresh_rate, timing->v_total); - refresh_rate = dc_fixpt_mul_int(refresh_rate, 100); - - max_dsc_overhead = dc_fixpt_from_int(num_slices_h); - max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_total); - max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256); - max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000); - max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate); - - return dc_fixpt_ceil(max_dsc_overhead); -} - void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy) @@ -1075,6 +1064,8 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, return; } + policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16; + /* internal upper limit, default 16 bpp */ if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) policy->max_target_bpp = dsc_policy_max_target_bpp_limit; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c index e97cf09be9..b19d3aeb59 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c @@ -60,3 +60,31 @@ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps) pps->dsc_version_minor); DC_FP_END(); } + +/** + * calc_dsc_bytes_per_pixel - calculate bytes per pixel + * @pps: DRM struct with all required DSC values + * + * Based on the information inside drm_dsc_config, this function calculates the + * total of bytes per pixel. + * + * @note This calculation requires float point operation, most of it executes + * under kernel_fpu_{begin,end}. + * + * Return: + * Return the number of bytes per pixel + */ +u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps) + +{ + u32 ret; + u16 drm_bpp = pps->bits_per_pixel; + int slice_width = pps->slice_width; + bool is_navite_422_or_420 = pps->native_422 || pps->native_420; + + DC_FP_START(); + ret = _do_bytes_per_pixel_calc(slice_width, drm_bpp, + is_navite_422_or_420); + DC_FP_END(); + return ret; +} diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h index 80921c1c0d..c2340e001b 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h @@ -30,6 +30,7 @@ #include "dml/dsc/rc_calc_fpu.h" void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps); +u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps); #endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c index 7e306aa3e2..1e19dd674e 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c @@ -100,7 +100,8 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par int ret; struct rc_params rc; struct drm_dsc_config dsc_cfg; - unsigned long long tmp; + + dsc_params->bytes_per_pixel = calc_dsc_bytes_per_pixel(pps); calc_rc_params(&rc, pps); dsc_params->pps = *pps; @@ -112,9 +113,6 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par dsc_cfg.mux_word_size = dsc_params->pps.bits_per_component <= 10 ? 48 : 64; ret = drm_dsc_compute_rc_parameters(&dsc_cfg); - tmp = (unsigned long long)dsc_cfg.slice_chunk_size * 0x10000000 + (dsc_cfg.slice_width - 1); - do_div(tmp, (uint32_t)dsc_cfg.slice_width); //ROUND-UP - dsc_params->bytes_per_pixel = (uint32_t)tmp; copy_pps_fields(&dsc_params->pps, &dsc_cfg); dsc_params->rc_buffer_model_size = dsc_cfg.rc_bits; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 5029d4e42d..c5c840a060 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -105,7 +105,6 @@ bool dal_hw_factory_init( case DCN_VERSION_2_0: dal_hw_factory_dcn20_init(factory); return true; - case DCN_VERSION_2_01: case DCN_VERSION_2_1: dal_hw_factory_dcn21_init(factory); return true; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index 904bd30bed..4a98483087 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -100,7 +100,6 @@ bool dal_hw_translate_init( case DCN_VERSION_2_0: dal_hw_translate_dcn20_init(translate); return true; - case DCN_VERSION_2_01: case DCN_VERSION_2_1: dal_hw_translate_dcn21_init(translate); return true; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h index 444182a97e..d34b0b0eea 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -53,8 +53,6 @@ enum dc_status { DC_NOT_SUPPORTED = 24, DC_UNSUPPORTED_VALUE = 25, - DC_NO_LINK_ENC_RESOURCE = 26, - DC_ERROR_UNEXPECTED = -1 }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 943240e280..45a6216dfa 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -62,7 +62,6 @@ struct link_init_data { uint32_t connector_index; /* this will be mapped to the HPD pins */ uint32_t link_index; /* this is mapped to DAL display_index TODO: remove it when DC is complete. */ - bool is_dpia_link; }; struct dc_link *link_create(const struct link_init_data *init_params); @@ -246,15 +245,7 @@ struct resource_pool { * entries in link_encoders array. */ unsigned int dig_link_enc_count; - /* Number of USB4 DPIA (DisplayPort Input Adapter) link objects created.*/ - unsigned int usb4_dpia_count; -#if defined(CONFIG_DRM_AMD_DC_DCN) - unsigned int hpo_dp_stream_enc_count; - struct hpo_dp_stream_encoder *hpo_dp_stream_enc[MAX_HPO_DP2_ENCODERS]; - unsigned int hpo_dp_link_enc_count; - struct hpo_dp_link_encoder *hpo_dp_link_enc[MAX_HPO_DP2_LINK_ENCODERS]; -#endif #if defined(CONFIG_DRM_AMD_DC_DCN) struct dc_3dlut *mpc_lut[MAX_PIPES]; struct dc_transfer_func *mpc_shaper[MAX_PIPES]; @@ -307,9 +298,6 @@ struct stream_resource { struct display_stream_compressor *dsc; struct timing_generator *tg; struct stream_encoder *stream_enc; -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_stream_encoder *hpo_dp_stream_enc; -#endif struct audio *audio; struct pixel_clk_params pix_clk_params; @@ -334,20 +322,6 @@ struct plane_resource { struct dcn_fe_bandwidth bw; }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -#define LINK_RES_HPO_DP_REC_MAP__MASK 0xFFFF -#define LINK_RES_HPO_DP_REC_MAP__SHIFT 0 -#endif - -/* all mappable hardware resources used to enable a link */ -struct link_resource { -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_link_encoder *hpo_dp_link_enc; -#else - void *dummy; -#endif -}; - union pipe_update_flags { struct { uint32_t enable : 1; @@ -375,14 +349,12 @@ struct pipe_ctx { struct plane_resource plane_res; struct stream_resource stream_res; - struct link_resource link_res; struct clock_source *clock_source; struct pll_settings pll_settings; uint8_t pipe_idx; - uint8_t pipe_idx_syncd; struct pipe_ctx *top_pipe; struct pipe_ctx *bottom_pipe; @@ -394,9 +366,6 @@ struct pipe_ctx { struct _vcs_dpi_display_ttu_regs_st ttu_regs; struct _vcs_dpi_display_rq_regs_st rq_regs; struct _vcs_dpi_display_pipe_dest_params_st pipe_dlg_param; - struct _vcs_dpi_display_rq_params_st dml_rq_param; - struct _vcs_dpi_display_dlg_sys_params_st dml_dlg_sys_param; - struct _vcs_dpi_display_e2e_pipe_params_st dml_input; int det_buffer_size_kb; bool unbounded_req; #endif @@ -406,17 +375,6 @@ struct pipe_ctx { bool vtp_locked; }; -/* Data used for dynamic link encoder assignment. - * Tracks current and future assignments; available link encoders; - * and mode of operation (whether to use current or future assignments). - */ -struct link_enc_cfg_context { - enum link_enc_cfg_mode mode; - struct link_enc_assignment link_enc_assignments[MAX_PIPES]; - enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS]; - struct link_enc_assignment transient_assignments[MAX_PIPES]; -}; - struct resource_context { struct pipe_ctx pipe_ctx[MAX_PIPES]; bool is_stream_enc_acquired[MAX_PIPES * 2]; @@ -424,12 +382,12 @@ struct resource_context { uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES]; uint8_t dp_clock_source_ref_count; bool is_dsc_acquired[MAX_PIPES]; - struct link_enc_cfg_context link_enc_cfg_ctx; -#if defined(CONFIG_DRM_AMD_DC_DCN) - bool is_hpo_dp_stream_enc_acquired[MAX_HPO_DP2_ENCODERS]; - unsigned int hpo_dp_link_enc_to_link_idx[MAX_HPO_DP2_LINK_ENCODERS]; - int hpo_dp_link_enc_ref_cnts[MAX_HPO_DP2_LINK_ENCODERS]; -#endif + /* A table/array of encoder-to-link assignments. One entry per stream. + * Indexed by stream index in dc_state. + */ + struct link_enc_assignment link_enc_assignments[MAX_PIPES]; + /* List of available link encoders. Uses engine ID as encoder identifier. */ + enum engine_id link_enc_avail[MAX_DIG_LINK_ENCODERS]; #if defined(CONFIG_DRM_AMD_DC_DCN) bool is_mpc_3dlut_acquired[MAX_PIPES]; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index 95fb61d627..4d7b271b64 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h @@ -69,7 +69,6 @@ struct ddc_service_init_data { struct graphics_object_id id; struct dc_context *ctx; struct dc_link *link; - bool is_dpia_link; }; struct ddc_service *dal_ddc_service_create( diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h index cd52813a84..01c3a31be1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h @@ -30,7 +30,6 @@ #define LINK_TRAINING_RETRY_DELAY 50 /* ms */ #define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/ #define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/ -#define MAX_MTP_SLOT_COUNT 64 #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 #define TRAINING_AUX_RD_INTERVAL 100 //us @@ -56,19 +55,16 @@ enum { bool dp_verify_link_cap( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *known_limit_link_setting, int *fail_count); bool dp_verify_link_cap_with_retries( struct dc_link *link, - const struct link_resource *link_res, struct dc_link_settings *known_limit_link_setting, int attempts); bool dp_verify_mst_link_cap( - struct dc_link *link, - const struct link_resource *link_res); + struct dc_link *link); bool dp_validate_mode_timing( struct dc_link *link, @@ -124,12 +120,12 @@ enum dc_status dpcd_set_lane_settings( const struct link_training_settings *link_training_setting, uint32_t offset); /* Read training status and adjustment requests from DPCD. */ -enum dc_status dp_get_lane_status_and_lane_adjust( +enum dc_status dp_get_lane_status_and_drive_settings( struct dc_link *link, const struct link_training_settings *link_training_setting, - union lane_status ln_status[LANE_COUNT_DP_MAX], - union lane_align_status_updated *ln_align, - union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], + union lane_status *ln_status, + union lane_align_status_updated *ln_status_updated, + struct link_training_settings *req_settings, uint32_t offset); void dp_wait_for_training_aux_rd_interval( @@ -150,15 +146,10 @@ bool dp_is_interlane_aligned(union lane_align_status_updated align_status); bool dp_is_max_vs_reached( const struct link_training_settings *lt_settings); -void dp_hw_to_dpcd_lane_settings( - const struct link_training_settings *lt_settings, - const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); -void dp_decide_lane_settings( - const struct link_training_settings *lt_settings, - const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], - struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); + +void dp_update_drive_settings( + struct link_training_settings *dest, + struct link_training_settings src); uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval); @@ -171,11 +162,10 @@ uint8_t dc_dp_initialize_scrambling_data_symbols( struct dc_link *link, enum dc_dp_training_pattern pattern); -enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready); +enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready); void dp_set_fec_enable(struct dc_link *link, bool enable); -struct link_encoder *dp_get_link_enc(struct dc_link *link); bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable); -bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update); +bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable); void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable); bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx); bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable); @@ -199,31 +189,5 @@ enum dc_status dpcd_configure_lttpr_mode( struct link_training_settings *lt_settings); enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings); -bool dpcd_write_128b_132b_sst_payload_allocation_table( - const struct dc_stream_state *stream, - struct dc_link *link, - struct link_mst_stream_allocation_table *proposed_table, - bool allocate); - -enum dc_status dpcd_configure_channel_coding( - struct dc_link *link, - struct link_training_settings *lt_settings); - -bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link); - -struct fixed31_32 calculate_sst_avg_time_slots_per_mtp( - const struct dc_stream_state *stream, - const struct dc_link *link); -void enable_dp_hpo_output(struct dc_link *link, - const struct link_resource *link_res, - const struct dc_link_settings *link_settings); -void disable_dp_hpo_output(struct dc_link *link, - const struct link_resource *link_res, - enum signal_type signal); -void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable); -bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx); -void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link); - bool dp_retrieve_lttpr_cap(struct dc_link *link); -void edp_panel_backlight_power_on(struct dc_link *link); #endif /* __DC_LINK_DP_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index 337c0161e7..806f3041db 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -619,7 +619,7 @@ struct dcn_ip_params { }; extern const struct dcn_ip_params dcn10_ip_defaults; -bool dcn10_validate_bandwidth( +bool dcn_validate_bandwidth( struct dc *dc, struct dc_state *context, bool fast_validate); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index ecb4191b6e..1427536443 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -54,7 +54,6 @@ struct abm_funcs { const char *src, unsigned int bytes, unsigned int inst); - bool (*set_abm_pause)(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index c920c4b607..a17e5de3b1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -211,8 +211,6 @@ struct dummy_pstate_entry { struct clk_bw_params { unsigned int vram_type; unsigned int num_channels; - unsigned int dispclk_vco_khz; - unsigned int dc_mode_softmax_memclk; struct clk_limit_table clk_table; struct wm_table wm_table; struct dummy_pstate_entry dummy_pstate_table[4]; @@ -263,10 +261,6 @@ struct clk_mgr_funcs { /* Send message to PMFW to set hard max memclk frequency to highest DPM */ void (*set_hard_max_memclk)(struct clk_mgr *clk_mgr); - /* Custom set a memclk freq range*/ - void (*set_max_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz); - void (*set_min_memclk)(struct clk_mgr *clk_mgr, unsigned int memclk_mhz); - /* Get current memclk states from PMFW, update relevant structures */ void (*get_memclk_states_from_smu)(struct clk_mgr *clk_mgr); @@ -280,7 +274,6 @@ struct clk_mgr { struct dc_clocks clks; bool psr_allow_active_cache; bool force_smu_not_present; - bool dc_mode_softmax_enabled; int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes int dentist_vco_freq_khz; struct clk_state_registers_and_bypass boot_snapshot; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h index 1391c20f18..a262f3278c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h @@ -102,11 +102,6 @@ enum dentist_divider_range { .MP1_SMN_C2PMSG_83 = mmMP1_SMN_C2PMSG_83, \ .MP1_SMN_C2PMSG_67 = mmMP1_SMN_C2PMSG_67 -#define CLK_COMMON_REG_LIST_DCN_201() \ - SR(DENTIST_DISPCLK_CNTL), \ - CLK_SRI(CLK4_CLK_PLL_REQ, CLK4, 0), \ - CLK_SRI(CLK4_CLK2_CURRENT_CNT, CLK4, 0) - #define CLK_REG_LIST_NV10() \ SR(DENTIST_DISPCLK_CNTL), \ CLK_SRI(CLK3_CLK_PLL_REQ, CLK3, 0), \ @@ -149,12 +144,6 @@ enum dentist_divider_range { CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_int, mask_sh),\ CLK_SF(CLK3_0_CLK3_CLK_PLL_REQ, FbMult_frac, mask_sh) -#define CLK_COMMON_MASK_SH_LIST_DCN201_BASE(mask_sh) \ - CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, mask_sh),\ - CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, mask_sh),\ - CLK_SF(CLK4_0_CLK4_CLK_PLL_REQ, FbMult_int, mask_sh) - #define CLK_REG_FIELD_LIST(type) \ type DPREFCLK_SRC_SEL; \ type DENTIST_DPREFCLK_WDIVIDER; \ @@ -190,8 +179,6 @@ struct clk_mgr_mask { struct clk_mgr_registers { uint32_t DPREFCLK_CNTL; uint32_t DENTIST_DISPCLK_CNTL; - uint32_t CLK4_CLK2_CURRENT_CNT; - uint32_t CLK4_CLK_PLL_REQ; uint32_t CLK3_CLK2_DFS_CNTL; uint32_t CLK3_CLK_PLL_REQ; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index c940fdfda1..0afa2364a9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -79,30 +79,7 @@ struct dccg_funcs { void (*otg_drop_pixel)(struct dccg *dccg, uint32_t otg_inst); void (*dccg_init)(struct dccg *dccg); -#if defined(CONFIG_DRM_AMD_DC_DCN) - void (*set_dpstreamclk)( - struct dccg *dccg, - enum hdmistreamclk_source src, - int otg_inst); - void (*enable_symclk32_se)( - struct dccg *dccg, - int hpo_se_inst, - enum phyd32clk_clock_source phyd32clk); - - void (*disable_symclk32_se)( - struct dccg *dccg, - int hpo_se_inst); - - void (*enable_symclk32_le)( - struct dccg *dccg, - int hpo_le_inst, - enum phyd32clk_clock_source phyd32clk); - - void (*disable_symclk32_le)( - struct dccg *dccg, - int hpo_le_inst); -#endif void (*set_physymclk)( struct dccg *dccg, int phy_inst, @@ -123,15 +100,6 @@ struct dccg_funcs { void (*set_dispclk_change_mode)( struct dccg *dccg, enum dentist_dispclk_change_mode change_mode); - - void (*disable_dsc)( - struct dccg *dccg, - int inst); - - void (*enable_dsc)( - struct dccg *dccg, - int inst); - }; #endif //__DAL_DCCG_H__ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 3ef7faa920..00fc81431b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -29,17 +29,6 @@ #include "transform.h" -union defer_reg_writes { - struct { - bool disable_blnd_lut:1; - bool disable_3dlut:1; - bool disable_shaper:1; - bool disable_gamcor:1; - bool disable_dscl:1; - } bits; - uint32_t raw; -}; - struct dpp { const struct dpp_funcs *funcs; struct dc_context *ctx; @@ -54,7 +43,6 @@ struct dpp { struct pwl_params regamma_params; struct pwl_params degamma_params; struct dpp_cursor_attributes cur_attr; - union defer_reg_writes deferred_reg_writes; struct pwl_params shaper_params; bool cm_bypass_mode; @@ -257,8 +245,6 @@ struct dpp_funcs { bool dppclk_div, bool enable); - void (*dpp_deferred_update)( - struct dpp *dpp); bool (*dpp_program_blnd_lut)( struct dpp *dpp, const struct pwl_params *params); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h index 346f0ba73e..f94135c6e3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h @@ -61,8 +61,6 @@ struct dcn_dsc_state { uint32_t dsc_pic_height; uint32_t dsc_slice_bpg_offset; uint32_t dsc_chunk_size; - uint32_t dsc_fw_en; - uint32_t dsc_opp_source; }; @@ -90,7 +88,6 @@ struct dsc_enc_caps { int32_t max_total_throughput_mps; /* Maximum total throughput with all the slices combined */ int32_t max_slice_width; uint32_t bpp_increment_div; /* bpp increment divisor, e.g. if 16, it's 1/16th of a bit */ - uint32_t edp_sink_max_bits_per_pixel; bool is_dp; }; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h index fd6572ba3f..ec28cb9c3a 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dwb.h @@ -171,9 +171,10 @@ struct dwbc { bool dwb_is_efc_transition; bool dwb_is_drc; int wb_src_plane_inst;/*hubp, mpcc, inst*/ + bool update_privacymask; uint32_t mask_id; - int otg_inst; - bool mvc_cfg; + int otg_inst; + bool mvc_cfg; }; struct dwbc_funcs { diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 2c031586f4..80e1a32bc6 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -139,7 +139,6 @@ struct hubp_funcs { bool (*hubp_is_flip_pending)(struct hubp *hubp); void (*set_blank)(struct hubp *hubp, bool blank); - void (*set_blank_regs)(struct hubp *hubp, bool blank); void (*set_hubp_blank_en)(struct hubp *hubp, bool blank); void (*set_cursor_attributes)( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index 10ecbc667f..31a1713bb4 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h @@ -38,10 +38,6 @@ #define MAX_PIPES 6 #define MAX_DIG_LINK_ENCODERS 7 #define MAX_DWB_PIPES 1 -#if defined(CONFIG_DRM_AMD_DC_DCN) -#define MAX_HPO_DP2_ENCODERS 4 -#define MAX_HPO_DP2_LINK_ENCODERS 2 -#endif struct gamma_curve { uint32_t offset; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index 2ce15cd10d..9eaf345aa2 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -59,10 +59,6 @@ struct encoder_feature_support { uint32_t IS_TPS3_CAPABLE:1; uint32_t IS_TPS4_CAPABLE:1; uint32_t HDMI_6GB_EN:1; - uint32_t IS_DP2_CAPABLE:1; - uint32_t IS_UHBR10_CAPABLE:1; - uint32_t IS_UHBR13_5_CAPABLE:1; - uint32_t IS_UHBR20_CAPABLE:1; uint32_t DP_IS_USB_C:1; } bits; uint32_t raw; @@ -212,100 +208,6 @@ struct link_enc_assignment { bool valid; struct display_endpoint_id ep_id; enum engine_id eng_id; - struct dc_stream_state *stream; }; -enum link_enc_cfg_mode { - LINK_ENC_CFG_STEADY, /* Normal operation - use current_state. */ - LINK_ENC_CFG_TRANSIENT /* During commit state - use state to be committed. */ -}; - -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum dp2_link_mode { - DP2_LINK_TRAINING_TPS1, - DP2_LINK_TRAINING_TPS2, - DP2_LINK_ACTIVE, - DP2_TEST_PATTERN -}; - -enum dp2_phy_tp_select { - DP_DPHY_TP_SELECT_TPS1, - DP_DPHY_TP_SELECT_TPS2, - DP_DPHY_TP_SELECT_PRBS, - DP_DPHY_TP_SELECT_CUSTOM, - DP_DPHY_TP_SELECT_SQUARE -}; - -enum dp2_phy_tp_prbs { - DP_DPHY_TP_PRBS7, - DP_DPHY_TP_PRBS9, - DP_DPHY_TP_PRBS11, - DP_DPHY_TP_PRBS15, - DP_DPHY_TP_PRBS23, - DP_DPHY_TP_PRBS31 -}; - -struct hpo_dp_link_enc_state { - uint32_t link_enc_enabled; - uint32_t link_mode; - uint32_t lane_count; - uint32_t slot_count[4]; - uint32_t stream_src[4]; - uint32_t vc_rate_x[4]; - uint32_t vc_rate_y[4]; -}; - -struct hpo_dp_link_encoder { - const struct hpo_dp_link_encoder_funcs *funcs; - struct dc_context *ctx; - int inst; - enum engine_id preferred_engine; - enum transmitter transmitter; - enum hpd_source_id hpd_source; -}; - -struct hpo_dp_link_encoder_funcs { - - void (*enable_link_phy)(struct hpo_dp_link_encoder *enc, - const struct dc_link_settings *link_settings, - enum transmitter transmitter, - enum hpd_source_id hpd_source); - - void (*disable_link_phy)(struct hpo_dp_link_encoder *link_enc, - enum signal_type signal); - - void (*link_enable)( - struct hpo_dp_link_encoder *enc, - enum dc_lane_count num_lanes); - - void (*link_disable)( - struct hpo_dp_link_encoder *enc); - - void (*set_link_test_pattern)( - struct hpo_dp_link_encoder *enc, - struct encoder_set_dp_phy_pattern_param *tp_params); - - void (*update_stream_allocation_table)( - struct hpo_dp_link_encoder *enc, - const struct link_mst_stream_allocation_table *table); - - void (*set_throttled_vcp_size)( - struct hpo_dp_link_encoder *enc, - uint32_t stream_encoder_inst, - struct fixed31_32 avg_time_slots_per_mtp); - - bool (*is_in_alt_mode) ( - struct hpo_dp_link_encoder *enc); - - void (*read_state)( - struct hpo_dp_link_encoder *enc, - struct hpo_dp_link_enc_state *state); - - void (*set_ffe)( - struct hpo_dp_link_encoder *enc, - const struct dc_link_settings *link_settings, - uint8_t ffe_preset); -}; -#endif - #endif /* LINK_ENCODER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index f5fd2a0673..640bb432bd 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -281,7 +281,6 @@ struct mpc_funcs { struct mpcc* (*get_mpcc_for_dpp_from_secondary)( struct mpc_tree *tree, int dpp_id); - struct mpcc* (*get_mpcc_for_dpp)( struct mpc_tree *tree, int dpp_id); @@ -367,7 +366,6 @@ struct mpc_funcs { void (*set_bg_color)(struct mpc *mpc, struct tg_color *bg_color, int mpcc_id); - void (*set_mpc_mem_lp_mode)(struct mpc *mpc); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h index c88e113b94..564ea6a727 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/stream_encoder.h @@ -165,11 +165,9 @@ struct stream_encoder_funcs { struct stream_encoder *enc); void (*dp_blank)( - struct dc_link *link, struct stream_encoder *enc); void (*dp_unblank)( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param); @@ -229,8 +227,7 @@ struct stream_encoder_funcs { void (*dp_set_dsc_pps_info_packet)(struct stream_encoder *enc, bool enable, - uint8_t *dsc_packed_pps, - bool immediate_update); + uint8_t *dsc_packed_pps); void (*set_dynamic_metadata)(struct stream_encoder *enc, bool enable, @@ -245,86 +242,4 @@ struct stream_encoder_funcs { struct stream_encoder *enc); }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct hpo_dp_stream_encoder_state { - uint32_t stream_enc_enabled; - uint32_t vid_stream_enabled; - uint32_t otg_inst; - uint32_t pixel_encoding; - uint32_t component_depth; - uint32_t compressed_format; - uint32_t sdp_enabled; - uint32_t mapped_to_link_enc; -}; - -struct hpo_dp_stream_encoder { - const struct hpo_dp_stream_encoder_funcs *funcs; - struct dc_context *ctx; - struct dc_bios *bp; - uint32_t inst; - enum engine_id id; - struct vpg *vpg; - struct apg *apg; -}; - -struct hpo_dp_stream_encoder_funcs { - void (*enable_stream)( - struct hpo_dp_stream_encoder *enc); - - void (*dp_unblank)( - struct hpo_dp_stream_encoder *enc, - uint32_t stream_source); - - void (*dp_blank)( - struct hpo_dp_stream_encoder *enc); - - void (*disable)( - struct hpo_dp_stream_encoder *enc); - - void (*set_stream_attribute)( - struct hpo_dp_stream_encoder *enc, - struct dc_crtc_timing *crtc_timing, - enum dc_color_space output_color_space, - bool use_vsc_sdp_for_colorimetry, - bool compressed_format, - bool double_buffer_en); - - void (*update_dp_info_packets)( - struct hpo_dp_stream_encoder *enc, - const struct encoder_info_frame *info_frame); - - void (*stop_dp_info_packets)( - struct hpo_dp_stream_encoder *enc); - - void (*dp_set_dsc_pps_info_packet)( - struct hpo_dp_stream_encoder *enc, - bool enable, - uint8_t *dsc_packed_pps, - bool immediate_update); - - void (*map_stream_to_link)( - struct hpo_dp_stream_encoder *enc, - uint32_t stream_enc_inst, - uint32_t link_enc_inst); - - void (*audio_mute_control)( - struct hpo_dp_stream_encoder *enc, bool mute); - - void (*dp_audio_setup)( - struct hpo_dp_stream_encoder *enc, - unsigned int az_inst, - struct audio_info *info); - - void (*dp_audio_enable)( - struct hpo_dp_stream_encoder *enc); - - void (*dp_audio_disable)( - struct hpo_dp_stream_encoder *enc); - - void (*read_state)( - struct hpo_dp_stream_encoder *enc, - struct hpo_dp_stream_encoder_state *state); -}; -#endif - #endif /* STREAM_ENCODER_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index c29320b385..03f47f23fb 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -100,9 +100,6 @@ enum crc_selection { enum otg_out_mux_dest { OUT_MUX_DIO = 0, -#if defined(CONFIG_DRM_AMD_DC_DCN) - OUT_MUX_HPO_DP = 2, -#endif }; enum h_timing_div_mode { @@ -290,8 +287,6 @@ struct timing_generator_funcs { enum optc_dsc_mode dsc_mode, uint32_t dsc_bytes_per_pixel, uint32_t dsc_slice_width); - void (*get_dsc_status)(struct timing_generator *optc, - uint32_t *dsc_mode); void (*set_odm_bypass)(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); void (*set_odm_combine)(struct timing_generator *optc, int *opp_id, int opp_cnt, struct dc_crtc_timing *timing); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 05053f3b4a..ad5f2adcc4 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -64,7 +64,6 @@ struct hw_sequencer_funcs { enum dc_status (*apply_ctx_to_hw)(struct dc *dc, struct dc_state *context); void (*disable_plane)(struct dc *dc, struct pipe_ctx *pipe_ctx); - void (*disable_pixel_data)(struct dc *dc, struct pipe_ctx *pipe_ctx, bool blank); void (*apply_ctx_for_surface)(struct dc *dc, const struct dc_stream_state *stream, int num_planes, struct dc_state *context); @@ -237,7 +236,7 @@ struct hw_sequencer_funcs { const struct tg_color *solid_color, int width, int height, int offset); - void (*z10_restore)(const struct dc *dc); + void (*z10_restore)(struct dc *dc); void (*z10_save_init)(struct dc *dc); void (*update_visual_confirm_color)(struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h index c2008258c5..f7f7e4fff0 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer_private.h @@ -41,9 +41,6 @@ struct dce_hwseq_wa { bool DEGVIDCN10_254; bool DEGVIDCN21; bool disallow_self_refresh_during_multi_plane_transition; -#if defined(CONFIG_DRM_AMD_DC_DCN) - bool dp_hpo_and_otg_sequence; -#endif }; struct hwseq_wa_state { @@ -143,7 +140,6 @@ struct hwseq_private_funcs { const struct dc_plane_state *plane_state); void (*PLAT_58856_wa)(struct dc_state *context, struct pipe_ctx *pipe_ctx); - void (*setup_hpo_hw_control)(const struct dce_hwseq *hws, bool enable); }; struct dce_hwseq { @@ -155,10 +151,6 @@ struct dce_hwseq { struct hwseq_wa_state wa_state; struct hwseq_private_funcs funcs; - PHYSICAL_ADDRESS_LOC fb_base; - PHYSICAL_ADDRESS_LOC fb_top; - PHYSICAL_ADDRESS_LOC fb_offset; - PHYSICAL_ADDRESS_LOC uma_top; }; #endif /* __DC_HW_SEQUENCER_PRIVATE_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h index a4e43b4826..883dd8733e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_enc_cfg.h @@ -36,7 +36,7 @@ * Initialise link encoder resource tracking. */ void link_enc_cfg_init( - const struct dc *dc, + struct dc *dc, struct dc_state *state); /* @@ -70,36 +70,22 @@ void link_enc_cfg_link_enc_unassign( * endpoint. */ bool link_enc_cfg_is_transmitter_mappable( - struct dc *dc, + struct dc_state *state, struct link_encoder *link_enc); -/* Return stream using DIG link encoder resource. NULL if unused. */ -struct dc_stream_state *link_enc_cfg_get_stream_using_link_enc( - struct dc *dc, - enum engine_id eng_id); - /* Return link using DIG link encoder resource. NULL if unused. */ struct dc_link *link_enc_cfg_get_link_using_link_enc( - struct dc *dc, + struct dc_state *state, enum engine_id eng_id); /* Return DIG link encoder used by link. NULL if unused. */ struct link_encoder *link_enc_cfg_get_link_enc_used_by_link( - struct dc *dc, + struct dc_state *state, const struct dc_link *link); /* Return next available DIG link encoder. NULL if none available. */ -struct link_encoder *link_enc_cfg_get_next_avail_link_enc(struct dc *dc); - -/* Return DIG link encoder used by stream. NULL if unused. */ -struct link_encoder *link_enc_cfg_get_link_enc_used_by_stream( - struct dc *dc, - const struct dc_stream_state *stream); - -/* Return true if encoder available to use. */ -bool link_enc_cfg_is_link_enc_avail(struct dc *dc, enum engine_id eng_id, struct dc_link *link); - -/* Returns true if encoder assignments in supplied state pass validity checks. */ -bool link_enc_cfg_validate(struct dc *dc, struct dc_state *state); +struct link_encoder *link_enc_cfg_get_next_avail_link_enc( + const struct dc *dc, + const struct dc_state *state); #endif /* DC_INC_LINK_ENC_CFG_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h index 69d63763a1..fc1d289bb9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h @@ -32,38 +32,31 @@ struct gpio *get_hpd_gpio(struct dc_bios *dcb, void dp_enable_link_phy( struct dc_link *link, - const struct link_resource *link_res, enum signal_type signal, enum clock_source_id clock_source, const struct dc_link_settings *link_settings); void dp_receiver_power_ctrl(struct dc_link *link, bool on); -void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode); void edp_add_delay_for_T9(struct dc_link *link); bool edp_receiver_ready_T9(struct dc_link *link); bool edp_receiver_ready_T7(struct dc_link *link); -void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res, - enum signal_type signal); +void dp_disable_link_phy(struct dc_link *link, enum signal_type signal); -void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res, - enum signal_type signal); +void dp_disable_link_phy_mst(struct dc_link *link, enum signal_type signal); bool dp_set_hw_training_pattern( struct dc_link *link, - const struct link_resource *link_res, enum dc_dp_training_pattern pattern, uint32_t offset); void dp_set_hw_lane_settings( struct dc_link *link, - const struct link_resource *link_res, const struct link_training_settings *link_settings, uint32_t offset); void dp_set_hw_test_pattern( struct dc_link *link, - const struct link_resource *link_res, enum dp_test_pattern test_pattern, uint8_t *custom_pattern, uint32_t custom_pattern_size); diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index dbfe6690de..fe1e5833c9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -34,10 +34,6 @@ #define MEMORY_TYPE_HBM 2 -#define IS_PIPE_SYNCD_VALID(pipe) ((((pipe)->pipe_idx_syncd) & 0x80)?1:0) -#define GET_PIPE_SYNCD_FROM_PIPE(pipe) ((pipe)->pipe_idx_syncd & 0x7F) -#define SET_PIPE_SYNCD_TO_PIPE(pipe, pipe_syncd) ((pipe)->pipe_idx_syncd = (0x80 | pipe_syncd)) - enum dce_version resource_parse_asic_id( struct hw_asic_id asic_id); @@ -53,11 +49,6 @@ struct resource_caps { int num_vmid; int num_dsc; unsigned int num_dig_link_enc; // Total number of DIGs (digital encoders) in DIO (Display Input/Output). - unsigned int num_usb4_dpia; // Total number of USB4 DPIA (DisplayPort Input Adapters). -#if defined(CONFIG_DRM_AMD_DC_DCN) - int num_hpo_dp_stream_encoder; - int num_hpo_dp_link_encoder; -#endif int num_mpc_3dlut; }; @@ -77,15 +68,6 @@ struct resource_create_funcs { struct stream_encoder *(*create_stream_encoder)( enum engine_id eng_id, struct dc_context *ctx); -#if defined(CONFIG_DRM_AMD_DC_DCN) - struct hpo_dp_stream_encoder *(*create_hpo_dp_stream_encoder)( - enum engine_id eng_id, struct dc_context *ctx); - - struct hpo_dp_link_encoder *(*create_hpo_dp_link_encoder)( - uint8_t inst, - struct dc_context *ctx); -#endif - struct dce_hwseq *(*create_hwseq)( struct dc_context *ctx); }; @@ -205,20 +187,4 @@ int get_num_mpc_splits(struct pipe_ctx *pipe); int get_num_odm_splits(struct pipe_ctx *pipe); -#if defined(CONFIG_DRM_AMD_DC_DCN) -struct hpo_dp_link_encoder *resource_get_hpo_dp_link_enc_for_det_lt( - const struct resource_context *res_ctx, - const struct resource_pool *pool, - const struct dc_link *link); -#endif - -void reset_syncd_pipes_from_disabled_pipes(struct dc *dc, - struct dc_state *context); - -void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc, - struct dc_state *context, - uint8_t disabled_master_pipe_idx); - -uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter); - #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/irq/Makefile b/drivers/gpu/drm/amd/display/dc/irq/Makefile index fd739aecf1..0d09181227 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/Makefile +++ b/drivers/gpu/drm/amd/display/dc/irq/Makefile @@ -93,16 +93,6 @@ IRQ_DCN21 = irq_service_dcn21.o AMD_DAL_IRQ_DCN21= $(addprefix $(AMDDALPATH)/dc/irq/dcn21/,$(IRQ_DCN21)) AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN21) - -############################################################################### -# DCN 201 -############################################################################### -IRQ_DCN201 = irq_service_dcn201.o - -AMD_DAL_IRQ_DCN201 = $(addprefix $(AMDDALPATH)/dc/irq/dcn201/,$(IRQ_DCN201)) - -AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCN201) - ############################################################################### # DCN 30 ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index 6b5fedd9ac..378cc11aa0 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -185,18 +185,16 @@ bool dal_irq_service_dummy_set(struct irq_service *irq_service, const struct irq_source_info *info, bool enable) { - DC_LOG_ERROR("%s: called for non-implemented irq source, src_id=%u, ext_id=%u\n", - __func__, info->src_id, info->ext_id); - + DC_LOG_ERROR("%s: called for non-implemented irq source\n", + __func__); return false; } bool dal_irq_service_dummy_ack(struct irq_service *irq_service, const struct irq_source_info *info) { - DC_LOG_ERROR("%s: called for non-implemented irq source, src_id=%u, ext_id=%u\n", - __func__, info->src_id, info->ext_id); - + DC_LOG_ERROR("%s: called for non-implemented irq source\n", + __func__); return false; } diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index cf072e2347..34f43cb650 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -40,9 +40,10 @@ #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" -static enum dc_irq_source to_dal_irq_source_dcn10(struct irq_service *irq_service, - uint32_t src_id, - uint32_t ext_id) +enum dc_irq_source to_dal_irq_source_dcn10( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) { switch (src_id) { case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c index 0f15bcada4..ed54e1c819 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -40,9 +40,10 @@ #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" -static enum dc_irq_source to_dal_irq_source_dcn21(struct irq_service *irq_service, - uint32_t src_id, - uint32_t ext_id) +enum dc_irq_source to_dal_irq_source_dcn21( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) { switch (src_id) { case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c index 1b88e4e627..38e0ade60c 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c @@ -36,9 +36,10 @@ #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" -static enum dc_irq_source to_dal_irq_source_dcn31(struct irq_service *irq_service, - uint32_t src_id, - uint32_t ext_id) +enum dc_irq_source to_dal_irq_source_dcn31( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) { switch (src_id) { case DCN_1_0__SRCID__DC_D1_OTG_VSTARTUP: diff --git a/drivers/gpu/drm/amd/display/dc/os_types.h b/drivers/gpu/drm/amd/display/dc/os_types.h index 5df1d80c83..f50cae252d 100644 --- a/drivers/gpu/drm/amd/display/dc/os_types.h +++ b/drivers/gpu/drm/amd/display/dc/os_types.h @@ -31,12 +31,10 @@ #include #include #include -#include #include #include -#include #include "cgs_common.h" diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c index 1e39aae6b1..1053b165c1 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c @@ -69,11 +69,9 @@ static void virtual_stream_encoder_stop_dp_info_packets( struct stream_encoder *enc) {} static void virtual_stream_encoder_dp_blank( - struct dc_link *link, struct stream_encoder *enc) {} static void virtual_stream_encoder_dp_unblank( - struct dc_link *link, struct stream_encoder *enc, const struct encoder_unblank_param *param) {} @@ -104,8 +102,7 @@ static void virtual_setup_stereo_sync( static void virtual_stream_encoder_set_dsc_pps_info_packet( struct stream_encoder *enc, bool enable, - uint8_t *dsc_packed_pps, - bool immediate_update) + uint8_t *dsc_packed_pps) {} static const struct stream_encoder_funcs virtual_str_enc_funcs = { diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index 83855b8a32..caf961bb63 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -84,7 +84,6 @@ enum dmub_status { DMUB_STATUS_QUEUE_FULL, DMUB_STATUS_TIMEOUT, DMUB_STATUS_INVALID, - DMUB_STATUS_HW_FAILURE, }; /* enum dmub_asic - dmub asic identifier */ @@ -97,7 +96,6 @@ enum dmub_asic { DMUB_ASIC_DCN302, DMUB_ASIC_DCN303, DMUB_ASIC_DCN31, - DMUB_ASIC_DCN31B, DMUB_ASIC_MAX, }; @@ -120,7 +118,6 @@ enum dmub_notification_type { DMUB_NOTIFICATION_AUX_REPLY, DMUB_NOTIFICATION_HPD, DMUB_NOTIFICATION_HPD_IRQ, - DMUB_NOTIFICATION_SET_CONFIG_REPLY, DMUB_NOTIFICATION_MAX }; @@ -238,9 +235,6 @@ struct dmub_srv_hw_params { bool load_inst_const; bool skip_panel_power_sequence; bool disable_z10; - bool power_optimization; - bool dpia_supported; - bool disable_dpia; }; /** @@ -360,14 +354,10 @@ struct dmub_srv_hw_funcs { uint32_t (*get_gpint_dataout)(struct dmub_srv *dmub); - void (*clear_inbox0_ack_register)(struct dmub_srv *dmub); - uint32_t (*read_inbox0_ack_register)(struct dmub_srv *dmub); void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data); uint32_t (*get_current_time)(struct dmub_srv *dmub); void (*get_diagnostic_data)(struct dmub_srv *dmub, struct dmub_diagnostic_data *dmub_oca); - - bool (*should_detect)(struct dmub_srv *dmub); }; /** @@ -411,7 +401,6 @@ struct dmub_srv { struct dmub_srv_base_funcs funcs; struct dmub_srv_hw_funcs hw_funcs; struct dmub_rb inbox1_rb; - uint32_t inbox1_last_wptr; /** * outbox1_rb is accessed without locks (dal & dc) * and to be used only in dmub_srv_stat_get_notification() @@ -448,7 +437,6 @@ struct dmub_notification { union { struct aux_reply_data aux_reply; enum dp_hpd_status hpd_status; - enum set_config_status sc_status; }; }; @@ -736,47 +724,6 @@ bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entr bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); -bool dmub_srv_should_detect(struct dmub_srv *dmub); - -/** - * dmub_srv_send_inbox0_cmd() - Send command to DMUB using INBOX0 - * @dmub: the dmub service - * @data: the data to be sent in the INBOX0 command - * - * Send command by writing directly to INBOX0 WPTR - * - * Return: - * DMUB_STATUS_OK - success - * DMUB_STATUS_INVALID - hw_init false or hw function does not exist - */ -enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); - -/** - * dmub_srv_wait_for_inbox0_ack() - wait for DMUB to ACK INBOX0 command - * @dmub: the dmub service - * @timeout_us: the maximum number of microseconds to wait - * - * Wait for DMUB to ACK the INBOX0 message - * - * Return: - * DMUB_STATUS_OK - success - * DMUB_STATUS_INVALID - hw_init false or hw function does not exist - * DMUB_STATUS_TIMEOUT - wait for ack timed out - */ -enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us); - -/** - * dmub_srv_wait_for_inbox0_ack() - clear ACK register for INBOX0 - * @dmub: the dmub service - * - * Clear ACK register for INBOX0 - * - * Return: - * DMUB_STATUS_OK - success - * DMUB_STATUS_INVALID - hw_init false or hw function does not exist - */ -enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub); - #if defined(__cplusplus) } #endif diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 873ecd04e0..7efe9ba870 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -46,10 +46,10 @@ /* Firmware versioning. */ #ifdef DMUB_EXPOSE_VERSION -#define DMUB_FW_VERSION_GIT_HASH 0xbaf06b95 +#define DMUB_FW_VERSION_GIT_HASH 0x7383caadc #define DMUB_FW_VERSION_MAJOR 0 #define DMUB_FW_VERSION_MINOR 0 -#define DMUB_FW_VERSION_REVISION 98 +#define DMUB_FW_VERSION_REVISION 79 #define DMUB_FW_VERSION_TEST 0 #define DMUB_FW_VERSION_VBIOS 0 #define DMUB_FW_VERSION_HOTFIX 0 @@ -172,6 +172,13 @@ extern "C" { #define dmub_udelay(microseconds) udelay(microseconds) #endif +/** + * Number of nanoseconds per DMUB tick. + * DMCUB_TIMER_CURRENT increments in DMUB ticks, which are 10ns by default. + * If DMCUB_TIMER_WINDOW is non-zero this will no longer be true. + */ +#define NS_PER_DMUB_TICK 10 + /** * union dmub_addr - DMUB physical/virtual 64-bit address. */ @@ -201,9 +208,10 @@ union dmub_psr_debug_flags { uint32_t use_hw_lock_mgr : 1; /** - * Use TPS3 signal when restore main link. + * Unused. + * TODO: Remove. */ - uint32_t force_wakeup_by_tps3 : 1; + uint32_t log_line_nums : 1; } bitfields; /** @@ -360,15 +368,10 @@ union dmub_fw_boot_options { uint32_t disable_clk_gate: 1; /**< 1 if clock gating should be disabled */ uint32_t skip_phy_init_panel_sequence: 1; /**< 1 to skip panel init seq */ uint32_t z10_disable: 1; /**< 1 to disable z10 */ - uint32_t enable_dpia: 1; /**< 1 if DPIA should be enabled */ + uint32_t reserved2: 1; /**< reserved for an unreleased feature */ + uint32_t reserved_unreleased1: 1; /**< reserved for an unreleased feature */ uint32_t invalid_vbios_data: 1; /**< 1 if VBIOS data table is invalid */ - uint32_t dpia_supported: 1; /**< 1 if DPIA is supported on this platform */ - uint32_t sel_mux_phy_c_d_phy_f_g: 1; /**< 1 if PHYF/PHYG should be enabled */ - /**< 1 if all root clock gating is enabled and low power memory is enabled*/ - uint32_t power_optimization: 1; - uint32_t diag_env: 1; /* 1 if diagnostic environment */ - - uint32_t reserved : 19; /**< reserved */ + uint32_t reserved : 23; /**< reserved */ } bits; /**< boot bits */ uint32_t all; /**< 32-bit access to bits */ }; @@ -408,14 +411,7 @@ enum dmub_cmd_vbios_type { * Enables or disables power gating. */ DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING = 3, - /** - * Controls embedded panels. - */ DMUB_CMD__VBIOS_LVTMA_CONTROL = 15, - /** - * Query DP alt status on a transmitter. - */ - DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT = 26, }; //============================================================================== @@ -656,10 +652,6 @@ enum dmub_cmd_type { * Command type used for all panel control commands. */ DMUB_CMD__PANEL_CNTL = 74, - /** - * Command type used for interfacing with DPIA. - */ - DMUB_CMD__DPIA = 77, /** * Command type used for EDID CEA parsing */ @@ -682,21 +674,6 @@ enum dmub_out_cmd_type { * Command type used for DP AUX Reply data notification */ DMUB_OUT_CMD__DP_AUX_REPLY = 1, - /** - * Command type used for DP HPD event notification - */ - DMUB_OUT_CMD__DP_HPD_NOTIFY = 2, - /** - * Command type used for SET_CONFIG Reply notification - */ - DMUB_OUT_CMD__SET_CONFIG_REPLY = 3, -}; - -/* DMUB_CMD__DPIA command sub-types. */ -enum dmub_cmd_dpia_type { - DMUB_CMD__DPIA_DIG1_DPIA_CONTROL = 0, - DMUB_CMD__DPIA_SET_CONFIG_ACCESS = 1, - DMUB_CMD__DPIA_MST_ALLOC_SLOTS = 2, }; #pragma pack(push, 1) @@ -996,7 +973,7 @@ struct dmub_dig_transmitter_control_data_v1_7 { uint8_t hpdsel; /**< =1: HPD1, =2: HPD2, ..., =6: HPD6, =0: HPD is not assigned */ uint8_t digfe_sel; /**< DIG front-end selection, bit0 means DIG0 FE is enabled */ uint8_t connobj_id; /**< Connector Object Id defined in ObjectId.h */ - uint8_t HPO_instance; /**< HPO instance (0: inst0, 1: inst1) */ + uint8_t reserved0; /**< For future use */ uint8_t reserved1; /**< For future use */ uint8_t reserved2[3]; /**< For future use */ uint32_t reserved3[11]; /**< For future use */ @@ -1018,77 +995,6 @@ struct dmub_rb_cmd_dig1_transmitter_control { union dmub_cmd_dig1_transmitter_control_data transmitter_control; /**< payload */ }; -/** - * DPIA tunnel command parameters. - */ -struct dmub_cmd_dig_dpia_control_data { - uint8_t enc_id; /** 0 = ENGINE_ID_DIGA, ... */ - uint8_t action; /** ATOM_TRANSMITER_ACTION_DISABLE/ENABLE/SETUP_VSEMPH */ - union { - uint8_t digmode; /** enum atom_encode_mode_def */ - uint8_t dplaneset; /** DP voltage swing and pre-emphasis value */ - } mode_laneset; - uint8_t lanenum; /** Lane number 1, 2, 4, 8 */ - uint32_t symclk_10khz; /** Symbol Clock in 10Khz */ - uint8_t hpdsel; /** =0: HPD is not assigned */ - uint8_t digfe_sel; /** DIG stream( front-end ) selection, bit0 - DIG0 FE */ - uint8_t dpia_id; /** Index of DPIA */ - uint8_t fec_rdy : 1; - uint8_t reserved : 7; - uint32_t reserved1; -}; - -/** - * DMUB command for DPIA tunnel control. - */ -struct dmub_rb_cmd_dig1_dpia_control { - struct dmub_cmd_header header; - struct dmub_cmd_dig_dpia_control_data dpia_control; -}; - -/** - * SET_CONFIG Command Payload - */ -struct set_config_cmd_payload { - uint8_t msg_type; /* set config message type */ - uint8_t msg_data; /* set config message data */ -}; - -/** - * Data passed from driver to FW in a DMUB_CMD__DPIA_SET_CONFIG_ACCESS command. - */ -struct dmub_cmd_set_config_control_data { - struct set_config_cmd_payload cmd_pkt; - uint8_t instance; /* DPIA instance */ - uint8_t immed_status; /* Immediate status returned in case of error */ -}; - -/** - * DMUB command structure for SET_CONFIG command. - */ -struct dmub_rb_cmd_set_config_access { - struct dmub_cmd_header header; /* header */ - struct dmub_cmd_set_config_control_data set_config_control; /* set config data */ -}; - -/** - * Data passed from driver to FW in a DMUB_CMD__DPIA_MST_ALLOC_SLOTS command. - */ -struct dmub_cmd_mst_alloc_slots_control_data { - uint8_t mst_alloc_slots; /* mst slots to be allotted */ - uint8_t instance; /* DPIA instance */ - uint8_t immed_status; /* Immediate status returned as there is no outbox msg posted */ - uint8_t mst_slots_in_use; /* returns slots in use for error cases */ -}; - -/** - * DMUB command structure for SET_ command. - */ -struct dmub_rb_cmd_set_mst_alloc_slots { - struct dmub_cmd_header header; /* header */ - struct dmub_cmd_mst_alloc_slots_control_data mst_slots_control; /* mst slots control */ -}; - /** * struct dmub_rb_cmd_dpphy_init - DPPHY init. */ @@ -1336,33 +1242,6 @@ struct dmub_rb_cmd_dp_hpd_notify { struct dp_hpd_data hpd_data; }; -/** - * Definition of a SET_CONFIG reply from DPOA. - */ -enum set_config_status { - SET_CONFIG_PENDING = 0, - SET_CONFIG_ACK_RECEIVED, - SET_CONFIG_RX_TIMEOUT, - SET_CONFIG_UNKNOWN_ERROR, -}; - -/** - * Definition of a set_config reply - */ -struct set_config_reply_control_data { - uint8_t instance; /* DPIA Instance */ - uint8_t status; /* Set Config reply */ - uint16_t pad; /* Alignment */ -}; - -/** - * Definition of a DMUB_OUT_CMD__SET_CONFIG_REPLY command. - */ -struct dmub_rb_cmd_dp_set_config_reply { - struct dmub_cmd_header header; - struct set_config_reply_control_data set_config_reply_control; -}; - /* * Command IDs should be treated as stable ABI. * Do not reuse or modify IDs. @@ -1401,10 +1280,6 @@ enum dmub_cmd_psr_type { * Forces PSR enabled until an explicit PSR disable call. */ DMUB_CMD__PSR_FORCE_STATIC = 5, - /** - * Set PSR power option - */ - DMUB_CMD__SET_PSR_POWER_OPT = 7, }; /** @@ -1549,14 +1424,10 @@ struct dmub_cmd_psr_copy_settings_data { * Currently the support is only for 0 or 1 */ uint8_t panel_inst; - /* - * DSC enable status in driver - */ - uint8_t dsc_enable_status; /** - * Explicit padding to 3 byte boundary. + * Explicit padding to 4 byte boundary. */ - uint8_t pad3[3]; + uint8_t pad3[4]; }; /** @@ -1706,44 +1577,6 @@ struct dmub_rb_cmd_psr_force_static { struct dmub_cmd_psr_force_static_data psr_force_static_data; }; -/** - * Data passed from driver to FW in a DMUB_CMD__SET_PSR_POWER_OPT command. - */ -struct dmub_cmd_psr_set_power_opt_data { - /** - * PSR control version. - */ - uint8_t cmd_version; - /** - * Panel Instance. - * Panel isntance to identify which psr_state to use - * Currently the support is only for 0 or 1 - */ - uint8_t panel_inst; - /** - * Explicit padding to 4 byte boundary. - */ - uint8_t pad[2]; - /** - * PSR power option - */ - uint32_t power_opt; -}; - -/** - * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. - */ -struct dmub_rb_cmd_psr_set_power_opt { - /** - * Command header. - */ - struct dmub_cmd_header header; - /** - * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. - */ - struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data; -}; - /** * Set of HW components that can be locked. * @@ -1897,11 +1730,6 @@ enum dmub_cmd_abm_type { * Enable/disable fractional duty cycle for backlight PWM. */ DMUB_CMD__ABM_SET_PWM_FRAC = 5, - - /** - * unregister vertical interrupt after steady state is reached - */ - DMUB_CMD__ABM_PAUSE = 6, }; /** @@ -2257,50 +2085,6 @@ struct dmub_rb_cmd_abm_init_config { struct dmub_cmd_abm_init_config_data abm_init_config_data; }; -/** - * Data passed from driver to FW in a DMUB_CMD__ABM_PAUSE command. - */ - -struct dmub_cmd_abm_pause_data { - - /** - * Panel Control HW instance mask. - * Bit 0 is Panel Control HW instance 0. - * Bit 1 is Panel Control HW instance 1. - */ - uint8_t panel_mask; - - /** - * OTG hw instance - */ - uint8_t otg_inst; - - /** - * Enable or disable ABM pause - */ - uint8_t enable; - - /** - * Explicit padding to 4 byte boundary. - */ - uint8_t pad[1]; -}; - -/** - * Definition of a DMUB_CMD__ABM_PAUSE command. - */ -struct dmub_rb_cmd_abm_pause { - /** - * Command header. - */ - struct dmub_cmd_header header; - - /** - * Data passed from driver to FW in a DMUB_CMD__ABM_PAUSE command. - */ - struct dmub_cmd_abm_pause_data abm_pause_data; -}; - /** * Data passed from driver to FW in a DMUB_CMD__QUERY_FEATURE_CAPS command. */ @@ -2400,24 +2184,6 @@ struct dmub_rb_cmd_lvtma_control { struct dmub_cmd_lvtma_control_data data; }; -/** - * Data passed in/out in a DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT command. - */ -struct dmub_rb_cmd_transmitter_query_dp_alt_data { - uint8_t phy_id; /**< 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4=UNIPHYE, 5=UNIPHYF */ - uint8_t is_usb; /**< is phy is usb */ - uint8_t is_dp_alt_disable; /**< is dp alt disable */ - uint8_t is_dp4; /**< is dp in 4 lane */ -}; - -/** - * Definition of a DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT command. - */ -struct dmub_rb_cmd_transmitter_query_dp_alt { - struct dmub_cmd_header header; /**< header */ - struct dmub_rb_cmd_transmitter_query_dp_alt_data data; /**< payload */ -}; - /** * Maximum number of bytes a chunk sent to DMUB for parsing */ @@ -2429,7 +2195,7 @@ struct dmub_rb_cmd_transmitter_query_dp_alt { struct dmub_cmd_send_edid_cea { uint16_t offset; /**< offset into the CEA block */ uint8_t length; /**< number of bytes in payload to copy as part of CEA block */ - uint16_t cea_total_length; /**< total length of the CEA block */ + uint16_t total_length; /**< total length of the CEA block */ uint8_t payload[DMUB_EDID_CEA_DATA_CHUNK_BYTES]; /**< data chunk of the CEA block */ uint8_t pad[3]; /**< padding and for future expansion */ }; @@ -2545,10 +2311,6 @@ union dmub_rb_cmd { * Definition of a DMUB_CMD__PSR_FORCE_STATIC command. */ struct dmub_rb_cmd_psr_force_static psr_force_static; - /** - * Definition of a DMUB_CMD__SET_PSR_POWER_OPT command. - */ - struct dmub_rb_cmd_psr_set_power_opt psr_set_power_opt; /** * Definition of a DMUB_CMD__PLAT_54186_WA command. */ @@ -2601,11 +2363,6 @@ union dmub_rb_cmd { */ struct dmub_rb_cmd_abm_init_config abm_init_config; - /** - * Definition of a DMUB_CMD__ABM_PAUSE command. - */ - struct dmub_rb_cmd_abm_pause abm_pause; - /** * Definition of a DMUB_CMD__DP_AUX_ACCESS command. */ @@ -2625,22 +2382,6 @@ union dmub_rb_cmd { * Definition of a DMUB_CMD__VBIOS_LVTMA_CONTROL command. */ struct dmub_rb_cmd_lvtma_control lvtma_control; - /** - * Definition of a DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT command. - */ - struct dmub_rb_cmd_transmitter_query_dp_alt query_dp_alt; - /** - * Definition of a DMUB_CMD__DPIA_DIG1_CONTROL command. - */ - struct dmub_rb_cmd_dig1_dpia_control dig1_dpia_control; - /** - * Definition of a DMUB_CMD__DPIA_SET_CONFIG_ACCESS command. - */ - struct dmub_rb_cmd_set_config_access set_config_access; - /** - * Definition of a DMUB_CMD__DPIA_MST_ALLOC_SLOTS command. - */ - struct dmub_rb_cmd_set_mst_alloc_slots set_mst_alloc_slots; /** * Definition of a DMUB_CMD__EDID_CEA command. */ @@ -2663,10 +2404,6 @@ union dmub_rb_out_cmd { * HPD notify command. */ struct dmub_rb_cmd_dp_hpd_notify dp_hpd_notify; - /** - * SET_CONFIG reply command. - */ - struct dmub_rb_cmd_dp_set_config_reply set_config_reply; }; #pragma pack(pop) @@ -2747,16 +2484,14 @@ static inline bool dmub_rb_full(struct dmub_rb *rb) static inline bool dmub_rb_push_front(struct dmub_rb *rb, const union dmub_rb_cmd *cmd) { - uint64_t volatile *dst = (uint64_t volatile *)((uint8_t *)(rb->base_address) + rb->wrpt); - const uint64_t *src = (const uint64_t *)cmd; - uint8_t i; + uint8_t *dst = (uint8_t *)(rb->base_address) + rb->wrpt; + const uint8_t *src = (const uint8_t *)cmd; if (dmub_rb_full(rb)) return false; // copying data - for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) - *dst++ = *src++; + dmub_memcpy(dst, src, DMUB_RB_CMD_SIZE); rb->wrpt += DMUB_RB_CMD_SIZE; @@ -2865,16 +2600,14 @@ static inline bool dmub_rb_peek_offset(struct dmub_rb *rb, static inline bool dmub_rb_out_front(struct dmub_rb *rb, union dmub_rb_out_cmd *cmd) { - const uint64_t volatile *src = (const uint64_t volatile *)((uint8_t *)(rb->base_address) + rb->rptr); - uint64_t *dst = (uint64_t *)cmd; - uint8_t i; + const uint8_t *src = (const uint8_t *)(rb->base_address) + rb->rptr; + uint8_t *dst = (uint8_t *)cmd; if (dmub_rb_empty(rb)) return false; // copying data - for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) - *dst++ = *src++; + dmub_memcpy(dst, src, DMUB_RB_CMD_SIZE); return true; } @@ -2909,17 +2642,14 @@ static inline bool dmub_rb_pop_front(struct dmub_rb *rb) */ static inline void dmub_rb_flush_pending(const struct dmub_rb *rb) { + uint8_t buf[DMUB_RB_CMD_SIZE]; uint32_t rptr = rb->rptr; uint32_t wptr = rb->wrpt; while (rptr != wptr) { - uint64_t volatile *data = (uint64_t volatile *)((uint8_t *)(rb->base_address) + rptr); - //uint64_t volatile *p = (uint64_t volatile *)data; - uint64_t temp; - uint8_t i; + const uint8_t *data = (const uint8_t *)rb->base_address + rptr; - for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) - temp = *data++; + dmub_memcpy(buf, data, DMUB_RB_CMD_SIZE); rptr += DMUB_RB_CMD_SIZE; if (rptr >= rb->capacity) diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index fa0569174a..fc667cb17e 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -338,11 +338,6 @@ void dmub_dcn31_enable_dmub_boot_options(struct dmub_srv *dmub, const struct dmu union dmub_fw_boot_options boot_options = {0}; boot_options.bits.z10_disable = params->disable_z10; - boot_options.bits.dpia_supported = params->dpia_supported; - boot_options.bits.enable_dpia = params->disable_dpia ? 0 : 1; - boot_options.bits.power_optimization = params->power_optimization; - - boot_options.bits.sel_mux_phy_c_d_phy_f_g = (dmub->asic == DMUB_ASIC_DCN31B) ? 1 : 0; REG_WRITE(DMCUB_SCRATCH14, boot_options.all); } @@ -437,11 +432,3 @@ void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnosti REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled); diag_data->is_cw6_enabled = is_cw6_enabled; } - -bool dmub_dcn31_should_detect(struct dmub_srv *dmub) -{ - uint32_t fw_boot_status = REG_READ(DMCUB_SCRATCH0); - bool should_detect = fw_boot_status & DMUB_FW_BOOT_STATUS_BIT_DETECTION_REQUIRED; - return should_detect; -} - diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index 59ddc81b5a..bb62605d2a 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -245,6 +245,4 @@ uint32_t dmub_dcn31_get_current_time(struct dmub_srv *dmub); void dmub_dcn31_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); -bool dmub_dcn31_should_detect(struct dmub_srv *dmub); - #endif /* _DMUB_DCN31_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 9280f2abd9..75a91cfaf0 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -100,9 +100,24 @@ void dmub_flush_buffer_mem(const struct dmub_fb *fb) } static const struct dmub_fw_meta_info * -dmub_get_fw_meta_info_from_blob(const uint8_t *blob, uint32_t blob_size, uint32_t meta_offset) +dmub_get_fw_meta_info(const struct dmub_srv_region_params *params) { const union dmub_fw_meta *meta; + const uint8_t *blob = NULL; + uint32_t blob_size = 0; + uint32_t meta_offset = 0; + + if (params->fw_bss_data && params->bss_data_size) { + /* Legacy metadata region. */ + blob = params->fw_bss_data; + blob_size = params->bss_data_size; + meta_offset = DMUB_FW_META_OFFSET; + } else if (params->fw_inst_const && params->inst_const_size) { + /* Combined metadata region. */ + blob = params->fw_inst_const; + blob_size = params->inst_const_size; + meta_offset = 0; + } if (!blob || !blob_size) return NULL; @@ -119,32 +134,6 @@ dmub_get_fw_meta_info_from_blob(const uint8_t *blob, uint32_t blob_size, uint32_ return &meta->info; } -static const struct dmub_fw_meta_info * -dmub_get_fw_meta_info(const struct dmub_srv_region_params *params) -{ - const struct dmub_fw_meta_info *info = NULL; - - if (params->fw_bss_data && params->bss_data_size) { - /* Legacy metadata region. */ - info = dmub_get_fw_meta_info_from_blob(params->fw_bss_data, - params->bss_data_size, - DMUB_FW_META_OFFSET); - } else if (params->fw_inst_const && params->inst_const_size) { - /* Combined metadata region - can be aligned to 16-bytes. */ - uint32_t i; - - for (i = 0; i < 16; ++i) { - info = dmub_get_fw_meta_info_from_blob( - params->fw_inst_const, params->inst_const_size, i); - - if (info) - break; - } - } - - return info; -} - static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) { struct dmub_srv_hw_funcs *funcs = &dmub->hw_funcs; @@ -219,7 +208,6 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) break; case DMUB_ASIC_DCN31: - case DMUB_ASIC_DCN31B: dmub->regs_dcn31 = &dmub_srv_dcn31_regs; funcs->reset = dmub_dcn31_reset; funcs->reset_release = dmub_dcn31_reset_release; @@ -246,7 +234,7 @@ static bool dmub_srv_hw_setup(struct dmub_srv *dmub, enum dmub_asic asic) funcs->set_outbox0_rptr = dmub_dcn31_set_outbox0_rptr; funcs->get_diagnostic_data = dmub_dcn31_get_diagnostic_data; - funcs->should_detect = dmub_dcn31_should_detect; + funcs->get_current_time = dmub_dcn31_get_current_time; break; @@ -609,8 +597,6 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub) { - struct dmub_rb flush_rb; - if (!dmub->hw_init) return DMUB_STATUS_INVALID; @@ -619,14 +605,9 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub) * been flushed to framebuffer memory. Otherwise DMCUB might * read back stale, fully invalid or partially invalid data. */ - flush_rb = dmub->inbox1_rb; - flush_rb.rptr = dmub->inbox1_last_wptr; - dmub_rb_flush_pending(&flush_rb); - - dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt); - - dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; + dmub_rb_flush_pending(&dmub->inbox1_rb); + dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt); return DMUB_STATUS_OK; } @@ -674,19 +655,13 @@ enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub, enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub, uint32_t timeout_us) { - uint32_t i, rptr; + uint32_t i; if (!dmub->hw_init) return DMUB_STATUS_INVALID; for (i = 0; i <= timeout_us; ++i) { - rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); - - if (rptr > dmub->inbox1_rb.capacity) - return DMUB_STATUS_HW_FAILURE; - - dmub->inbox1_rb.rptr = rptr; - + dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); if (dmub_rb_empty(&dmub->inbox1_rb)) return DMUB_STATUS_OK; @@ -841,46 +816,3 @@ bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_ dmub->hw_funcs.get_diagnostic_data(dmub, diag_data); return true; } - -bool dmub_srv_should_detect(struct dmub_srv *dmub) -{ - if (!dmub->hw_init || !dmub->hw_funcs.should_detect) - return false; - - return dmub->hw_funcs.should_detect(dmub); -} - -enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub) -{ - if (!dmub->hw_init || !dmub->hw_funcs.clear_inbox0_ack_register) - return DMUB_STATUS_INVALID; - - dmub->hw_funcs.clear_inbox0_ack_register(dmub); - return DMUB_STATUS_OK; -} - -enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us) -{ - uint32_t i = 0; - uint32_t ack = 0; - - if (!dmub->hw_init || !dmub->hw_funcs.read_inbox0_ack_register) - return DMUB_STATUS_INVALID; - - for (i = 0; i <= timeout_us; i++) { - ack = dmub->hw_funcs.read_inbox0_ack_register(dmub); - if (ack) - return DMUB_STATUS_OK; - } - return DMUB_STATUS_TIMEOUT; -} - -enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, - union dmub_inbox0_data_register data) -{ - if (!dmub->hw_init || !dmub->hw_funcs.send_inbox0_cmd) - return DMUB_STATUS_INVALID; - - dmub->hw_funcs.send_inbox0_cmd(dmub, data); - return DMUB_STATUS_OK; -} diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c index 44502ec919..70766d534c 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv_stat.c @@ -76,22 +76,6 @@ enum dmub_status dmub_srv_stat_get_notification(struct dmub_srv *dmub, dmub_memcpy((void *)¬ify->aux_reply, (void *)&cmd.dp_aux_reply.reply_data, sizeof(struct aux_reply_data)); break; - case DMUB_OUT_CMD__DP_HPD_NOTIFY: - if (cmd.dp_hpd_notify.hpd_data.hpd_type == DP_HPD) { - notify->type = DMUB_NOTIFICATION_HPD; - notify->hpd_status = cmd.dp_hpd_notify.hpd_data.hpd_status; - } else { - notify->type = DMUB_NOTIFICATION_HPD_IRQ; - } - - notify->link_index = cmd.dp_hpd_notify.hpd_data.instance; - notify->result = AUX_RET_SUCCESS; - break; - case DMUB_OUT_CMD__SET_CONFIG_REPLY: - notify->type = DMUB_NOTIFICATION_SET_CONFIG_REPLY; - notify->link_index = cmd.set_config_reply.set_config_reply_control.instance; - notify->sc_status = cmd.set_config_reply.set_config_reply_control.status; - break; default: notify->type = DMUB_NOTIFICATION_NO_DATA; break; diff --git a/drivers/gpu/drm/amd/display/include/bios_parser_types.h b/drivers/gpu/drm/amd/display/include/bios_parser_types.h index b8ffb216eb..76a87b6828 100644 --- a/drivers/gpu/drm/amd/display/include/bios_parser_types.h +++ b/drivers/gpu/drm/amd/display/include/bios_parser_types.h @@ -152,10 +152,6 @@ struct bp_transmitter_control { enum signal_type signal; enum dc_color_depth color_depth; /* not used for DCE6.0 */ enum hpd_source_id hpd_sel; /* ucHPDSel, used for DCe6.0 */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - enum tx_ffe_id txffe_sel; /* used for DCN3 */ - enum engine_id hpo_engine_id; /* used for DCN3 */ -#endif struct graphics_object_id connector_obj_id; /* symClock; in 10kHz, pixel clock, in HDMI deep color mode, it should * be pixel clock * deep_color_ratio (in KHz) @@ -323,10 +319,6 @@ struct bp_encoder_cap_info { uint32_t DP_HBR2_EN:1; uint32_t DP_HBR3_EN:1; uint32_t HDMI_6GB_EN:1; - uint32_t IS_DP2_CAPABLE:1; - uint32_t DP_UHBR10_EN:1; - uint32_t DP_UHBR13_5_EN:1; - uint32_t DP_UHBR20_EN:1; uint32_t DP_IS_USB_C:1; uint32_t RESERVED:27; }; diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index e4a2dfacab..3d2f0817e4 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -211,7 +211,6 @@ enum { #ifndef ASICREV_IS_GREEN_SARDINE #define ASICREV_IS_GREEN_SARDINE(eChipRev) ((eChipRev >= GREEN_SARDINE_A0) && (eChipRev < 0xFF)) #endif -#define DEVICE_ID_NV_13FE 0x13FE // CYAN_SKILLFISH #define FAMILY_VGH 144 #define DEVICE_ID_VGH_163F 0x163F #define VANGOGH_A0 0x01 diff --git a/drivers/gpu/drm/amd/display/include/dal_types.h b/drivers/gpu/drm/amd/display/include/dal_types.h index 012b7c6179..fe75ec8348 100644 --- a/drivers/gpu/drm/amd/display/include/dal_types.h +++ b/drivers/gpu/drm/amd/display/include/dal_types.h @@ -50,7 +50,6 @@ enum dce_version { DCN_VERSION_1_0, DCN_VERSION_1_01, DCN_VERSION_2_0, - DCN_VERSION_2_01, DCN_VERSION_2_1, DCN_VERSION_3_0, DCN_VERSION_3_01, diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h index a2b80514d8..4de59b66bb 100644 --- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -35,7 +35,6 @@ #define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C #define DP_BRANCH_DEVICE_ID_006037 0x006037 -#define DP_DEVICE_ID_38EC11 0x38EC11 enum ddc_result { DDC_RESULT_UNKNOWN = 0, DDC_RESULT_SUCESSFULL, @@ -118,7 +117,4 @@ struct av_sync_data { uint8_t aud_del_ins3;/* DPCD 0002Dh */ }; -static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0}; -static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0}; - #endif /* __DAL_DDC_SERVICE_TYPES_H__ */ diff --git a/drivers/gpu/drm/amd/display/include/dpcd_defs.h b/drivers/gpu/drm/amd/display/include/dpcd_defs.h index ffd0df1701..aec7389aff 100644 --- a/drivers/gpu/drm/amd/display/include/dpcd_defs.h +++ b/drivers/gpu/drm/amd/display/include/dpcd_defs.h @@ -80,15 +80,6 @@ enum dpcd_phy_test_patterns { PHY_TEST_PATTERN_CP2520_1, PHY_TEST_PATTERN_CP2520_2, PHY_TEST_PATTERN_CP2520_3, /* same as TPS4 */ - PHY_TEST_PATTERN_128b_132b_TPS1 = 0x8, - PHY_TEST_PATTERN_128b_132b_TPS2 = 0x10, - PHY_TEST_PATTERN_PRBS9 = 0x18, - PHY_TEST_PATTERN_PRBS11 = 0x20, - PHY_TEST_PATTERN_PRBS15 = 0x28, - PHY_TEST_PATTERN_PRBS23 = 0x30, - PHY_TEST_PATTERN_PRBS31 = 0x38, - PHY_TEST_PATTERN_264BIT_CUSTOM = 0x40, - PHY_TEST_PATTERN_SQUARE_PULSE = 0x48, }; enum dpcd_test_dyn_range { @@ -144,14 +135,7 @@ enum dpcd_training_patterns { DPCD_TRAINING_PATTERN_1, DPCD_TRAINING_PATTERN_2, DPCD_TRAINING_PATTERN_3, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DPCD_TRAINING_PATTERN_4 = 7, - DPCD_128b_132b_TPS1 = 1, - DPCD_128b_132b_TPS2 = 2, - DPCD_128b_132b_TPS2_CDS = 3, -#else DPCD_TRAINING_PATTERN_4 = 7 -#endif }; /* This enum is for use with PsrSinkPsrStatus.bits.sinkSelfRefreshStatus @@ -165,7 +149,6 @@ enum dpcd_psr_sink_states { PSR_SINK_STATE_SINK_INTERNAL_ERROR = 7, }; -#define DP_SOURCE_SEQUENCE 0x30c #define DP_SOURCE_TABLE_REVISION 0x310 #define DP_SOURCE_PAYLOAD_SIZE 0x311 #define DP_SOURCE_SINK_CAP 0x317 diff --git a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h index dd974c428d..792652236c 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_ctrl_defs.h @@ -328,7 +328,6 @@ struct integrated_info { uint8_t gu_id[NUMBER_OF_UCHAR_FOR_GUID]; uint8_t checksum; - uint8_t fixdpvoltageswing; } ext_disp_conn_info; /* exiting long long time */ struct available_s_clk_list { diff --git a/drivers/gpu/drm/amd/display/include/grph_object_defs.h b/drivers/gpu/drm/amd/display/include/grph_object_defs.h index 84b299ff50..58bb42ed85 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_defs.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_defs.h @@ -140,18 +140,6 @@ enum sync_source { SYNC_SOURCE_DUAL_GPU_PIN }; -#if defined(CONFIG_DRM_AMD_DC_DCN) -enum tx_ffe_id { - TX_FFE0 = 0, - TX_FFE1, - TX_FFE2, - TX_FFE3, - TX_FFE_DeEmphasis_Only, - TX_FFE_PreShoot_Only, - TX_FFE_No_FFE, -}; -#endif - /* connector sizes in millimeters - from BiosParserTypes.hpp */ #define CONNECTOR_SIZE_DVI 40 #define CONNECTOR_SIZE_VGA 32 diff --git a/drivers/gpu/drm/amd/display/include/grph_object_id.h b/drivers/gpu/drm/amd/display/include/grph_object_id.h index 01775417cf..33b3d755fe 100644 --- a/drivers/gpu/drm/amd/display/include/grph_object_id.h +++ b/drivers/gpu/drm/amd/display/include/grph_object_id.h @@ -184,14 +184,6 @@ enum engine_id { ENGINE_ID_DACA, ENGINE_ID_DACB, ENGINE_ID_VCE, /* wireless display pseudo-encoder */ -#if defined(CONFIG_DRM_AMD_DC_DCN) - ENGINE_ID_HPO_0, - ENGINE_ID_HPO_1, - ENGINE_ID_HPO_DP_0, - ENGINE_ID_HPO_DP_1, - ENGINE_ID_HPO_DP_2, - ENGINE_ID_HPO_DP_3, -#endif ENGINE_ID_VIRTUAL, ENGINE_ID_COUNT, diff --git a/drivers/gpu/drm/amd/display/include/i2caux_interface.h b/drivers/gpu/drm/amd/display/include/i2caux_interface.h index 418fbf8c5c..c7fbb9c3ad 100644 --- a/drivers/gpu/drm/amd/display/include/i2caux_interface.h +++ b/drivers/gpu/drm/amd/display/include/i2caux_interface.h @@ -41,8 +41,6 @@ struct aux_payload { * reset it to read data */ bool write; bool mot; - bool write_status_update; - uint32_t address; uint32_t length; uint8_t *data; @@ -55,7 +53,6 @@ struct aux_payload { * zero means "use default value" */ uint32_t defer_delay; - }; struct aux_command { diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 424bccd364..32f5274ed3 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -53,11 +53,7 @@ enum edp_revision { }; enum { - LINK_RATE_REF_FREQ_IN_KHZ = 27000, /*27MHz*/ - BITS_PER_DP_BYTE = 10, - DATA_EFFICIENCY_8b_10b_x10000 = 8000, /* 80% data efficiency */ - DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100 = 97, /* 97% data efficiency when FEC is enabled */ - DATA_EFFICIENCY_128b_132b_x10000 = 9646, /* 96.71% data efficiency x 99.75% downspread factor */ + LINK_RATE_REF_FREQ_IN_KHZ = 27000 /*27MHz*/ }; enum link_training_result { @@ -74,12 +70,6 @@ enum link_training_result { LINK_TRAINING_LINK_LOSS, /* Abort link training (because sink unplugged) */ LINK_TRAINING_ABORT, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DP_128b_132b_LT_FAILED, - DP_128b_132b_MAX_LOOP_COUNT_REACHED, - DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT, - DP_128b_132b_CDS_DONE_TIMEOUT, -#endif }; enum lttpr_mode { @@ -90,58 +80,21 @@ enum lttpr_mode { struct link_training_settings { struct dc_link_settings link_settings; - - /* TODO: turn lane settings below into mandatory fields - * as initial lane configuration - */ struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]; + enum dc_voltage_swing *voltage_swing; enum dc_pre_emphasis *pre_emphasis; enum dc_post_cursor2 *post_cursor2; bool should_set_fec_ready; -#if defined(CONFIG_DRM_AMD_DC_DCN) - /* TODO - factor lane_settings out because it changes during LT */ - union dc_dp_ffe_preset *ffe_preset; -#endif uint16_t cr_pattern_time; uint16_t eq_pattern_time; - uint16_t cds_pattern_time; enum dc_dp_training_pattern pattern_for_cr; enum dc_dp_training_pattern pattern_for_eq; -#if defined(CONFIG_DRM_AMD_DC_DCN) - enum dc_dp_training_pattern pattern_for_cds; - - uint32_t eq_wait_time_limit; - uint8_t eq_loop_count_limit; - uint32_t cds_wait_time_limit; -#endif bool enhanced_framing; + bool allow_invalid_msa_timing_param; enum lttpr_mode lttpr_mode; - - /* disallow different lanes to have different lane settings */ - bool disallow_per_lane_settings; - /* dpcd lane settings will always use the same hw lane settings - * even if it doesn't match requested lane adjust */ - bool always_match_dpcd_with_hw_lane_settings; - - /***************************************************************** - * training states - parameters that can change in link training - *****************************************************************/ - /* TODO: Move hw_lane_settings and dpcd_lane_settings - * along with lane adjust, lane align, offset and all - * other training states into a new structure called - * training states, so link_training_settings becomes - * a constant input pre-decided prior to link training. - * - * The goal is to strictly decouple link training settings - * decision making process from link training states to - * prevent it from messy code practice of changing training - * decision on the fly. - */ - struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX]; - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]; }; /*TODO: Move this enum test harness*/ @@ -161,30 +114,13 @@ enum dp_test_pattern { DP_TEST_PATTERN_CP2520_2, DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE = DP_TEST_PATTERN_CP2520_2, DP_TEST_PATTERN_CP2520_3, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DP_TEST_PATTERN_128b_132b_TPS1, - DP_TEST_PATTERN_128b_132b_TPS2, - DP_TEST_PATTERN_PRBS9, - DP_TEST_PATTERN_PRBS11, - DP_TEST_PATTERN_PRBS15, - DP_TEST_PATTERN_PRBS23, - DP_TEST_PATTERN_PRBS31, - DP_TEST_PATTERN_264BIT_CUSTOM, - DP_TEST_PATTERN_SQUARE_PULSE, -#endif /* Link Training Patterns */ DP_TEST_PATTERN_TRAINING_PATTERN1, DP_TEST_PATTERN_TRAINING_PATTERN2, DP_TEST_PATTERN_TRAINING_PATTERN3, DP_TEST_PATTERN_TRAINING_PATTERN4, -#if defined(CONFIG_DRM_AMD_DC_DCN) - DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE, - DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE, - DP_TEST_PATTERN_PHY_PATTERN_END = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE, -#else DP_TEST_PATTERN_PHY_PATTERN_END = DP_TEST_PATTERN_TRAINING_PATTERN4, -#endif /* link test patterns*/ DP_TEST_PATTERN_COLOR_SQUARES, @@ -216,22 +152,6 @@ enum dp_panel_mode { DP_PANEL_MODE_SPECIAL }; -enum dpcd_source_sequence { - DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG = 1, /*done in apply_single_controller_ctx_to_hw */ - DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR, /*done in core_link_enable_stream */ - DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME, /*done in core_link_enable_stream/dcn20_enable_stream */ - DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE, /*done in perform_link_training_with_retries/dcn20_enable_stream */ - DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY, /*done in dp_enable_link_phy */ - DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN, /*done in dp_set_hw_test_pattern */ - DPCD_SOURCE_SEQ_AFTER_ENABLE_AUDIO_STREAM, /*done in dce110_enable_audio_stream */ - DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM, /*done in enc1_stream_encoder_dp_unblank */ - DPCD_SOURCE_SEQ_AFTER_DISABLE_DP_VID_STREAM, /*done in enc1_stream_encoder_dp_blank */ - DPCD_SOURCE_SEQ_AFTER_FIFO_STEER_RESET, /*done in enc1_stream_encoder_dp_blank */ - DPCD_SOURCE_SEQ_AFTER_DISABLE_AUDIO_STREAM, /*done in dce110_disable_audio_stream */ - DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY, /*done in dp_disable_link_phy */ - DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE, /*done in dce110_disable_stream */ -}; - /* DPCD_ADDR_TRAINING_LANEx_SET registers value */ union dpcd_training_lane_set { struct { diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h index f093b49c5e..a3a9ea077f 100644 --- a/drivers/gpu/drm/amd/display/include/logger_types.h +++ b/drivers/gpu/drm/amd/display/include/logger_types.h @@ -72,7 +72,9 @@ #define DC_LOG_DSC(...) DRM_DEBUG_KMS(__VA_ARGS__) #define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__) #define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__) +#if defined(CONFIG_DRM_AMD_DC_DCN) #define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__) +#endif struct dal_logger; @@ -124,7 +126,6 @@ enum dc_log_type { LOG_MAX_HW_POINTS, LOG_ALL_TF_CHANNELS, LOG_SAMPLE_1DLUT, - LOG_DP2, LOG_SECTION_TOTAL_COUNT }; diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index 64a38f08f4..ef742d95ef 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -54,17 +54,12 @@ static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2]; * just multiply with 2^gamma which can be computed once, and save the result so we * recursively compute all the values. */ - -/* - * Regamma coefficients are used for both regamma and degamma. Degamma - * coefficients are calculated in our formula using the regamma coefficients. - */ - /*sRGB 709 2.2 2.4 P3*/ -static const int32_t numerator01[] = { 31308, 180000, 0, 0, 0}; -static const int32_t numerator02[] = { 12920, 4500, 0, 0, 0}; -static const int32_t numerator03[] = { 55, 99, 0, 0, 0}; -static const int32_t numerator04[] = { 55, 99, 0, 0, 0}; -static const int32_t numerator05[] = { 2400, 2200, 2200, 2400, 2600}; + /*sRGB 709 2.2 2.4 P3*/ +static const int32_t gamma_numerator01[] = { 31308, 180000, 0, 0, 0}; +static const int32_t gamma_numerator02[] = { 12920, 4500, 0, 0, 0}; +static const int32_t gamma_numerator03[] = { 55, 99, 0, 0, 0}; +static const int32_t gamma_numerator04[] = { 55, 99, 0, 0, 0}; +static const int32_t gamma_numerator05[] = { 2400, 2200, 2200, 2400, 2600}; /* one-time setup of X points */ void setup_x_points_distribution(void) @@ -293,8 +288,7 @@ struct dividers { }; -static bool build_coefficients(struct gamma_coefficients *coefficients, - enum dc_transfer_func_predefined type) +static bool build_coefficients(struct gamma_coefficients *coefficients, enum dc_transfer_func_predefined type) { uint32_t i = 0; @@ -318,15 +312,15 @@ static bool build_coefficients(struct gamma_coefficients *coefficients, do { coefficients->a0[i] = dc_fixpt_from_fraction( - numerator01[index], 10000000); + gamma_numerator01[index], 10000000); coefficients->a1[i] = dc_fixpt_from_fraction( - numerator02[index], 1000); + gamma_numerator02[index], 1000); coefficients->a2[i] = dc_fixpt_from_fraction( - numerator03[index], 1000); + gamma_numerator03[index], 1000); coefficients->a3[i] = dc_fixpt_from_fraction( - numerator04[index], 1000); + gamma_numerator04[index], 1000); coefficients->user_gamma[i] = dc_fixpt_from_fraction( - numerator05[index], 1000); + gamma_numerator05[index], 1000); ++i; } while (i != ARRAY_SIZE(coefficients->a0)); @@ -1691,7 +1685,7 @@ static void apply_degamma_for_user_regamma(struct pwl_float_data_ex *rgb_regamma struct pwl_float_data_ex *rgb = rgb_regamma; const struct hw_x_point *coord_x = coordinates_x; - build_coefficients(&coeff, true); + build_coefficients(&coeff, TRANSFER_FUNCTION_SRGB); i = 0; while (i != hw_points_num + 1) { diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index bd1d1dc936..b99aa232bd 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -155,18 +155,9 @@ static unsigned int calc_v_total_from_duration( if (duration_in_us > vrr->max_duration_in_us) duration_in_us = vrr->max_duration_in_us; - if (dc_is_hdmi_signal(stream->signal)) { - uint32_t h_total_up_scaled; - - h_total_up_scaled = stream->timing.h_total * 10000; - v_total = div_u64((unsigned long long)duration_in_us - * stream->timing.pix_clk_100hz + (h_total_up_scaled - 1), - h_total_up_scaled); - } else { - v_total = div64_u64(div64_u64(((unsigned long long)( - duration_in_us) * (stream->timing.pix_clk_100hz / 10)), - stream->timing.h_total), 1000); - } + v_total = div64_u64(div64_u64(((unsigned long long)( + duration_in_us) * (stream->timing.pix_clk_100hz / 10)), + stream->timing.h_total), 1000); /* v_total cannot be less than nominal */ if (v_total < stream->timing.v_total) { diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h index f7420c3f56..f37101f5a7 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_hdcp.h @@ -104,7 +104,6 @@ struct mod_hdcp_displayport { uint8_t rev; uint8_t assr_enabled; uint8_t mst_enabled; - uint8_t usb4_enabled; }; struct mod_hdcp_hdmi { @@ -250,7 +249,6 @@ struct mod_hdcp_link { uint8_t ddc_line; uint8_t link_enc_idx; uint8_t phy_idx; - uint8_t dio_output_id; uint8_t hdcp_supported_informational; union { struct mod_hdcp_displayport dp; diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index f57a1478f0..bd077ea224 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -229,18 +229,15 @@ enum DC_FEATURE_MASK { DC_FBC_MASK = (1 << 0), //0x1, disabled by default DC_MULTI_MON_PP_MCLK_SWITCH_MASK = (1 << 1), //0x2, enabled by default DC_DISABLE_FRACTIONAL_PWM_MASK = (1 << 2), //0x4, disabled by default - DC_PSR_MASK = (1 << 3), //0x8, disabled by default for dcn < 3.1 + DC_PSR_MASK = (1 << 3), //0x8, disabled by default DC_EDP_NO_POWER_SEQUENCING = (1 << 4), //0x10, disabled by default - DC_DISABLE_LTTPR_DP1_4A = (1 << 5), //0x20, disabled by default - DC_DISABLE_LTTPR_DP2_0 = (1 << 6), //0x40, disabled by default }; enum DC_DEBUG_MASK { DC_DISABLE_PIPE_SPLIT = 0x1, DC_DISABLE_STUTTER = 0x2, DC_DISABLE_DSC = 0x4, - DC_DISABLE_CLOCK_GATING = 0x8, - DC_DISABLE_PSR = 0x10, + DC_DISABLE_CLOCK_GATING = 0x8 }; enum amd_dpm_forced_level; diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_offset.h index f268d33c47..312c50ea30 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_offset.h @@ -436,8 +436,6 @@ #define regPHYESYMCLK_CLOCK_CNTL_BASE_IDX 2 #define regDCCG_GATE_DISABLE_CNTL3 0x005a #define regDCCG_GATE_DISABLE_CNTL3_BASE_IDX 2 -#define regHDMISTREAMCLK0_DTO_PARAM 0x005b -#define regHDMISTREAMCLK0_DTO_PARAM_BASE_IDX 2 #define regDCCG_AUDIO_DTBCLK_DTO_PHASE 0x0061 #define regDCCG_AUDIO_DTBCLK_DTO_PHASE_BASE_IDX 2 #define regDCCG_AUDIO_DTBCLK_DTO_MODULO 0x0062 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_sh_mask.h index 1f21f313bd..a9d553ef26 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_3_1_2_sh_mask.h @@ -1438,14 +1438,6 @@ #define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_LE0_GATE_DISABLE_MASK 0x00200000L #define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_ROOT_LE1_GATE_DISABLE_MASK 0x00400000L #define DCCG_GATE_DISABLE_CNTL3__SYMCLK32_LE1_GATE_DISABLE_MASK 0x00800000L -//HDMISTREAMCLK0_DTO_PARAM -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_PHASE__SHIFT 0x0 -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_MODULO__SHIFT 0x8 -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_EN__SHIFT 0x10 -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_PHASE_MASK 0x000000FFL -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_MODULO_MASK 0x0000FF00L -#define HDMISTREAMCLK0_DTO_PARAM__HDMISTREAMCLK0_DTO_EN_MASK 0x00010000L - //DCCG_AUDIO_DTBCLK_DTO_PHASE #define DCCG_AUDIO_DTBCLK_DTO_PHASE__DCCG_AUDIO_DTBCLK_DTO_PHASE__SHIFT 0x0 #define DCCG_AUDIO_DTBCLK_DTO_PHASE__DCCG_AUDIO_DTBCLK_DTO_PHASE_MASK 0xFFFFFFFFL diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h index b4b2584bbd..bd37aa6b65 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h @@ -77,9 +77,4 @@ #define smnDF_CS_UMC_AON0_DramBaseAddress0 0x1c110UL #define smnDF_CS_UMC_AON0_DramLimitAddress0 0x1c114UL -#define mmDF_CS_UMC_AON0_HardwareAssertMaskLow 0x067e -#define mmDF_CS_UMC_AON0_HardwareAssertMaskLow_BASE_IDX 0 -#define mmDF_NCS_PG0_HardwareAssertMaskHigh 0x067f -#define mmDF_NCS_PG0_HardwareAssertMaskHigh_BASE_IDX 0 - #endif diff --git a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h index f45ec6f97f..f804e13b00 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h @@ -62,136 +62,4 @@ #define DF_CS_UMC_AON0_DramLimitAddress0__AllowReqIO_MASK 0x00000400L #define DF_CS_UMC_AON0_DramLimitAddress0__DramLimitAddr_MASK 0xFFFFF000L -//DF_CS_UMC_AON0_HardwareAssertMaskLow -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk0__SHIFT 0x0 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk1__SHIFT 0x1 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk2__SHIFT 0x2 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk3__SHIFT 0x3 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk4__SHIFT 0x4 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk5__SHIFT 0x5 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk6__SHIFT 0x6 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk7__SHIFT 0x7 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk8__SHIFT 0x8 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk9__SHIFT 0x9 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk10__SHIFT 0xa -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk11__SHIFT 0xb -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk12__SHIFT 0xc -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk13__SHIFT 0xd -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk14__SHIFT 0xe -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk15__SHIFT 0xf -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk16__SHIFT 0x10 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk17__SHIFT 0x11 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk18__SHIFT 0x12 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk19__SHIFT 0x13 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk20__SHIFT 0x14 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk21__SHIFT 0x15 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk22__SHIFT 0x16 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk23__SHIFT 0x17 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk24__SHIFT 0x18 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk25__SHIFT 0x19 -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk26__SHIFT 0x1a -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk27__SHIFT 0x1b -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk28__SHIFT 0x1c -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk29__SHIFT 0x1d -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk30__SHIFT 0x1e -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk31__SHIFT 0x1f -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk0_MASK 0x00000001L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk1_MASK 0x00000002L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk2_MASK 0x00000004L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk3_MASK 0x00000008L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk4_MASK 0x00000010L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk5_MASK 0x00000020L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk6_MASK 0x00000040L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk7_MASK 0x00000080L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk8_MASK 0x00000100L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk9_MASK 0x00000200L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk10_MASK 0x00000400L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk11_MASK 0x00000800L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk12_MASK 0x00001000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk13_MASK 0x00002000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk14_MASK 0x00004000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk15_MASK 0x00008000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk16_MASK 0x00010000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk17_MASK 0x00020000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk18_MASK 0x00040000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk19_MASK 0x00080000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk20_MASK 0x00100000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk21_MASK 0x00200000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk22_MASK 0x00400000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk23_MASK 0x00800000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk24_MASK 0x01000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk25_MASK 0x02000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk26_MASK 0x04000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk27_MASK 0x08000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk28_MASK 0x10000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk29_MASK 0x20000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk30_MASK 0x40000000L -#define DF_CS_UMC_AON0_HardwareAssertMaskLow__HWAssertMsk31_MASK 0x80000000L - -//DF_NCS_PG0_HardwareAssertMaskHigh -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk0__SHIFT 0x0 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk1__SHIFT 0x1 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk2__SHIFT 0x2 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk3__SHIFT 0x3 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk4__SHIFT 0x4 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk5__SHIFT 0x5 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk6__SHIFT 0x6 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk7__SHIFT 0x7 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk8__SHIFT 0x8 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk9__SHIFT 0x9 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk10__SHIFT 0xa -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk11__SHIFT 0xb -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk12__SHIFT 0xc -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk13__SHIFT 0xd -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk14__SHIFT 0xe -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk15__SHIFT 0xf -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk16__SHIFT 0x10 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk17__SHIFT 0x11 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk18__SHIFT 0x12 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk19__SHIFT 0x13 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk20__SHIFT 0x14 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk21__SHIFT 0x15 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk22__SHIFT 0x16 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk23__SHIFT 0x17 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk24__SHIFT 0x18 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk25__SHIFT 0x19 -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk26__SHIFT 0x1a -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk27__SHIFT 0x1b -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk28__SHIFT 0x1c -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk29__SHIFT 0x1d -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk30__SHIFT 0x1e -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk31__SHIFT 0x1f -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk0_MASK 0x00000001L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk1_MASK 0x00000002L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk2_MASK 0x00000004L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk3_MASK 0x00000008L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk4_MASK 0x00000010L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk5_MASK 0x00000020L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk6_MASK 0x00000040L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk7_MASK 0x00000080L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk8_MASK 0x00000100L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk9_MASK 0x00000200L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk10_MASK 0x00000400L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk11_MASK 0x00000800L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk12_MASK 0x00001000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk13_MASK 0x00002000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk14_MASK 0x00004000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk15_MASK 0x00008000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk16_MASK 0x00010000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk17_MASK 0x00020000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk18_MASK 0x00040000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk19_MASK 0x00080000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk20_MASK 0x00100000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk21_MASK 0x00200000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk22_MASK 0x00400000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk23_MASK 0x00800000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk24_MASK 0x01000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk25_MASK 0x02000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk26_MASK 0x04000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk27_MASK 0x08000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk28_MASK 0x10000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk29_MASK 0x20000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk30_MASK 0x40000000L -#define DF_NCS_PG0_HardwareAssertMaskHigh__HWAssertMsk31_MASK 0x80000000L - #endif diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_offset.h index da6d380c94..6d0052ce6b 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_offset.h @@ -354,12 +354,5 @@ #define mmMP1_SMN_EXT_SCRATCH7 0x03c7 #define mmMP1_SMN_EXT_SCRATCH7_BASE_IDX 0 -/* - * addressBlock: mp_SmuMp1Pub_MmuDec - * base address: 0x0 - */ -#define smnMP1_PMI_3_START 0x3030204 -#define smnMP1_PMI_3_FIFO 0x3030208 -#define smnMP1_PMI_3 0x3030600 #endif diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_sh_mask.h index a5ae2a8012..136fb5de6a 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_11_0_sh_mask.h @@ -959,17 +959,5 @@ #define MP1_SMN_EXT_SCRATCH7__DATA__SHIFT 0x0 #define MP1_SMN_EXT_SCRATCH7__DATA_MASK 0xFFFFFFFFL -// MP1_PMI_3_START -#define MP1_PMI_3_START__ENABLE_MASK 0x80000000L -// MP1_PMI_3_FIFO -#define MP1_PMI_3_FIFO__DEPTH_MASK 0x00000fffL - -// MP1_PMI_3_START -#define MP1_PMI_3_START__ENABLE__SHIFT 0x0000001f -// MP1_PMI_3_FIFO -#define MP1_PMI_3_FIFO__DEPTH__SHIFT 0x00000000 - - - #endif diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_offset.h index 8072b0a637..79eae0256d 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_offset.h @@ -20753,6 +20753,8 @@ // addressBlock: nbio_nbif0_gdc_GDCDEC // base address: 0xd0000000 +#define regGDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL 0x2ffc0eda +#define regGDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL_BASE_IDX 5 #define regGDC1_NGDC_SDP_PORT_CTRL 0x2ffc0ee2 #define regGDC1_NGDC_SDP_PORT_CTRL_BASE_IDX 5 #define regGDC1_SHUB_REGS_IF_CTL 0x2ffc0ee3 diff --git a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_sh_mask.h index 54b0e46239..e27fdc0c64 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_2_0_sh_mask.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2020 Advanced Micro Devices, Inc. * @@ -108540,6 +108541,17 @@ // addressBlock: nbio_nbif0_gdc_GDCDEC +//GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN0_FAST_WRITE_RESPONSE_EN__SHIFT 0x0 +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN1_FAST_WRITE_RESPONSE_EN__SHIFT 0x1 +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN2_FAST_WRITE_RESPONSE_EN__SHIFT 0x2 +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN3_FAST_WRITE_RESPONSE_EN__SHIFT 0x3 +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__FWR_NORMAL_ARB_MODE__SHIFT 0x10 +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN0_FAST_WRITE_RESPONSE_EN_MASK 0x00000001L +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN1_FAST_WRITE_RESPONSE_EN_MASK 0x00000002L +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN2_FAST_WRITE_RESPONSE_EN_MASK 0x00000004L +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__LOGAN3_FAST_WRITE_RESPONSE_EN_MASK 0x00000008L +#define GDC1_LOGAN_FAST_WRITE_RESPONSE_CNTL__FWR_NORMAL_ARB_MODE_MASK 0x00010000L //GDC1_NGDC_SDP_PORT_CTRL #define GDC1_NGDC_SDP_PORT_CTRL__SDP_DISCON_HYSTERESIS__SHIFT 0x0 #define GDC1_NGDC_SDP_PORT_CTRL__NGDC_OBFF_HW_URGENT_EARLY_WAKEUP_EN__SHIFT 0xf diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h index da895d1f3b..6a505d1b82 100644 --- a/drivers/gpu/drm/amd/include/atombios.h +++ b/drivers/gpu/drm/amd/include/atombios.h @@ -7148,7 +7148,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableFormatRevision )&0x3F) #define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) (((static_cast(TABLE_HEADER_OFFSET))->ucTableContentRevision)&0x3F) #else // not __cplusplus -#define GetIndexIntoMasterTable(MasterOrData, FieldName) (offsetof(ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES, FieldName) / sizeof(USHORT)) +#define GetIndexIntoMasterTable(MasterOrData, FieldName) (((char*)(&((ATOM_MASTER_LIST_OF_##MasterOrData##_TABLES*)0)->FieldName)-(char*)0)/sizeof(USHORT)) #define GET_COMMAND_TABLE_COMMANDSET_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableFormatRevision)&0x3F) #define GET_COMMAND_TABLE_PARAMETER_REVISION(TABLE_HEADER_OFFSET) ((((ATOM_COMMON_TABLE_HEADER*)TABLE_HEADER_OFFSET)->ucTableContentRevision)&0x3F) diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 7bd763361d..44955458fe 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h @@ -768,10 +768,6 @@ enum atom_encoder_caps_def ATOM_ENCODER_CAP_RECORD_HBR2_EN =0x02, // DP1.2 HBR2 setting is qualified and HBR2 can be enabled ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN =0x04, // HDMI2.0 6Gbps enable or not. ATOM_ENCODER_CAP_RECORD_HBR3_EN =0x08, // DP1.3 HBR3 is supported by board. - ATOM_ENCODER_CAP_RECORD_DP2 =0x10, // DP2 is supported by ASIC/board. - ATOM_ENCODER_CAP_RECORD_UHBR10_EN =0x20, // DP2.0 UHBR10 settings is supported by board - ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN =0x40, // DP2.0 UHBR13.5 settings is supported by board - ATOM_ENCODER_CAP_RECORD_UHBR20_EN =0x80, // DP2.0 UHBR20 settings is supported by board ATOM_ENCODER_CAP_RECORD_USB_C_TYPE =0x100, // the DP connector is a USB-C type. }; diff --git a/drivers/gpu/drm/amd/include/cyan_skillfish_ip_offset.h b/drivers/gpu/drm/amd/include/cyan_skillfish_ip_offset.h index ce79e5de8c..9cb5f3631c 100644 --- a/drivers/gpu/drm/amd/include/cyan_skillfish_ip_offset.h +++ b/drivers/gpu/drm/amd/include/cyan_skillfish_ip_offset.h @@ -25,15 +25,15 @@ #define MAX_SEGMENT 5 -struct IP_BASE_INSTANCE +struct IP_BASE_INSTANCE { unsigned int segment[MAX_SEGMENT]; -} __maybe_unused; - -struct IP_BASE +}; + +struct IP_BASE { struct IP_BASE_INSTANCE instance[MAX_INSTANCE]; -} __maybe_unused; +}; static const struct IP_BASE ATHUB_BASE ={ { { { 0x00000C00, 0, 0, 0, 0 } }, diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index ac941f62cb..c84bd7b2cf 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -33,11 +33,12 @@ #include struct pci_dev; -struct amdgpu_device; #define KGD_MAX_QUEUES 128 struct kfd_dev; +struct kgd_dev; + struct kgd_mem; enum kfd_preempt_type { @@ -227,61 +228,61 @@ struct tile_config { */ struct kfd2kgd_calls { /* Register access functions */ - void (*program_sh_mem_settings)(struct amdgpu_device *adev, uint32_t vmid, + void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid, uint32_t sh_mem_config, uint32_t sh_mem_ape1_base, uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases); - int (*set_pasid_vmid_mapping)(struct amdgpu_device *adev, u32 pasid, + int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, u32 pasid, unsigned int vmid); - int (*init_interrupts)(struct amdgpu_device *adev, uint32_t pipe_id); + int (*init_interrupts)(struct kgd_dev *kgd, uint32_t pipe_id); - int (*hqd_load)(struct amdgpu_device *adev, void *mqd, uint32_t pipe_id, + int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t __user *wptr, uint32_t wptr_shift, uint32_t wptr_mask, struct mm_struct *mm); - int (*hiq_mqd_load)(struct amdgpu_device *adev, void *mqd, + int (*hiq_mqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, uint32_t queue_id, uint32_t doorbell_off); - int (*hqd_sdma_load)(struct amdgpu_device *adev, void *mqd, + int (*hqd_sdma_load)(struct kgd_dev *kgd, void *mqd, uint32_t __user *wptr, struct mm_struct *mm); - int (*hqd_dump)(struct amdgpu_device *adev, + int (*hqd_dump)(struct kgd_dev *kgd, uint32_t pipe_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs); - int (*hqd_sdma_dump)(struct amdgpu_device *adev, + int (*hqd_sdma_dump)(struct kgd_dev *kgd, uint32_t engine_id, uint32_t queue_id, uint32_t (**dump)[2], uint32_t *n_regs); - bool (*hqd_is_occupied)(struct amdgpu_device *adev, - uint64_t queue_address, uint32_t pipe_id, - uint32_t queue_id); - - int (*hqd_destroy)(struct amdgpu_device *adev, void *mqd, - uint32_t reset_type, unsigned int timeout, + bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address, uint32_t pipe_id, uint32_t queue_id); - bool (*hqd_sdma_is_occupied)(struct amdgpu_device *adev, void *mqd); + int (*hqd_destroy)(struct kgd_dev *kgd, void *mqd, uint32_t reset_type, + unsigned int timeout, uint32_t pipe_id, + uint32_t queue_id); - int (*hqd_sdma_destroy)(struct amdgpu_device *adev, void *mqd, + bool (*hqd_sdma_is_occupied)(struct kgd_dev *kgd, void *mqd); + + int (*hqd_sdma_destroy)(struct kgd_dev *kgd, void *mqd, unsigned int timeout); - int (*address_watch_disable)(struct amdgpu_device *adev); - int (*address_watch_execute)(struct amdgpu_device *adev, + int (*address_watch_disable)(struct kgd_dev *kgd); + int (*address_watch_execute)(struct kgd_dev *kgd, unsigned int watch_point_id, uint32_t cntl_val, uint32_t addr_hi, uint32_t addr_lo); - int (*wave_control_execute)(struct amdgpu_device *adev, + int (*wave_control_execute)(struct kgd_dev *kgd, uint32_t gfx_index_val, uint32_t sq_cmd); - uint32_t (*address_watch_get_offset)(struct amdgpu_device *adev, + uint32_t (*address_watch_get_offset)(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset); - bool (*get_atc_vmid_pasid_mapping_info)(struct amdgpu_device *adev, + bool (*get_atc_vmid_pasid_mapping_info)( + struct kgd_dev *kgd, uint8_t vmid, uint16_t *p_pasid); @@ -289,16 +290,16 @@ struct kfd2kgd_calls { * passed to the shader by the CP. It's the user mode driver's * responsibility. */ - void (*set_scratch_backing_va)(struct amdgpu_device *adev, + void (*set_scratch_backing_va)(struct kgd_dev *kgd, uint64_t va, uint32_t vmid); - void (*set_vm_context_page_table_base)(struct amdgpu_device *adev, + void (*set_vm_context_page_table_base)(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base); - uint32_t (*read_vmid_from_vmfault_reg)(struct amdgpu_device *adev); + uint32_t (*read_vmid_from_vmfault_reg)(struct kgd_dev *kgd); - void (*get_cu_occupancy)(struct amdgpu_device *adev, int pasid, - int *wave_cnt, int *max_waves_per_cu); - void (*program_trap_handler_settings)(struct amdgpu_device *adev, + void (*get_cu_occupancy)(struct kgd_dev *kgd, int pasid, int *wave_cnt, + int *max_waves_per_cu); + void (*program_trap_handler_settings)(struct kgd_dev *kgd, uint32_t vmid, uint64_t tba_addr, uint64_t tma_addr); }; diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 5c0867ebcf..bac15c4667 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -153,10 +153,6 @@ enum PP_SMC_POWER_PROFILE { PP_SMC_POWER_PROFILE_COUNT, }; -extern const char * const amdgpu_pp_profile_name[PP_SMC_POWER_PROFILE_COUNT]; - - - enum { PP_GROUP_UNKNOWN = 0, PP_GROUP_GFX = 1, diff --git a/drivers/gpu/drm/amd/include/soc15_hw_ip.h b/drivers/gpu/drm/amd/include/soc15_hw_ip.h index c1519d2059..45ca4c921a 100644 --- a/drivers/gpu/drm/amd/include/soc15_hw_ip.h +++ b/drivers/gpu/drm/amd/include/soc15_hw_ip.h @@ -80,8 +80,6 @@ #define L1IMU15_HWID 65 #define WAFLC_HWID 66 #define FCH_USB_PD_HWID 67 -#define SDMA2_HWID 68 -#define SDMA3_HWID 69 #define PCIE_HWID 70 #define PCS_HWID 80 #define DDCL_HWID 89 diff --git a/drivers/gpu/drm/amd/include/yellow_carp_offset.h b/drivers/gpu/drm/amd/include/yellow_carp_offset.h index 28a56b56bc..76b9eb3f44 100644 --- a/drivers/gpu/drm/amd/include/yellow_carp_offset.h +++ b/drivers/gpu/drm/amd/include/yellow_carp_offset.h @@ -9,12 +9,12 @@ struct IP_BASE_INSTANCE { unsigned int segment[MAX_SEGMENT]; -} __maybe_unused; +}; struct IP_BASE { struct IP_BASE_INSTANCE instance[MAX_INSTANCE]; -} __maybe_unused; +}; static const struct IP_BASE ACP_BASE = { { { { 0x02403800, 0x00480000, 0, 0, 0, 0 } }, diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 48cc009d9b..640db5020c 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -82,16 +82,6 @@ static const struct hwmon_temp_label { {PP_TEMP_MEM, "mem"}, }; -const char * const amdgpu_pp_profile_name[] = { - "BOOTUP_DEFAULT", - "3D_FULL_SCREEN", - "POWER_SAVING", - "VIDEO", - "VR", - "COMPUTE", - "CUSTOM" -}; - /** * DOC: power_dpm_state * @@ -320,7 +310,7 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, struct amdgpu_device *adev = drm_to_adev(ddev); const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; enum amd_dpm_forced_level level; - enum amd_dpm_forced_level current_level; + enum amd_dpm_forced_level current_level = 0xff; int ret = 0; if (amdgpu_in_reset(adev)) @@ -360,8 +350,6 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, if (pp_funcs->get_performance_level) current_level = amdgpu_dpm_get_performance_level(adev); - else - current_level = adev->pm.dpm.forced_level; if (current_level == level) { pm_runtime_mark_last_busy(ddev->dev); @@ -2031,15 +2019,15 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RW(pp_dpm_pcie, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RW(pp_sclk_od, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RW(pp_mclk_od, ATTR_FLAG_BASIC), - AMDGPU_DEVICE_ATTR_RW(pp_power_profile_mode, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), + AMDGPU_DEVICE_ATTR_RW(pp_power_profile_mode, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RW(pp_od_clk_voltage, ATTR_FLAG_BASIC), - AMDGPU_DEVICE_ATTR_RO(gpu_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), - AMDGPU_DEVICE_ATTR_RO(mem_busy_percent, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), + AMDGPU_DEVICE_ATTR_RO(gpu_busy_percent, ATTR_FLAG_BASIC), + AMDGPU_DEVICE_ATTR_RO(mem_busy_percent, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(pcie_bw, ATTR_FLAG_BASIC), - AMDGPU_DEVICE_ATTR_RW(pp_features, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), - AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), - AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), - AMDGPU_DEVICE_ATTR_RO(gpu_metrics, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), + AMDGPU_DEVICE_ATTR_RW(pp_features, ATTR_FLAG_BASIC), + AMDGPU_DEVICE_ATTR_RO(unique_id, ATTR_FLAG_BASIC), + AMDGPU_DEVICE_ATTR_RW(thermal_throttling_logging, ATTR_FLAG_BASIC), + AMDGPU_DEVICE_ATTR_RO(gpu_metrics, ATTR_FLAG_BASIC), AMDGPU_DEVICE_ATTR_RO(smartshift_apu_power, ATTR_FLAG_BASIC, .attr_update = ss_power_attr_update), AMDGPU_DEVICE_ATTR_RO(smartshift_dgpu_power, ATTR_FLAG_BASIC, @@ -2090,8 +2078,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ } else if (DEVICE_ATTR_IS(unique_id)) { if (asic_type != CHIP_VEGA10 && asic_type != CHIP_VEGA20 && - asic_type != CHIP_ARCTURUS && - asic_type != CHIP_ALDEBARAN) + asic_type != CHIP_ARCTURUS) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_features)) { if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10) @@ -2100,14 +2087,10 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ if (asic_type < CHIP_VEGA12) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_vclk)) { - if (!(asic_type == CHIP_VANGOGH || asic_type == CHIP_SIENNA_CICHLID)) + if (!(asic_type == CHIP_VANGOGH)) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dclk)) { - if (!(asic_type == CHIP_VANGOGH || asic_type == CHIP_SIENNA_CICHLID)) - *states = ATTR_STATE_UNSUPPORTED; - } else if (DEVICE_ATTR_IS(pp_power_profile_mode)) { - if (!adev->powerplay.pp_funcs->get_power_profile_mode || - amdgpu_dpm_get_power_profile_mode(adev, NULL) == -EOPNOTSUPP) + if (!(asic_type == CHIP_VANGOGH)) *states = ATTR_STATE_UNSUPPORTED; } @@ -3775,7 +3758,5 @@ void amdgpu_debugfs_pm_init(struct amdgpu_device *adev) adev, &amdgpu_debugfs_pm_prv_buffer_fops, adev->pm.smu_prv_buffer_size); - - amdgpu_smu_stb_debug_fs_init(adev); #endif } diff --git a/drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h b/drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h index ab66a4b9e4..35fa0d8e92 100644 --- a/drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/inc/aldebaran_ppsmc.h @@ -102,9 +102,7 @@ #define PPSMC_MSG_GfxDriverResetRecovery 0x42 #define PPSMC_MSG_BoardPowerCalibration 0x43 -#define PPSMC_MSG_HeavySBR 0x45 -#define PPSMC_Message_Count 0x46 - +#define PPSMC_Message_Count 0x44 //PPSMC Reset Types #define PPSMC_RESET_TYPE_WARM_RESET 0x00 diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index c464a04500..16e3f72d31 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -423,9 +423,6 @@ enum ip_power_state { POWER_STATE_OFF, }; -/* Used to mask smu debug modes */ -#define SMU_DEBUG_HALT_ON_ERROR 0x1 - struct amdgpu_pm { struct mutex mutex; u32 current_sclk; @@ -463,11 +460,6 @@ struct amdgpu_pm { struct list_head pm_attr_list; atomic_t pwr_state[AMD_IP_BLOCK_TYPE_NUM]; - - /* - * 0 = disabled (default), otherwise enable corresponding debug mode - */ - uint32_t smu_debug_mask; }; #define R600_SSTU_DFLT 0 diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h index ba7565bc81..8156729c37 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h @@ -324,7 +324,6 @@ enum smu_table_id SMU_TABLE_OVERDRIVE, SMU_TABLE_I2C_COMMANDS, SMU_TABLE_PACE, - SMU_TABLE_ECCINFO, SMU_TABLE_COUNT, }; @@ -341,7 +340,6 @@ struct smu_table_context void *max_sustainable_clocks; struct smu_bios_boot_up_values boot_values; void *driver_pptable; - void *ecc_table; struct smu_table tables[SMU_TABLE_COUNT]; /* * The driver table is just a staging buffer for @@ -474,14 +472,7 @@ struct cmn2asic_mapping { int map_to; }; -struct stb_context { - uint32_t stb_buf_size; - bool enabled; - spinlock_t lock; -}; - #define WORKLOAD_POLICY_MAX 7 - struct smu_context { struct amdgpu_device *adev; @@ -568,8 +559,6 @@ struct smu_context uint16_t cpu_core_num; struct smu_user_dpm_profile user_dpm_profile; - - struct stb_context stb_context; }; struct i2c_adapter; @@ -1019,9 +1008,7 @@ struct pptable_funcs { /** * @set_power_limit: Set power limit in watts. */ - int (*set_power_limit)(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit); + int (*set_power_limit)(struct smu_context *smu, uint32_t n); /** * @init_max_sustainable_clocks: Populate max sustainable clock speed @@ -1257,9 +1244,9 @@ struct pptable_funcs { int (*set_fine_grain_gfx_freq_parameters)(struct smu_context *smu); /** - * @smu_handle_passthrough_sbr: Send message to SMU about special handling for SBR. + * @set_light_sbr: Set light sbr mode for the SMU. */ - int (*smu_handle_passthrough_sbr)(struct smu_context *smu, bool enable); + int (*set_light_sbr)(struct smu_context *smu, bool enable); /** * @wait_for_event: Wait for events from SMU. @@ -1272,17 +1259,6 @@ struct pptable_funcs { * of SMUBUS table. */ int (*send_hbm_bad_pages_num)(struct smu_context *smu, uint32_t size); - - /** - * @get_ecc_table: message SMU to get ECC INFO table. - */ - ssize_t (*get_ecc_info)(struct smu_context *smu, void *table); - - - /** - * @stb_collect_info: Collects Smart Trace Buffers data. - */ - int (*stb_collect_info)(struct smu_context *smu, void *buf, uint32_t size); }; typedef enum { @@ -1415,13 +1391,10 @@ int smu_allow_xgmi_power_down(struct smu_context *smu, bool en); int smu_get_status_gfxoff(struct amdgpu_device *adev, uint32_t *value); -int smu_handle_passthrough_sbr(struct smu_context *smu, bool enable); +int smu_set_light_sbr(struct smu_context *smu, bool enable); int smu_wait_for_event(struct amdgpu_device *adev, enum smu_event_type event, uint64_t event_arg); -int smu_get_ecc_info(struct smu_context *smu, void *umc_ecc); -int smu_stb_collect_info(struct smu_context *smu, void *buff, uint32_t size); -void amdgpu_smu_stb_debug_fs_init(struct amdgpu_device *adev); #endif #endif diff --git a/drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h b/drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h index 0f67c56c28..a017983ff1 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h +++ b/drivers/gpu/drm/amd/pm/inc/smu13_driver_if_aldebaran.h @@ -140,8 +140,6 @@ #define MAX_SW_I2C_COMMANDS 24 -#define ALDEBARAN_UMC_CHANNEL_NUM 32 - typedef enum { I2C_CONTROLLER_PORT_0, //CKSVII2C0 I2C_CONTROLLER_PORT_1, //CKSVII2C1 @@ -509,19 +507,6 @@ typedef struct { uint32_t MmHubPadding[8]; // SMU internal use } AvfsDebugTable_t; -typedef struct { - uint64_t mca_umc_status; - uint64_t mca_umc_addr; - uint16_t ce_count_lo_chip; - uint16_t ce_count_hi_chip; - - uint32_t eccPadding; -} EccInfo_t; - -typedef struct { - EccInfo_t EccInfo[ALDEBARAN_UMC_CHANNEL_NUM]; -} EccInfoTable_t; - // These defines are used with the following messages: // SMC_MSG_TransferTableDram2Smu // SMC_MSG_TransferTableSmu2Dram @@ -532,7 +517,6 @@ typedef struct { #define TABLE_SMU_METRICS 4 #define TABLE_DRIVER_SMU_CONFIG 5 #define TABLE_I2C_COMMANDS 6 -#define TABLE_ECCINFO 7 -#define TABLE_COUNT 8 +#define TABLE_COUNT 7 #endif diff --git a/drivers/gpu/drm/amd/pm/inc/smu_types.h b/drivers/gpu/drm/amd/pm/inc/smu_types.h index ff8a0bcbd2..18b862a90f 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_types.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_types.h @@ -229,8 +229,7 @@ __SMU_DUMMY_MAP(BoardPowerCalibration), \ __SMU_DUMMY_MAP(RequestGfxclk), \ __SMU_DUMMY_MAP(ForceGfxVid), \ - __SMU_DUMMY_MAP(UnforceGfxVid), \ - __SMU_DUMMY_MAP(HeavySBR), + __SMU_DUMMY_MAP(UnforceGfxVid), #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h index acb3be2920..cbdae8a2c6 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v11_0.h @@ -197,9 +197,7 @@ int smu_v11_0_notify_display_change(struct smu_context *smu); int smu_v11_0_get_current_power_limit(struct smu_context *smu, uint32_t *power_limit); -int smu_v11_0_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit); +int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n); int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu); @@ -312,7 +310,7 @@ int smu_v11_0_deep_sleep_control(struct smu_context *smu, void smu_v11_0_interrupt_work(struct smu_context *smu); -int smu_v11_0_handle_passthrough_sbr(struct smu_context *smu, bool enable); +int smu_v11_0_set_light_sbr(struct smu_context *smu, bool enable); int smu_v11_0_restore_user_od_settings(struct smu_context *smu); diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/inc/smu_v13_0.h index 44af23ae05..dc91eb6087 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v13_0.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v13_0.h @@ -27,9 +27,7 @@ #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04 -#define SMU13_DRIVER_IF_VERSION_ALDE 0x08 - -#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms +#define SMU13_DRIVER_IF_VERSION_ALDE 0x07 /* MP Apertures */ #define MP0_Public 0x03800000 @@ -165,9 +163,7 @@ int smu_v13_0_notify_display_change(struct smu_context *smu); int smu_v13_0_get_current_power_limit(struct smu_context *smu, uint32_t *power_limit); -int smu_v13_0_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit); +int smu_v13_0_set_power_limit(struct smu_context *smu, uint32_t n); int smu_v13_0_init_max_sustainable_clocks(struct smu_context *smu); @@ -218,6 +214,7 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) int smu_v13_0_baco_enter(struct smu_context *smu); int smu_v13_0_baco_exit(struct smu_context *smu); +int smu_v13_0_mode1_reset(struct smu_context *smu); int smu_v13_0_mode2_reset(struct smu_context *smu); int smu_v13_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h b/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h index fc9198846e..1d3447991d 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1_ppsmc.h @@ -51,7 +51,7 @@ #define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default #define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display #define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz -#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Deprecated (Not to be used) +#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Set active work load type #define PPSMC_MSG_ForcePowerDownGfx 0x0B ///< Force power down GFX, i.e. enter GFXOFF #define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload #define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer @@ -63,7 +63,7 @@ #define PPSMC_MSG_SetHardMinSocclkByFreq 0x13 ///< Set hard min for SOC CLK #define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK #define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK) -#define PPSMC_MSG_SPARE 0x16 ///< Spare +#define PPSMC_MSG_SPARE0 0x16 ///< Spared #define PPSMC_MSG_GetGfxclkFrequency 0x17 ///< Get GFX clock frequency #define PPSMC_MSG_GetFclkFrequency 0x18 ///< Get FCLK frequency #define PPSMC_MSG_AllowGfxOff 0x19 ///< Inform PMFW of allowing GFXOFF entry diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index 3ab67b232c..3212150036 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -875,30 +875,34 @@ pp_dpm_get_vce_clock_state(void *handle, unsigned idx) static int pp_get_power_profile_mode(void *handle, char *buf) { struct pp_hwmgr *hwmgr = handle; - int ret; - if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->get_power_profile_mode) - return -EOPNOTSUPP; - if (!buf) + if (!hwmgr || !hwmgr->pm_en || !buf) return -EINVAL; - mutex_lock(&hwmgr->smu_lock); - ret = hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf); - mutex_unlock(&hwmgr->smu_lock); - return ret; + if (hwmgr->hwmgr_func->get_power_profile_mode == NULL) { + pr_info_ratelimited("%s was not implemented.\n", __func__); + return snprintf(buf, PAGE_SIZE, "\n"); + } + + return hwmgr->hwmgr_func->get_power_profile_mode(hwmgr, buf); } static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size) { struct pp_hwmgr *hwmgr = handle; - int ret = -EOPNOTSUPP; + int ret = -EINVAL; - if (!hwmgr || !hwmgr->pm_en || !hwmgr->hwmgr_func->set_power_profile_mode) + if (!hwmgr || !hwmgr->pm_en) return ret; + if (hwmgr->hwmgr_func->set_power_profile_mode == NULL) { + pr_info_ratelimited("%s was not implemented.\n", __func__); + return ret; + } + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { pr_debug("power profile setting is for manual dpm mode only.\n"); - return -EINVAL; + return ret; } mutex_lock(&hwmgr->smu_lock); @@ -1328,12 +1332,7 @@ static int pp_set_powergating_by_smu(void *handle, pp_dpm_powergate_vce(handle, gate); break; case AMD_IP_BLOCK_TYPE_GMC: - /* - * For now, this is only used on PICASSO. - * And only "gate" operation is supported. - */ - if (gate) - pp_dpm_powergate_mmhub(handle); + pp_dpm_powergate_mmhub(handle); break; case AMD_IP_BLOCK_TYPE_GFX: ret = pp_dpm_powergate_gfx(handle, gate); @@ -1556,7 +1555,7 @@ static int pp_set_ppfeature_status(void *handle, uint64_t ppfeature_masks) static int pp_asic_reset_mode_2(void *handle) { struct pp_hwmgr *hwmgr = handle; - int ret = 0; + int ret = 0; if (!hwmgr || !hwmgr->pm_en) return -EINVAL; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h index 2fc1733bcd..b7e2651b57 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h @@ -29,9 +29,9 @@ typedef enum atom_smu9_syspll0_clock_id BIOS_CLKID; #define GetIndexIntoMasterCmdTable(FieldName) \ - (offsetof(struct atom_master_list_of_command_functions_v2_1, FieldName) / sizeof(uint16_t)) + (((char*)(&((struct atom_master_list_of_command_functions_v2_1*)0)->FieldName)-(char*)0)/sizeof(uint16_t)) #define GetIndexIntoMasterDataTable(FieldName) \ - (offsetof(struct atom_master_list_of_data_tables_v2_1, FieldName) / sizeof(uint16_t)) + (((char*)(&((struct atom_master_list_of_data_tables_v2_1*)0)->FieldName)-(char*)0)/sizeof(uint16_t)) #define PP_ATOMFWCTRL_MAX_VOLTAGE_ENTRIES 32 diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 9ddd8491ff..1f406f21b4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1439,6 +1439,13 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) {70, 90, 0, 0,}, {30, 60, 0, 6,}, }; + static const char *profile_name[6] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE"}; static const char *title[6] = {"NUM", "MODE_NAME", "BUSY_SET_POINT", @@ -1456,7 +1463,7 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) for (i = 0; i <= PP_SMC_POWER_PROFILE_COMPUTE; i++) size += sysfs_emit_at(buf, size, "%3d %14s%s: %14d %3d %10d %14d\n", - i, amdgpu_pp_profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", + i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", profile_mode_setting[i][0], profile_mode_setting[i][1], profile_mode_setting[i][2], profile_mode_setting[i][3]); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index cd99db0dc2..611969bf45 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -5498,6 +5498,14 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) uint32_t i, size = 0; uint32_t len; + static const char *profile_name[7] = {"BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; + static const char *title[8] = {"NUM", "MODE_NAME", "SCLK_UP_HYST", @@ -5521,7 +5529,7 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) for (i = 0; i < len; i++) { if (i == hwmgr->power_profile_mode) { size += sysfs_emit_at(buf, size, "%3d %14s %s: %8d %16d %16d %16d %16d %16d\n", - i, amdgpu_pp_profile_name[i], "*", + i, profile_name[i], "*", data->current_profile_setting.sclk_up_hyst, data->current_profile_setting.sclk_down_hyst, data->current_profile_setting.sclk_activity, @@ -5532,12 +5540,12 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) } if (smu7_profiling[i].bupdate_sclk) size += sysfs_emit_at(buf, size, "%3d %16s: %8d %16d %16d ", - i, amdgpu_pp_profile_name[i], smu7_profiling[i].sclk_up_hyst, + i, profile_name[i], smu7_profiling[i].sclk_up_hyst, smu7_profiling[i].sclk_down_hyst, smu7_profiling[i].sclk_activity); else size += sysfs_emit_at(buf, size, "%3d %16s: %8s %16s %16s ", - i, amdgpu_pp_profile_name[i], "-", "-", "-"); + i, profile_name[i], "-", "-", "-"); if (smu7_profiling[i].bupdate_mclk) size += sysfs_emit_at(buf, size, "%16d %16d %16d\n", diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 3f040be0d1..e6336654c5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -5097,6 +5097,13 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) {70, 90, 0, 0,}, {30, 60, 0, 6,}, }; + static const char *profile_name[7] = {"BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; static const char *title[6] = {"NUM", "MODE_NAME", "BUSY_SET_POINT", @@ -5114,12 +5121,11 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) for (i = 0; i < PP_SMC_POWER_PROFILE_CUSTOM; i++) size += sysfs_emit_at(buf, size, "%3d %14s%s: %14d %3d %10d %14d\n", - i, amdgpu_pp_profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", + i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", profile_mode_setting[i][0], profile_mode_setting[i][1], profile_mode_setting[i][2], profile_mode_setting[i][3]); - size += sysfs_emit_at(buf, size, "%3d %14s%s: %14d %3d %10d %14d\n", i, - amdgpu_pp_profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", + profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", data->custom_profile_mode[0], data->custom_profile_mode[1], data->custom_profile_mode[2], data->custom_profile_mode[3]); return size; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 97b3ad3690..85d55ab4e3 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -3980,6 +3980,14 @@ static int vega20_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) DpmActivityMonitorCoeffInt_t activity_monitor; uint32_t i, size = 0; uint16_t workload_type = 0; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; static const char *title[] = { "PROFILE_INDEX(NAME)", "CLOCK_TYPE(NAME)", @@ -4013,7 +4021,7 @@ static int vega20_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) return result); size += sysfs_emit_at(buf, size, "%2d %14s%s:\n", - i, amdgpu_pp_profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " "); size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", " ", diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index d93d28c1af..6dc83cfad9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -277,12 +277,8 @@ static int smu_dpm_set_power_gate(void *handle, struct smu_context *smu = handle; int ret = 0; - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) { - dev_WARN(smu->adev->dev, - "SMU uninitialized but power %s requested for %u!\n", - gate ? "gate" : "ungate", block_type); + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; - } switch (block_type) { /* @@ -459,11 +455,7 @@ static int smu_get_power_num_states(void *handle, bool is_support_sw_smu(struct amdgpu_device *adev) { - /* vega20 is 11.0.2, but it's supported via the powerplay code */ - if (adev->asic_type == CHIP_VEGA20) - return false; - - if (adev->ip_versions[MP1_HWIP][0] >= IP_VERSION(11, 0, 0)) + if (adev->asic_type >= CHIP_ARCTURUS) return true; return false; @@ -583,43 +575,41 @@ static int smu_set_funcs(struct amdgpu_device *adev) if (adev->pm.pp_feature & PP_OVERDRIVE_MASK) smu->od_enabled = true; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: navi10_set_ppt_funcs(smu); break; - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - sienna_cichlid_set_ppt_funcs(smu); - break; - case IP_VERSION(12, 0, 0): - case IP_VERSION(12, 0, 1): - renoir_set_ppt_funcs(smu); - break; - case IP_VERSION(11, 5, 0): - vangogh_set_ppt_funcs(smu); - break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): - yellow_carp_set_ppt_funcs(smu); - break; - case IP_VERSION(11, 0, 8): - cyan_skillfish_set_ppt_funcs(smu); - break; - case IP_VERSION(11, 0, 2): + case CHIP_ARCTURUS: adev->pm.pp_feature &= ~PP_GFXOFF_MASK; arcturus_set_ppt_funcs(smu); /* OD is not supported on Arcturus */ smu->od_enabled =false; break; - case IP_VERSION(13, 0, 2): + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + sienna_cichlid_set_ppt_funcs(smu); + break; + case CHIP_ALDEBARAN: aldebaran_set_ppt_funcs(smu); /* Enable pp_od_clk_voltage node */ smu->od_enabled = true; break; + case CHIP_RENOIR: + renoir_set_ppt_funcs(smu); + break; + case CHIP_VANGOGH: + vangogh_set_ppt_funcs(smu); + break; + case CHIP_YELLOW_CARP: + yellow_carp_set_ppt_funcs(smu); + break; + case CHIP_CYAN_SKILLFISH: + cyan_skillfish_set_ppt_funcs(smu); + break; default: return -EINVAL; } @@ -704,8 +694,7 @@ static int smu_late_init(void *handle) return ret; } - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 1)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 3))) + if (adev->asic_type == CHIP_YELLOW_CARP) return 0; if (!amdgpu_sriov_vf(adev) || smu->od_enabled) { @@ -1151,18 +1140,9 @@ static int smu_smc_hw_setup(struct smu_context *smu) if (adev->in_suspend && smu_is_dpm_running(smu)) { dev_info(adev->dev, "dpm has been enabled\n"); /* this is needed specifically */ - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 5, 0): - case IP_VERSION(11, 0, 12): + if ((adev->asic_type >= CHIP_SIENNA_CICHLID) && + (adev->asic_type <= CHIP_DIMGREY_CAVEFISH)) ret = smu_system_features_control(smu, true); - if (ret) - dev_err(adev->dev, "Failed system features control!\n"); - break; - default: - break; - } return ret; } @@ -1283,10 +1263,8 @@ static int smu_smc_hw_setup(struct smu_context *smu) } ret = smu_notify_display_change(smu); - if (ret) { - dev_err(adev->dev, "Failed to notify display change!\n"); + if (ret) return ret; - } /* * Set min deep sleep dce fclk with bootup value from vbios via @@ -1294,6 +1272,8 @@ static int smu_smc_hw_setup(struct smu_context *smu) */ ret = smu_set_min_dcef_deep_sleep(smu, smu->smu_table.boot_values.dcefclk / 100); + if (ret) + return ret; return ret; } @@ -1304,7 +1284,7 @@ static int smu_start_smc_engine(struct smu_context *smu) int ret = 0; if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { - if (adev->ip_versions[MP1_HWIP][0] < IP_VERSION(11, 0, 0)) { + if (adev->asic_type < CHIP_NAVI10) { if (smu->ppt_funcs->load_microcode) { ret = smu->ppt_funcs->load_microcode(smu); if (ret) @@ -1350,6 +1330,7 @@ static int smu_hw_init(void *handle) } if (smu->is_apu) { + smu_powergate_sdma(&adev->smu, false); smu_dpm_set_vcn_enable(smu, true); smu_dpm_set_jpeg_enable(smu, true); smu_set_gfx_cgpg(&adev->smu, true); @@ -1427,41 +1408,23 @@ static int smu_disable_dpms(struct smu_context *smu) * - SMU firmware can handle the DPM reenablement * properly. */ - if (smu->uploading_custom_pp_table) { - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 5, 0): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - return smu_disable_all_features_with_exception(smu, - true, - SMU_FEATURE_COUNT); - default: - break; - } - } + if (smu->uploading_custom_pp_table && + (adev->asic_type >= CHIP_NAVI10) && + (adev->asic_type <= CHIP_BEIGE_GOBY)) + return smu_disable_all_features_with_exception(smu, + true, + SMU_FEATURE_COUNT); /* * For Sienna_Cichlid, PMFW will handle the features disablement properly * on BACO in. Driver involvement is unnecessary. */ - if (use_baco) { - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - return smu_disable_all_features_with_exception(smu, - true, - SMU_FEATURE_BACO_BIT); - default: - break; - } - } + if (((adev->asic_type == CHIP_SIENNA_CICHLID) || + ((adev->asic_type >= CHIP_NAVI10) && (adev->asic_type <= CHIP_NAVI12))) && + use_baco) + return smu_disable_all_features_with_exception(smu, + true, + SMU_FEATURE_BACO_BIT); /* * For gpu reset, runpm and hibernation through BACO, @@ -1479,7 +1442,7 @@ static int smu_disable_dpms(struct smu_context *smu) dev_err(adev->dev, "Failed to disable smu features.\n"); } - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2) && + if (adev->asic_type >= CHIP_NAVI10 && adev->gfx.rlc.funcs->stop) adev->gfx.rlc.funcs->stop(adev); @@ -1517,6 +1480,10 @@ static int smu_hw_fini(void *handle) if (amdgpu_sriov_vf(adev)&& !amdgpu_sriov_is_pp_one_vf(adev)) return 0; + if (smu->is_apu) { + smu_powergate_sdma(&adev->smu, true); + } + smu_dpm_set_vcn_enable(smu, false); smu_dpm_set_jpeg_enable(smu, false); @@ -2265,7 +2232,6 @@ int smu_get_power_limit(void *handle, enum pp_power_type pp_power_type) { struct smu_context *smu = handle; - struct amdgpu_device *adev = smu->adev; enum smu_ppt_limit_level limit_level; uint32_t limit_type; int ret = 0; @@ -2309,20 +2275,15 @@ int smu_get_power_limit(void *handle, } else { switch (limit_level) { case SMU_PPT_LIMIT_CURRENT: - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 2): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): + if ((smu->adev->asic_type == CHIP_ALDEBARAN) || + (smu->adev->asic_type == CHIP_SIENNA_CICHLID) || + (smu->adev->asic_type == CHIP_NAVY_FLOUNDER) || + (smu->adev->asic_type == CHIP_DIMGREY_CAVEFISH) || + (smu->adev->asic_type == CHIP_BEIGE_GOBY)) ret = smu_get_asic_power_limits(smu, &smu->current_power_limit, NULL, NULL); - break; - default: - break; - } *limit = smu->current_power_limit; break; case SMU_PPT_LIMIT_DEFAULT: @@ -2352,10 +2313,9 @@ static int smu_set_power_limit(void *handle, uint32_t limit) mutex_lock(&smu->mutex); - limit &= (1<<24)-1; if (limit_type != SMU_DEFAULT_PPT_LIMIT) if (smu->ppt_funcs->set_power_limit) { - ret = smu->ppt_funcs->set_power_limit(smu, limit_type, limit); + ret = smu->ppt_funcs->set_power_limit(smu, limit); goto out; } @@ -2371,7 +2331,7 @@ static int smu_set_power_limit(void *handle, uint32_t limit) limit = smu->current_power_limit; if (smu->ppt_funcs->set_power_limit) { - ret = smu->ppt_funcs->set_power_limit(smu, limit_type, limit); + ret = smu->ppt_funcs->set_power_limit(smu, limit); if (!ret && !(smu->user_dpm_profile.flags & SMU_DPM_USER_PROFILE_RESTORE)) smu->user_dpm_profile.power_limit = limit; } @@ -2538,15 +2498,13 @@ static int smu_get_power_profile_mode(void *handle, char *buf) struct smu_context *smu = handle; int ret = 0; - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || - !smu->ppt_funcs->get_power_profile_mode) + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; - if (!buf) - return -EINVAL; mutex_lock(&smu->mutex); - ret = smu->ppt_funcs->get_power_profile_mode(smu, buf); + if (smu->ppt_funcs->get_power_profile_mode) + ret = smu->ppt_funcs->get_power_profile_mode(smu, buf); mutex_unlock(&smu->mutex); @@ -2560,8 +2518,7 @@ static int smu_set_power_profile_mode(void *handle, struct smu_context *smu = handle; int ret = 0; - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled || - !smu->ppt_funcs->set_power_profile_mode) + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; mutex_lock(&smu->mutex); @@ -3064,32 +3021,18 @@ static int smu_gfx_state_change_set(void *handle, return ret; } -int smu_handle_passthrough_sbr(struct smu_context *smu, bool enable) +int smu_set_light_sbr(struct smu_context *smu, bool enable) { int ret = 0; mutex_lock(&smu->mutex); - if (smu->ppt_funcs->smu_handle_passthrough_sbr) - ret = smu->ppt_funcs->smu_handle_passthrough_sbr(smu, enable); + if (smu->ppt_funcs->set_light_sbr) + ret = smu->ppt_funcs->set_light_sbr(smu, enable); mutex_unlock(&smu->mutex); return ret; } -int smu_get_ecc_info(struct smu_context *smu, void *umc_ecc) -{ - int ret = -EOPNOTSUPP; - - mutex_lock(&smu->mutex); - if (smu->ppt_funcs && - smu->ppt_funcs->get_ecc_info) - ret = smu->ppt_funcs->get_ecc_info(smu, umc_ecc); - mutex_unlock(&smu->mutex); - - return ret; - -} - static int smu_get_prv_buffer_details(void *handle, void **addr, size_t *size) { struct smu_context *smu = handle; @@ -3179,107 +3122,3 @@ int smu_wait_for_event(struct amdgpu_device *adev, enum smu_event_type event, return ret; } - -int smu_stb_collect_info(struct smu_context *smu, void *buf, uint32_t size) -{ - - if (!smu->ppt_funcs->stb_collect_info || !smu->stb_context.enabled) - return -EOPNOTSUPP; - - /* Confirm the buffer allocated is of correct size */ - if (size != smu->stb_context.stb_buf_size) - return -EINVAL; - - /* - * No need to lock smu mutex as we access STB directly through MMIO - * and not going through SMU messaging route (for now at least). - * For registers access rely on implementation internal locking. - */ - return smu->ppt_funcs->stb_collect_info(smu, buf, size); -} - -#if defined(CONFIG_DEBUG_FS) - -static int smu_stb_debugfs_open(struct inode *inode, struct file *filp) -{ - struct amdgpu_device *adev = filp->f_inode->i_private; - struct smu_context *smu = &adev->smu; - unsigned char *buf; - int r; - - buf = kvmalloc_array(smu->stb_context.stb_buf_size, sizeof(*buf), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - r = smu_stb_collect_info(smu, buf, smu->stb_context.stb_buf_size); - if (r) - goto out; - - filp->private_data = buf; - - return 0; - -out: - kvfree(buf); - return r; -} - -static ssize_t smu_stb_debugfs_read(struct file *filp, char __user *buf, size_t size, - loff_t *pos) -{ - struct amdgpu_device *adev = filp->f_inode->i_private; - struct smu_context *smu = &adev->smu; - - - if (!filp->private_data) - return -EINVAL; - - return simple_read_from_buffer(buf, - size, - pos, filp->private_data, - smu->stb_context.stb_buf_size); -} - -static int smu_stb_debugfs_release(struct inode *inode, struct file *filp) -{ - kvfree(filp->private_data); - filp->private_data = NULL; - - return 0; -} - -/* - * We have to define not only read method but also - * open and release because .read takes up to PAGE_SIZE - * data each time so and so is invoked multiple times. - * We allocate the STB buffer in .open and release it - * in .release - */ -static const struct file_operations smu_stb_debugfs_fops = { - .owner = THIS_MODULE, - .open = smu_stb_debugfs_open, - .read = smu_stb_debugfs_read, - .release = smu_stb_debugfs_release, - .llseek = default_llseek, -}; - -#endif - -void amdgpu_smu_stb_debug_fs_init(struct amdgpu_device *adev) -{ -#if defined(CONFIG_DEBUG_FS) - - struct smu_context *smu = &adev->smu; - - if (!smu->stb_context.stb_buf_size) - return; - - debugfs_create_file_size("amdgpu_smu_stb_dump", - S_IRUSR, - adev_to_drm(adev)->primary->debugfs_root, - adev, - &smu_stb_debugfs_fops, - smu->stb_context.stb_buf_size); -#endif - -} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 505d2fb94f..082f01893f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -295,6 +295,16 @@ static int arcturus_allocate_dpm_context(struct smu_context *smu) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); + smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state), + GFP_KERNEL); + if (!smu_dpm->dpm_current_power_state) + return -ENOMEM; + + smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state), + GFP_KERNEL); + if (!smu_dpm->dpm_request_power_state) + return -ENOMEM; + return 0; } @@ -426,19 +436,6 @@ static void arcturus_check_bxco_support(struct smu_context *smu) } } -static void arcturus_check_fan_support(struct smu_context *smu) -{ - struct smu_table_context *table_context = &smu->smu_table; - PPTable_t *pptable = table_context->driver_pptable; - - /* No sort of fan control possible if PPTable has it disabled */ - smu->adev->pm.no_fan = - !(pptable->FeaturesToRun[0] & FEATURE_FAN_CONTROL_MASK); - if (smu->adev->pm.no_fan) - dev_info_once(smu->adev->dev, - "PMFW based fan control disabled"); -} - static int arcturus_check_powerplay_table(struct smu_context *smu) { struct smu_table_context *table_context = &smu->smu_table; @@ -446,7 +443,6 @@ static int arcturus_check_powerplay_table(struct smu_context *smu) table_context->power_play_table; arcturus_check_bxco_support(smu); - arcturus_check_fan_support(smu); table_context->thermal_controller_type = powerplay_table->thermal_controller_type; @@ -1379,6 +1375,14 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, char *buf) { DpmActivityMonitorCoeffInt_t activity_monitor; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; static const char *title[] = { "PROFILE_INDEX(NAME)", "CLOCK_TYPE(NAME)", @@ -1435,7 +1439,7 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, } size += sysfs_emit_at(buf, size, "%2d %14s%s\n", - i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); if (smu_version >= 0x360d00) { size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", @@ -2472,7 +2476,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .deep_sleep_control = smu_v11_0_deep_sleep_control, .get_fan_parameters = arcturus_get_fan_parameters, .interrupt_work = smu_v11_0_interrupt_work, - .smu_handle_passthrough_sbr = smu_v11_0_handle_passthrough_sbr, + .set_light_sbr = smu_v11_0_set_light_sbr, .set_mp1_state = smu_cmn_set_mp1_state, }; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index 2238ee19c2..3d4c65bc29 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -47,6 +47,7 @@ /* unit: MHz */ #define CYAN_SKILLFISH_SCLK_MIN 1000 #define CYAN_SKILLFISH_SCLK_MAX 2000 +#define CYAN_SKILLFISH_SCLK_DEFAULT 1800 /* unit: mV */ #define CYAN_SKILLFISH_VDDC_MIN 700 @@ -58,8 +59,6 @@ static struct gfx_user_settings { uint32_t vddc; } cyan_skillfish_user_settings; -static uint32_t cyan_skillfish_sclk_default; - #define FEATURE_MASK(feature) (1ULL << feature) #define SMC_DPM_FEATURE ( \ FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ @@ -309,7 +308,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, { int ret = 0, size = 0; uint32_t cur_value = 0; - int i; smu_cmn_get_sysfs_buf(&buf, &size); @@ -335,6 +333,8 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n", CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX); break; + case SMU_GFXCLK: + case SMU_SCLK: case SMU_FCLK: case SMU_MCLK: case SMU_SOCCLK: @@ -345,25 +345,6 @@ static int cyan_skillfish_print_clk_levels(struct smu_context *smu, return ret; size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value); break; - case SMU_SCLK: - case SMU_GFXCLK: - ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value); - if (ret) - return ret; - if (cur_value == CYAN_SKILLFISH_SCLK_MAX) - i = 2; - else if (cur_value == CYAN_SKILLFISH_SCLK_MIN) - i = 0; - else - i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : cyan_skillfish_sclk_default, - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX, - i == 2 ? "*" : ""); - break; default: dev_warn(smu->adev->dev, "Unsupported clock type\n"); return ret; @@ -384,19 +365,13 @@ static bool cyan_skillfish_is_dpm_running(struct smu_context *smu) return false; ret = smu_cmn_get_enabled_32_bits_mask(smu, feature_mask, 2); + if (ret) return false; feature_enabled = (uint64_t)feature_mask[0] | ((uint64_t)feature_mask[1] << 32); - /* - * cyan_skillfish specific, query default sclk inseted of hard code. - */ - if (!cyan_skillfish_sclk_default) - cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK, - &cyan_skillfish_sclk_default); - return !!(feature_enabled & SMC_DPM_FEATURE); } @@ -469,14 +444,14 @@ static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; } - if (input[1] < CYAN_SKILLFISH_SCLK_MIN || + if (input[1] <= CYAN_SKILLFISH_SCLK_MIN || input[1] > CYAN_SKILLFISH_SCLK_MAX) { dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n", CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX); return -EINVAL; } - if (input[2] < CYAN_SKILLFISH_VDDC_MIN || + if (input[2] <= CYAN_SKILLFISH_VDDC_MIN || input[2] > CYAN_SKILLFISH_VDDC_MAX) { dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n", CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX); @@ -493,7 +468,7 @@ static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu, return -EINVAL; } - cyan_skillfish_user_settings.sclk = cyan_skillfish_sclk_default; + cyan_skillfish_user_settings.sclk = CYAN_SKILLFISH_SCLK_DEFAULT; cyan_skillfish_user_settings.vddc = CYAN_SKILLFISH_VDDC_MAGIC; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 2bb7816b24..dfba0bc732 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -86,21 +86,21 @@ static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 0), MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1), MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1), - MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 0), + MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1), MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), - MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), - MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), + MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 0), + MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 0), MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0), MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0), - MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), + MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0), MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0), MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0), MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable, 0), MSG_MAP(RunBtc, PPSMC_MSG_RunBtc, 0), MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0), - MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 1), - MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 1), - MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 0), + MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0), + MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0), + MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 1), MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq, 0), MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1), MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1), @@ -345,7 +345,7 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, /* DPM UCLK enablement should be skipped for navi10 A0 secure board */ if (!(is_asic_secure(smu) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && + (adev->asic_type == CHIP_NAVI10) && (adev->rev_id == 0)) && (adev->pm.pp_feature & PP_MCLK_DPM_MASK)) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) @@ -354,7 +354,7 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, /* DS SOCCLK enablement should be skipped for navi10 A0 secure board */ if (is_asic_secure(smu) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && + (adev->asic_type == CHIP_NAVI10) && (adev->rev_id == 0)) *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_DS_SOCCLK_BIT); @@ -925,18 +925,18 @@ static int navi1x_get_smu_metrics_data(struct smu_context *smu, return ret; } - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 9): + switch (adev->asic_type) { + case CHIP_NAVI12: if (smu_version > 0x00341C00) ret = navi12_get_smu_metrics_data(smu, member, value); else ret = navi12_get_legacy_smu_metrics_data(smu, member, value); break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): + case CHIP_NAVI10: + case CHIP_NAVI14: default: - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && smu_version > 0x00351F00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && smu_version > 0x002A3B00)) + if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || + ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) ret = navi10_get_smu_metrics_data(smu, member, value); else ret = navi10_get_legacy_smu_metrics_data(smu, member, value); @@ -1512,8 +1512,8 @@ static int navi10_populate_umd_state_clk(struct smu_context *smu) uint32_t sclk_freq; pstate_table->gfxclk_pstate.min = gfx_table->min; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): + switch (adev->asic_type) { + case CHIP_NAVI10: switch (adev->pdev->revision) { case 0xf0: /* XTX */ case 0xc0: @@ -1528,7 +1528,7 @@ static int navi10_populate_umd_state_clk(struct smu_context *smu) break; } break; - case IP_VERSION(11, 0, 5): + case CHIP_NAVI14: switch (adev->pdev->revision) { case 0xc7: /* XT */ case 0xf4: @@ -1551,7 +1551,7 @@ static int navi10_populate_umd_state_clk(struct smu_context *smu) break; } break; - case IP_VERSION(11, 0, 9): + case CHIP_NAVI12: sclk_freq = NAVI12_UMD_PSTATE_PEAK_GFXCLK; break; default: @@ -1713,6 +1713,14 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) DpmActivityMonitorCoeffInt_t activity_monitor; uint32_t i, size = 0; int16_t workload_type = 0; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; static const char *title[] = { "PROFILE_INDEX(NAME)", "CLOCK_TYPE(NAME)", @@ -1751,7 +1759,7 @@ static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) } size += sysfs_emit_at(buf, size, "%2d %14s%s:\n", - i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", " ", @@ -2557,8 +2565,8 @@ static bool navi10_need_umc_cdr_workaround(struct smu_context *smu) if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) return false; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) + if (adev->asic_type == CHIP_NAVI10 || + adev->asic_type == CHIP_NAVI14) return true; return false; @@ -2666,8 +2674,8 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) * - PPSMC_MSG_SetDriverDummyTableDramAddrLow * - PPSMC_MSG_GetUMCFWWA */ - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && (pmfw_version >= 0x2a3500)) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && (pmfw_version >= 0x351D00))) { + if (((adev->asic_type == CHIP_NAVI10) && (pmfw_version >= 0x2a3500)) || + ((adev->asic_type == CHIP_NAVI14) && (pmfw_version >= 0x351D00))) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GET_UMC_FW_WA, 0, @@ -2686,13 +2694,13 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) return 0; if (umc_fw_disable_cdr) { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) + if (adev->asic_type == CHIP_NAVI10) return navi10_umc_hybrid_cdr_workaround(smu); } else { return navi10_set_dummy_pstates_table_location(smu); } } else { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) + if (adev->asic_type == CHIP_NAVI10) return navi10_umc_hybrid_cdr_workaround(smu); } @@ -3146,18 +3154,18 @@ static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, return ret; } - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 9): + switch (adev->asic_type) { + case CHIP_NAVI12: if (smu_version > 0x00341C00) ret = navi12_get_gpu_metrics(smu, table); else ret = navi12_get_legacy_gpu_metrics(smu, table); break; - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): + case CHIP_NAVI10: + case CHIP_NAVI14: default: - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && smu_version > 0x00351F00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && smu_version > 0x002A3B00)) + if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || + ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) ret = navi10_get_gpu_metrics(smu, table); else ret =navi10_get_legacy_gpu_metrics(smu, table); @@ -3175,7 +3183,7 @@ static int navi10_enable_mgpu_fan_boost(struct smu_context *smu) uint32_t param = 0; /* Navi12 does not support this */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 9)) + if (adev->asic_type == CHIP_NAVI12) return 0; /* diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 5488a0edb9..574a9d7f7a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -74,18 +74,15 @@ #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15 #define GET_PPTABLE_MEMBER(field, member) do {\ - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))\ + if (smu->adev->asic_type == CHIP_BEIGE_GOBY)\ (*member) = (smu->smu_table.driver_pptable + offsetof(PPTable_beige_goby_t, field));\ else\ (*member) = (smu->smu_table.driver_pptable + offsetof(PPTable_t, field));\ } while(0) -/* STB FIFO depth is in 64bit units */ -#define SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES 8 - static int get_table_size(struct smu_context *smu) { - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (smu->adev->asic_type == CHIP_BEIGE_GOBY) return sizeof(PPTable_beige_goby_t); else return sizeof(PPTable_t); @@ -301,7 +298,7 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, } if ((adev->pm.pp_feature & PP_GFX_DCS_MASK) && - (adev->ip_versions[MP1_HWIP][0] > IP_VERSION(11, 0, 7)) && + (adev->asic_type > CHIP_SIENNA_CICHLID) && !(adev->flags & AMD_IS_APU)) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DCS_BIT); @@ -529,7 +526,7 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s uint32_t throttler_status = 0; int i; - if ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + if ((smu->adev->asic_type == CHIP_SIENNA_CICHLID) && (smu->smc_fw_version >= 0x3A4300)) { for (i = 0; i < THROTTLER_COUNT; i++) throttler_status |= @@ -550,7 +547,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics); SmuMetrics_V2_t *metrics_v2 = &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics_V2); - bool use_metrics_v2 = ((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + bool use_metrics_v2 = ((smu->adev->asic_type == CHIP_SIENNA_CICHLID) && (smu->smc_fw_version >= 0x3A4300)) ? true : false; uint16_t average_gfx_activity; int ret = 0; @@ -683,8 +680,6 @@ static int sienna_cichlid_allocate_dpm_context(struct smu_context *smu) return 0; } -static void sienna_cichlid_stb_init(struct smu_context *smu); - static int sienna_cichlid_init_smc_tables(struct smu_context *smu) { int ret = 0; @@ -697,8 +692,6 @@ static int sienna_cichlid_init_smc_tables(struct smu_context *smu) if (ret) return ret; - sienna_cichlid_stb_init(smu); - return smu_v11_0_init_smc_tables(smu); } @@ -707,7 +700,7 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu) struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_11_0_dpm_table *dpm_table; struct amdgpu_device *adev = smu->adev; - int i, ret = 0; + int ret = 0; DpmDescriptor_t *table_member; /* socclk dpm table setup */ @@ -783,45 +776,78 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu) dpm_table->max = dpm_table->dpm_levels[0].value; } - /* vclk0/1 dpm table setup */ - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; + /* vclk0 dpm table setup */ + dpm_table = &dpm_context->dpm_tables.vclk_table; + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { + ret = smu_v11_0_set_single_dpm_table(smu, + SMU_VCLK, + dpm_table); + if (ret) + return ret; + dpm_table->is_fine_grained = + !table_member[PPCLK_VCLK_0].SnapToDiscrete; + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100; + dpm_table->dpm_levels[0].enabled = true; + dpm_table->min = dpm_table->dpm_levels[0].value; + dpm_table->max = dpm_table->dpm_levels[0].value; + } - dpm_table = &dpm_context->dpm_tables.vclk_table; + /* vclk1 dpm table setup */ + if (adev->vcn.num_vcn_inst > 1) { + dpm_table = &dpm_context->dpm_tables.vclk1_table; if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { ret = smu_v11_0_set_single_dpm_table(smu, - i ? SMU_VCLK1 : SMU_VCLK, + SMU_VCLK1, dpm_table); if (ret) return ret; dpm_table->is_fine_grained = - !table_member[i ? PPCLK_VCLK_1 : PPCLK_VCLK_0].SnapToDiscrete; + !table_member[PPCLK_VCLK_1].SnapToDiscrete; } else { dpm_table->count = 1; - dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100; + dpm_table->dpm_levels[0].value = + smu->smu_table.boot_values.vclk / 100; dpm_table->dpm_levels[0].enabled = true; dpm_table->min = dpm_table->dpm_levels[0].value; dpm_table->max = dpm_table->dpm_levels[0].value; } } - /* dclk0/1 dpm table setup */ - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - dpm_table = &dpm_context->dpm_tables.dclk_table; + /* dclk0 dpm table setup */ + dpm_table = &dpm_context->dpm_tables.dclk_table; + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { + ret = smu_v11_0_set_single_dpm_table(smu, + SMU_DCLK, + dpm_table); + if (ret) + return ret; + dpm_table->is_fine_grained = + !table_member[PPCLK_DCLK_0].SnapToDiscrete; + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100; + dpm_table->dpm_levels[0].enabled = true; + dpm_table->min = dpm_table->dpm_levels[0].value; + dpm_table->max = dpm_table->dpm_levels[0].value; + } + + /* dclk1 dpm table setup */ + if (adev->vcn.num_vcn_inst > 1) { + dpm_table = &dpm_context->dpm_tables.dclk1_table; if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { ret = smu_v11_0_set_single_dpm_table(smu, - i ? SMU_DCLK1 : SMU_DCLK, + SMU_DCLK1, dpm_table); if (ret) return ret; dpm_table->is_fine_grained = - !table_member[i ? PPCLK_DCLK_1 : PPCLK_DCLK_0].SnapToDiscrete; + !table_member[PPCLK_DCLK_1].SnapToDiscrete; } else { dpm_table->count = 1; - dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100; + dpm_table->dpm_levels[0].value = + smu->smu_table.boot_values.dclk / 100; dpm_table->dpm_levels[0].enabled = true; dpm_table->min = dpm_table->dpm_levels[0].value; dpm_table->max = dpm_table->dpm_levels[0].value; @@ -906,18 +932,32 @@ static int sienna_cichlid_set_default_dpm_table(struct smu_context *smu) static int sienna_cichlid_dpm_set_vcn_enable(struct smu_context *smu, bool enable) { struct amdgpu_device *adev = smu->adev; - int i, ret = 0; + int ret = 0; - for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; + if (enable) { /* vcn dpm on is a prerequisite for vcn power gate messages */ if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { - ret = smu_cmn_send_smc_msg_with_param(smu, enable ? - SMU_MSG_PowerUpVcn : SMU_MSG_PowerDownVcn, - 0x10000 * i, NULL); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 0, NULL); if (ret) return ret; + if (adev->vcn.num_vcn_inst > 1) { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, + 0x10000, NULL); + if (ret) + return ret; + } + } + } else { + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_MM_DPM_PG_BIT)) { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, 0, NULL); + if (ret) + return ret; + if (adev->vcn.num_vcn_inst > 1) { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownVcn, + 0x10000, NULL); + if (ret) + return ret; + } } } @@ -1160,7 +1200,7 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu, * and onwards SMU firmwares. */ smu_cmn_get_smc_version(smu, NULL, &smu_version); - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + if ((adev->asic_type == CHIP_SIENNA_CICHLID) && (smu_version < 0x003a2900)) break; @@ -1208,7 +1248,7 @@ static int sienna_cichlid_force_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t mask) { struct amdgpu_device *adev = smu->adev; - int ret = 0; + int ret = 0, size = 0; uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0; soft_min_level = mask ? (ffs(mask) - 1) : 0; @@ -1253,7 +1293,7 @@ static int sienna_cichlid_force_clk_levels(struct smu_context *smu, if ((clk_type == SMU_GFXCLK) || (clk_type == SMU_SCLK)) amdgpu_gfx_off_ctrl(adev, true); - return 0; + return size; } static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu) @@ -1395,6 +1435,14 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char * &(activity_monitor_external.DpmActivityMonitorCoeffInt); uint32_t i, size = 0; int16_t workload_type = 0; + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; static const char *title[] = { "PROFILE_INDEX(NAME)", "CLOCK_TYPE(NAME)", @@ -1433,7 +1481,7 @@ static int sienna_cichlid_get_power_profile_mode(struct smu_context *smu, char * } size += sysfs_emit_at(buf, size, "%2d %14s%s:\n", - i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", " ", @@ -1935,7 +1983,7 @@ static void sienna_cichlid_dump_od_table(struct smu_context *smu, od_table->UclkFmax); smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (!((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + if (!((adev->asic_type == CHIP_SIENNA_CICHLID) && (smu_version < 0x003a2900))) dev_dbg(smu->adev->dev, "OD: VddGfxOffset: %d\n", od_table->VddGfxOffset); } @@ -2159,7 +2207,7 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu, * and onwards SMU firmwares. */ smu_cmn_get_smc_version(smu, NULL, &smu_version); - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + if ((adev->asic_type == CHIP_SIENNA_CICHLID) && (smu_version < 0x003a2900)) { dev_err(smu->adev->dev, "OD GFX Voltage offset functionality is supported " "only by 58.41.0 and onwards SMU firmwares!\n"); @@ -2180,13 +2228,7 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu, static int sienna_cichlid_run_btc(struct smu_context *smu) { - int res; - - res = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); - if (res) - dev_err(smu->adev->dev, "RunDcBtc failed!\n"); - - return res; + return smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); } static int sienna_cichlid_baco_enter(struct smu_context *smu) @@ -2869,7 +2911,7 @@ static void sienna_cichlid_dump_pptable(struct smu_context *smu) PPTable_t *pptable = table_context->driver_pptable; int i; - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) { + if (smu->adev->asic_type == CHIP_BEIGE_GOBY) { beige_goby_dump_pptable(smu); return; } @@ -3629,7 +3671,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, SmuMetrics_V2_t *metrics_v2 = &(metrics_external.SmuMetrics_V2); struct amdgpu_device *adev = smu->adev; - bool use_metrics_v2 = ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && + bool use_metrics_v2 = ((adev->asic_type == CHIP_SIENNA_CICHLID) && (smu->smc_fw_version >= 0x3A4300)) ? true : false; uint16_t average_gfx_activity; int ret = 0; @@ -3670,16 +3712,6 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->energy_accumulator = use_metrics_v2 ? metrics_v2->EnergyAccumulator : metrics->EnergyAccumulator; - if (metrics->CurrGfxVoltageOffset) - gpu_metrics->voltage_gfx = - (155000 - 625 * metrics->CurrGfxVoltageOffset) / 100; - if (metrics->CurrMemVidOffset) - gpu_metrics->voltage_mem = - (155000 - 625 * metrics->CurrMemVidOffset) / 100; - if (metrics->CurrSocVoltageOffset) - gpu_metrics->voltage_soc = - (155000 - 625 * metrics->CurrSocVoltageOffset) / 100; - average_gfx_activity = use_metrics_v2 ? metrics_v2->AverageGfxActivity : metrics->AverageGfxActivity; if (average_gfx_activity <= SMU_11_0_7_GFX_BUSY_THRESHOLD) gpu_metrics->average_gfxclk_frequency = @@ -3720,8 +3752,8 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = use_metrics_v2 ? metrics_v2->CurrFanSpeed : metrics->CurrFanSpeed; - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && smu->smc_fw_version > 0x003A1E00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 11)) && smu->smc_fw_version > 0x00410400)) { + if (((adev->asic_type == CHIP_SIENNA_CICHLID) && smu->smc_fw_version > 0x003A1E00) || + ((adev->asic_type == CHIP_NAVY_FLOUNDER) && smu->smc_fw_version > 0x00410400)) { gpu_metrics->pcie_link_width = use_metrics_v2 ? metrics_v2->PcieWidth : metrics->PcieWidth; gpu_metrics->pcie_link_speed = link_speed[use_metrics_v2 ? metrics_v2->PcieRate : metrics->PcieRate]; } else { @@ -3854,53 +3886,6 @@ static int sienna_cichlid_set_mp1_state(struct smu_context *smu, return ret; } -static void sienna_cichlid_stb_init(struct smu_context *smu) -{ - struct amdgpu_device *adev = smu->adev; - uint32_t reg; - - reg = RREG32_PCIE(MP1_Public | smnMP1_PMI_3_START); - smu->stb_context.enabled = REG_GET_FIELD(reg, MP1_PMI_3_START, ENABLE); - - /* STB is disabled */ - if (!smu->stb_context.enabled) - return; - - spin_lock_init(&smu->stb_context.lock); - - /* STB buffer size in bytes as function of FIFO depth */ - reg = RREG32_PCIE(MP1_Public | smnMP1_PMI_3_FIFO); - smu->stb_context.stb_buf_size = 1 << REG_GET_FIELD(reg, MP1_PMI_3_FIFO, DEPTH); - smu->stb_context.stb_buf_size *= SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES; - - dev_info(smu->adev->dev, "STB initialized to %d entries", - smu->stb_context.stb_buf_size / SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES); - -} - -int sienna_cichlid_stb_get_data_direct(struct smu_context *smu, - void *buf, - uint32_t size) -{ - uint32_t *p = buf; - struct amdgpu_device *adev = smu->adev; - - /* No need to disable interrupts for now as we don't lock it yet from ISR */ - spin_lock(&smu->stb_context.lock); - - /* - * Read the STB FIFO in units of 32bit since this is the accessor window - * (register width) we have. - */ - buf = ((char *) buf) + size; - while ((void *)p < buf) - *p++ = cpu_to_le32(RREG32_PCIE(MP1_Public | smnMP1_PMI_3)); - - spin_unlock(&smu->stb_context.lock); - - return 0; -} - static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .get_allowed_feature_mask = sienna_cichlid_get_allowed_feature_mask, .set_default_dpm_table = sienna_cichlid_set_default_dpm_table, @@ -3990,7 +3975,6 @@ static const struct pptable_funcs sienna_cichlid_ppt_funcs = { .interrupt_work = smu_v11_0_interrupt_work, .gpo_control = sienna_cichlid_gpo_control, .set_mp1_state = sienna_cichlid_set_mp1_state, - .stb_collect_info = sienna_cichlid_stb_get_data_direct, }; void sienna_cichlid_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index 4e9e2cf398..87b055466a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -90,38 +90,37 @@ int smu_v11_0_init_microcode(struct smu_context *smu) struct amdgpu_firmware_info *ucode = NULL; if (amdgpu_sriov_vf(adev) && - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 9)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)))) + ((adev->asic_type == CHIP_NAVI12) || + (adev->asic_type == CHIP_SIENNA_CICHLID))) return 0; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - chip_name = "navi10"; - break; - case IP_VERSION(11, 0, 5): - chip_name = "navi14"; - break; - case IP_VERSION(11, 0, 9): - chip_name = "navi12"; - break; - case IP_VERSION(11, 0, 7): - chip_name = "sienna_cichlid"; - break; - case IP_VERSION(11, 0, 11): - chip_name = "navy_flounder"; - break; - case IP_VERSION(11, 0, 12): - chip_name = "dimgrey_cavefish"; - break; - case IP_VERSION(11, 0, 13): - chip_name = "beige_goby"; - break; - case IP_VERSION(11, 0, 2): + switch (adev->asic_type) { + case CHIP_ARCTURUS: chip_name = "arcturus"; break; + case CHIP_NAVI10: + chip_name = "navi10"; + break; + case CHIP_NAVI14: + chip_name = "navi14"; + break; + case CHIP_NAVI12: + chip_name = "navi12"; + break; + case CHIP_SIENNA_CICHLID: + chip_name = "sienna_cichlid"; + break; + case CHIP_NAVY_FLOUNDER: + chip_name = "navy_flounder"; + break; + case CHIP_DIMGREY_CAVEFISH: + chip_name = "dimgrey_cavefish"; + break; + case CHIP_BEIGE_GOBY: + chip_name = "beige_goby"; + break; default: - dev_err(adev->dev, "Unsupported IP version 0x%x\n", - adev->ip_versions[MP1_HWIP][0]); + dev_err(adev->dev, "Unsupported ASIC type %d\n", adev->asic_type); return -EINVAL; } @@ -239,40 +238,39 @@ int smu_v11_0_check_fw_version(struct smu_context *smu) if (smu->is_apu) adev->pm.fw_version = smu_version; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV10; - break; - case IP_VERSION(11, 0, 9): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV12; - break; - case IP_VERSION(11, 0, 5): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV14; - break; - case IP_VERSION(11, 0, 7): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Sienna_Cichlid; - break; - case IP_VERSION(11, 0, 11): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Navy_Flounder; - break; - case IP_VERSION(11, 5, 0): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_VANGOGH; - break; - case IP_VERSION(11, 0, 12): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish; - break; - case IP_VERSION(11, 0, 13): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Beige_Goby; - break; - case IP_VERSION(11, 0, 8): - smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Cyan_Skillfish; - break; - case IP_VERSION(11, 0, 2): + switch (smu->adev->asic_type) { + case CHIP_ARCTURUS: smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_ARCT; break; + case CHIP_NAVI10: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV10; + break; + case CHIP_NAVI12: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV12; + break; + case CHIP_NAVI14: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV14; + break; + case CHIP_SIENNA_CICHLID: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Sienna_Cichlid; + break; + case CHIP_NAVY_FLOUNDER: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Navy_Flounder; + break; + case CHIP_VANGOGH: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_VANGOGH; + break; + case CHIP_DIMGREY_CAVEFISH: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Dimgrey_Cavefish; + break; + case CHIP_BEIGE_GOBY: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Beige_Goby; + break; + case CHIP_CYAN_SKILLFISH: + smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_Cyan_Skillfish; + break; default: - dev_err(smu->adev->dev, "smu unsupported IP version: 0x%x.\n", - adev->ip_versions[MP1_HWIP][0]); + dev_err(smu->adev->dev, "smu unsupported asic type:%d.\n", smu->adev->asic_type); smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_INV; break; } @@ -494,9 +492,8 @@ int smu_v11_0_fini_smc_tables(struct smu_context *smu) int smu_v11_0_init_power(struct smu_context *smu) { - struct amdgpu_device *adev = smu->adev; struct smu_power_context *smu_power = &smu->smu_power; - size_t size = adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 5, 0) ? + size_t size = smu->adev->asic_type == CHIP_VANGOGH ? sizeof(struct smu_11_5_power_context) : sizeof(struct smu_11_0_power_context); @@ -753,10 +750,8 @@ int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count) /* Navy_Flounder/Dimgrey_Cavefish do not support to change * display num currently */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 11) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 5, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 12) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (adev->asic_type >= CHIP_NAVY_FLOUNDER && + adev->asic_type <= CHIP_BEIGE_GOBY) return 0; return smu_cmn_send_smc_msg_with_param(smu, @@ -979,16 +974,10 @@ int smu_v11_0_get_current_power_limit(struct smu_context *smu, return ret; } -int smu_v11_0_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit) +int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n) { int power_src; int ret = 0; - uint32_t limit_param; - - if (limit_type != SMU_DEFAULT_PPT_LIMIT) - return -EINVAL; if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { dev_err(smu->adev->dev, "Setting new power limit is not supported!\n"); @@ -1008,16 +997,16 @@ int smu_v11_0_set_power_limit(struct smu_context *smu, * BIT 16-23: PowerSource * BIT 0-15: PowerLimit */ - limit_param = (limit & 0xFFFF); - limit_param |= 0 << 24; - limit_param |= (power_src) << 16; - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit_param, NULL); + n &= 0xFFFF; + n |= 0 << 24; + n |= (power_src) << 16; + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, n, NULL); if (ret) { dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__); return ret; } - smu->current_power_limit = limit; + smu->current_power_limit = n; return 0; } @@ -1147,15 +1136,15 @@ int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) int ret = 0; struct amdgpu_device *adev = smu->adev; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 5): - case IP_VERSION(11, 0, 9): - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): - case IP_VERSION(11, 5, 0): + switch (adev->asic_type) { + case CHIP_NAVI10: + case CHIP_NAVI14: + case CHIP_NAVI12: + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: + case CHIP_VANGOGH: if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) return 0; if (enable) @@ -1641,11 +1630,11 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) mutex_lock(&smu_baco->mutex); if (state == SMU_BACO_STATE_ENTER) { - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(11, 0, 7): - case IP_VERSION(11, 0, 11): - case IP_VERSION(11, 0, 12): - case IP_VERSION(11, 0, 13): + switch (adev->asic_type) { + case CHIP_SIENNA_CICHLID: + case CHIP_NAVY_FLOUNDER: + case CHIP_DIMGREY_CAVEFISH: + case CHIP_BEIGE_GOBY: if (amdgpu_runtime_pm == 2) ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, @@ -1660,7 +1649,7 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) default: if (!ras || !adev->ras_enabled || adev->gmc.xgmi.pending_reset) { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 2)) { + if (adev->asic_type == CHIP_ARCTURUS) { data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL_ARCT); data |= 0x80000000; WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL_ARCT, data); @@ -1724,7 +1713,7 @@ int smu_v11_0_mode1_reset(struct smu_context *smu) return ret; } -int smu_v11_0_handle_passthrough_sbr(struct smu_context *smu, bool enable) +int smu_v11_0_set_light_sbr(struct smu_context *smu, bool enable) { int ret = 0; @@ -1942,7 +1931,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu, * Separate MCLK and SOCCLK soft min/max settings are not allowed * on Arcturus. */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 2)) { + if (adev->asic_type == CHIP_ARCTURUS) { mclk_min = mclk_max = 0; socclk_min = socclk_max = 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 5cb07ed227..a9dceef4a7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -683,7 +683,6 @@ static int vangogh_print_clk_levels(struct smu_context *smu, int i, size = 0, ret = 0; uint32_t cur_value = 0, value = 0, count = 0; bool cur_value_match_level = false; - uint32_t min, max; memset(&metrics, 0, sizeof(metrics)); @@ -744,13 +743,6 @@ static int vangogh_print_clk_levels(struct smu_context *smu, if (ret) return ret; break; - case SMU_GFXCLK: - case SMU_SCLK: - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetGfxclkFrequency, 0, &cur_value); - if (ret) { - return ret; - } - break; default: break; } @@ -776,24 +768,6 @@ static int vangogh_print_clk_levels(struct smu_context *smu, if (!cur_value_match_level) size += sysfs_emit_at(buf, size, " %uMhz *\n", cur_value); break; - case SMU_GFXCLK: - case SMU_SCLK: - min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; - max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; - if (cur_value == max) - i = 2; - else if (cur_value == min) - i = 0; - else - i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, - i == 2 ? "*" : ""); - break; default: break; } @@ -1039,6 +1013,14 @@ static int vangogh_get_dpm_ultimate_freq(struct smu_context *smu, static int vangogh_get_power_profile_mode(struct smu_context *smu, char *buf) { + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; uint32_t i, size = 0; int16_t workload_type = 0; @@ -1058,7 +1040,7 @@ static int vangogh_get_power_profile_mode(struct smu_context *smu, continue; size += sysfs_emit_at(buf, size, "%2d %14s%s\n", - i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); } return size; @@ -2131,12 +2113,11 @@ static int vangogh_get_ppt_limit(struct smu_context *smu, return 0; } -static int vangogh_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t ppt_limit) +static int vangogh_set_power_limit(struct smu_context *smu, uint32_t ppt_limit) { struct smu_11_5_power_context *power_context = - smu->smu_power.power_context; + smu->smu_power.power_context; + uint32_t limit_type = ppt_limit >> 24; int ret = 0; if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 25c4b135f8..145f13b8c9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1095,6 +1095,14 @@ static int renoir_set_watermarks_table( static int renoir_get_power_profile_mode(struct smu_context *smu, char *buf) { + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; uint32_t i, size = 0; int16_t workload_type = 0; @@ -1113,7 +1121,7 @@ static int renoir_get_power_profile_mode(struct smu_context *smu, continue; size += sysfs_emit_at(buf, size, "%2d %14s%s\n", - i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); } return size; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 4885c4ae78..c9cfeb0947 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -78,12 +78,6 @@ #define smnPCIE_ESM_CTRL 0x111003D0 -/* - * SMU support ECCTABLE since version 68.42.0, - * use this to check ECCTALE feature whether support - */ -#define SUPPORT_ECCTABLE_SMU_VERSION 0x00442a00 - static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, @@ -141,7 +135,6 @@ static const struct cmn2asic_msg_mapping aldebaran_message_map[SMU_MSG_MAX_COUNT MSG_MAP(SetUclkDpmMode, PPSMC_MSG_SetUclkDpmMode, 0), MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), MSG_MAP(BoardPowerCalibration, PPSMC_MSG_BoardPowerCalibration, 0), - MSG_MAP(HeavySBR, PPSMC_MSG_HeavySBR, 0), }; static const struct cmn2asic_mapping aldebaran_clk_map[SMU_CLK_COUNT] = { @@ -197,7 +190,6 @@ static const struct cmn2asic_mapping aldebaran_table_map[SMU_TABLE_COUNT] = { TAB_MAP(SMU_METRICS), TAB_MAP(DRIVER_SMU_CONFIG), TAB_MAP(I2C_COMMANDS), - TAB_MAP(ECCINFO), }; static const uint8_t aldebaran_throttler_map[] = { @@ -231,9 +223,6 @@ static int aldebaran_tables_init(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t), - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); if (!smu_table->metrics_table) return -ENOMEM; @@ -246,10 +235,6 @@ static int aldebaran_tables_init(struct smu_context *smu) return -ENOMEM; } - smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL); - if (!smu_table->ecc_table) - return -ENOMEM; - return 0; } @@ -263,6 +248,16 @@ static int aldebaran_allocate_dpm_context(struct smu_context *smu) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context); + smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state), + GFP_KERNEL); + if (!smu_dpm->dpm_current_power_state) + return -ENOMEM; + + smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state), + GFP_KERNEL); + if (!smu_dpm->dpm_request_power_state) + return -ENOMEM; + return 0; } @@ -1246,13 +1241,11 @@ static int aldebaran_get_power_limit(struct smu_context *smu, return 0; } -static int aldebaran_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit) +static int aldebaran_set_power_limit(struct smu_context *smu, uint32_t n) { /* Power limit can be set only through primary die */ if (aldebaran_is_primary(smu)) - return smu_v13_0_set_power_limit(smu, limit_type, limit); + return smu_v13_0_set_power_limit(smu, n); return -EINVAL; } @@ -1606,8 +1599,7 @@ static void aldebaran_get_unique_id(struct smu_context *smu) mutex_unlock(&smu->metrics_lock); adev->unique_id = ((uint64_t)upper32 << 32) | lower32; - if (adev->serial[0] == '\0') - sprintf(adev->serial, "%016llx", adev->unique_id); + sprintf(adev->serial, "%016llx", adev->unique_id); } static bool aldebaran_is_baco_supported(struct smu_context *smu) @@ -1625,18 +1617,10 @@ static int aldebaran_set_df_cstate(struct smu_context *smu, static int aldebaran_allow_xgmi_power_down(struct smu_context *smu, bool en) { - struct amdgpu_device *adev = smu->adev; - - /* The message only works on master die and NACK will be sent - back for other dies, only send it on master die */ - if (!adev->smuio.funcs->get_socket_id(adev) && - !adev->smuio.funcs->get_die_id(adev)) - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GmiPwrDnControl, - en ? 0 : 1, - NULL); - else - return 0; + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GmiPwrDnControl, + en ? 0 : 1, + NULL); } static const struct throttling_logging_label { @@ -1779,98 +1763,6 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, return sizeof(struct gpu_metrics_v1_3); } -static int aldebaran_check_ecc_table_support(struct smu_context *smu) -{ - uint32_t if_version = 0xff, smu_version = 0xff; - int ret = 0; - - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { - /* return not support if failed get smu_version */ - ret = -EOPNOTSUPP; - } - - if (smu_version < SUPPORT_ECCTABLE_SMU_VERSION) - ret = -EOPNOTSUPP; - - return ret; -} - -static ssize_t aldebaran_get_ecc_info(struct smu_context *smu, - void *table) -{ - struct smu_table_context *smu_table = &smu->smu_table; - EccInfoTable_t *ecc_table = NULL; - struct ecc_info_per_ch *ecc_info_per_channel = NULL; - int i, ret = 0; - struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table; - - ret = aldebaran_check_ecc_table_support(smu); - if (ret) - return ret; - - ret = smu_cmn_update_table(smu, - SMU_TABLE_ECCINFO, - 0, - smu_table->ecc_table, - false); - if (ret) { - dev_info(smu->adev->dev, "Failed to export SMU ecc table!\n"); - return ret; - } - - ecc_table = (EccInfoTable_t *)smu_table->ecc_table; - - for (i = 0; i < ALDEBARAN_UMC_CHANNEL_NUM; i++) { - ecc_info_per_channel = &(eccinfo->ecc[i]); - ecc_info_per_channel->ce_count_lo_chip = - ecc_table->EccInfo[i].ce_count_lo_chip; - ecc_info_per_channel->ce_count_hi_chip = - ecc_table->EccInfo[i].ce_count_hi_chip; - ecc_info_per_channel->mca_umc_status = - ecc_table->EccInfo[i].mca_umc_status; - ecc_info_per_channel->mca_umc_addr = - ecc_table->EccInfo[i].mca_umc_addr; - } - - return ret; -} - -static int aldebaran_mode1_reset(struct smu_context *smu) -{ - u32 smu_version, fatal_err, param; - int ret = 0; - struct amdgpu_device *adev = smu->adev; - struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - - fatal_err = 0; - param = SMU_RESET_MODE_1; - - /* - * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07 - */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (smu_version < 0x00440700) { - ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); - } - else { - /* fatal error triggered by ras, PMFW supports the flag - from 68.44.0 */ - if ((smu_version >= 0x00442c00) && ras && - atomic_read(&ras->in_recovery)) - fatal_err = 1; - - param |= (fatal_err << 16); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GfxDeviceDriverReset, param, NULL); - } - - if (!ret) - msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); - - return ret; -} - static int aldebaran_mode2_reset(struct smu_context *smu) { u32 smu_version; @@ -1922,14 +1814,6 @@ static int aldebaran_mode2_reset(struct smu_context *smu) return ret; } -static int aldebaran_smu_handle_passthrough_sbr(struct smu_context *smu, bool enable) -{ - int ret = 0; - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_HeavySBR, enable ? 1 : 0, NULL); - - return ret; -} - static bool aldebaran_is_mode1_reset_supported(struct smu_context *smu) { #if 0 @@ -2039,15 +1923,13 @@ static const struct pptable_funcs aldebaran_ppt_funcs = { .get_gpu_metrics = aldebaran_get_gpu_metrics, .mode1_reset_is_support = aldebaran_is_mode1_reset_supported, .mode2_reset_is_support = aldebaran_is_mode2_reset_supported, - .smu_handle_passthrough_sbr = aldebaran_smu_handle_passthrough_sbr, - .mode1_reset = aldebaran_mode1_reset, + .mode1_reset = smu_v13_0_mode1_reset, .set_mp1_state = aldebaran_set_mp1_state, .mode2_reset = aldebaran_mode2_reset, .wait_for_event = smu_v13_0_wait_for_event, .i2c_init = aldebaran_i2c_control_init, .i2c_fini = aldebaran_i2c_control_fini, .send_hbm_bad_pages_num = aldebaran_smu_send_hbm_bad_page_num, - .get_ecc_info = aldebaran_get_ecc_info, }; void aldebaran_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index b54790d348..8d4aa16b2a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -60,6 +60,8 @@ MODULE_FIRMWARE("amdgpu/aldebaran_smc.bin"); #define SMU13_VOLTAGE_SCALE 4 +#define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms + #define LINK_WIDTH_MAX 6 #define LINK_SPEED_MAX 3 @@ -87,13 +89,12 @@ int smu_v13_0_init_microcode(struct smu_context *smu) if (amdgpu_sriov_vf(adev)) return 0; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 2): + switch (adev->asic_type) { + case CHIP_ALDEBARAN: chip_name = "aldebaran"; break; default: - dev_err(adev->dev, "Unsupported IP version 0x%x\n", - adev->ip_versions[MP1_HWIP][0]); + dev_err(adev->dev, "Unsupported ASIC type %d\n", adev->asic_type); return -EINVAL; } @@ -212,24 +213,20 @@ int smu_v13_0_check_fw_version(struct smu_context *smu) if (smu->is_apu) adev->pm.fw_version = smu_version; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 2): + switch (smu->adev->asic_type) { + case CHIP_ALDEBARAN: smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE; break; - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + case CHIP_YELLOW_CARP: smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_YELLOW_CARP; break; default: - dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n", - adev->ip_versions[MP1_HWIP][0]); + dev_err(smu->adev->dev, "smu unsupported asic type:%d.\n", smu->adev->asic_type); smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_INV; break; } - /* only for dGPU w/ SMU13*/ - if (adev->pm.fw) - dev_dbg(adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n", + dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n", smu_version, smu_major, smu_minor, smu_debug); /* @@ -241,11 +238,11 @@ int smu_v13_0_check_fw_version(struct smu_context *smu) * of halt driver loading. */ if (if_version != smu->smc_driver_if_version) { - dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, " + dev_info(smu->adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, " "smu fw version = 0x%08x (%d.%d.%d)\n", smu->smc_driver_if_version, if_version, smu_version, smu_major, smu_minor, smu_debug); - dev_warn(adev->dev, "SMU driver if version not matched\n"); + dev_warn(smu->adev->dev, "SMU driver if version not matched\n"); } return ret; @@ -433,10 +430,8 @@ int smu_v13_0_fini_smc_tables(struct smu_context *smu) kfree(smu_table->hardcode_pptable); smu_table->hardcode_pptable = NULL; - kfree(smu_table->ecc_table); kfree(smu_table->metrics_table); kfree(smu_table->watermarks_table); - smu_table->ecc_table = NULL; smu_table->metrics_table = NULL; smu_table->watermarks_table = NULL; smu_table->metrics_time = 0; @@ -748,9 +743,8 @@ int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable) int ret = 0; struct amdgpu_device *adev = smu->adev; - switch (adev->ip_versions[MP1_HWIP][0]) { - case IP_VERSION(13, 0, 1): - case IP_VERSION(13, 0, 3): + switch (adev->asic_type) { + case CHIP_YELLOW_CARP: if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) return 0; if (enable) @@ -950,27 +944,22 @@ int smu_v13_0_get_current_power_limit(struct smu_context *smu, return ret; } -int smu_v13_0_set_power_limit(struct smu_context *smu, - enum smu_ppt_limit_type limit_type, - uint32_t limit) +int smu_v13_0_set_power_limit(struct smu_context *smu, uint32_t n) { int ret = 0; - if (limit_type != SMU_DEFAULT_PPT_LIMIT) - return -EINVAL; - if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { dev_err(smu->adev->dev, "Setting new power limit is not supported!\n"); return -EOPNOTSUPP; } - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit, NULL); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, n, NULL); if (ret) { dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__); return ret; } - smu->current_power_limit = limit; + smu->current_power_limit = n; return 0; } @@ -1429,6 +1418,25 @@ int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu) return ret; } +int smu_v13_0_mode1_reset(struct smu_context *smu) +{ + u32 smu_version; + int ret = 0; + /* + * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07 + */ + smu_cmn_get_smc_version(smu, NULL, &smu_version); + if (smu_version < 0x00440700) + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); + else + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_1, NULL); + + if (!ret) + msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); + + return ret; +} + static int smu_v13_0_wait_for_reset_complete(struct smu_context *smu, uint64_t event_arg) { diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index 0bc84b709a..0e1a843608 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -64,6 +64,7 @@ static struct cmn2asic_msg_mapping yellow_carp_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1), MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1), MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1), + MSG_MAP(ActiveProcessNotify, PPSMC_MSG_ActiveProcessNotify, 1), MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), @@ -134,6 +135,14 @@ static struct cmn2asic_mapping yellow_carp_table_map[SMU_TABLE_COUNT] = { TAB_MAP_VALID(CUSTOM_DPM), TAB_MAP_VALID(DPMCLOCKS), }; + +static struct cmn2asic_mapping yellow_carp_workload_map[PP_SMC_POWER_PROFILE_COUNT] = { + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT), + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT), + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT), + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT), + WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT), +}; static int yellow_carp_init_smc_tables(struct smu_context *smu) { @@ -529,6 +538,81 @@ static int yellow_carp_set_watermarks_table(struct smu_context *smu, return 0; } +static int yellow_carp_get_power_profile_mode(struct smu_context *smu, + char *buf) +{ + static const char *profile_name[] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE", + "CUSTOM"}; + uint32_t i, size = 0; + int16_t workload_type = 0; + + if (!buf) + return -EINVAL; + + for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { + /* + * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT. + * Not all profile modes are supported on yellow carp. + */ + workload_type = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_WORKLOAD, + i); + + if (workload_type < 0) + continue; + + size += sysfs_emit_at(buf, size, "%2d %14s%s\n", + i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); + } + + return size; +} + +static int yellow_carp_set_power_profile_mode(struct smu_context *smu, + long *input, uint32_t size) +{ + int workload_type, ret; + uint32_t profile_mode = input[size]; + + if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { + dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode); + return -EINVAL; + } + + if (profile_mode == PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT || + profile_mode == PP_SMC_POWER_PROFILE_POWERSAVING) + return 0; + + /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_WORKLOAD, + profile_mode); + if (workload_type < 0) { + dev_dbg(smu->adev->dev, "Unsupported power profile mode %d on YELLOWCARP\n", + profile_mode); + return -EINVAL; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify, + 1 << workload_type, + NULL); + if (ret) { + dev_err_once(smu->adev->dev, "Fail to set workload type %d\n", + workload_type); + return ret; + } + + smu->power_profile_mode = profile_mode; + + return 0; +} + static ssize_t yellow_carp_get_gpu_metrics(struct smu_context *smu, void **table) { @@ -692,11 +776,6 @@ static int yellow_carp_get_current_clk_freq(struct smu_context *smu, case SMU_FCLK: return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetFclkFrequency, 0, value); - case SMU_GFXCLK: - case SMU_SCLK: - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetGfxclkFrequency, 0, value); - break; default: return -EINVAL; } @@ -967,7 +1046,6 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, { int i, size = 0, ret = 0; uint32_t cur_value = 0, value = 0, count = 0; - uint32_t min, max; smu_cmn_get_sysfs_buf(&buf, &size); @@ -1006,27 +1084,6 @@ static int yellow_carp_print_clk_levels(struct smu_context *smu, cur_value == value ? "*" : ""); } break; - case SMU_GFXCLK: - case SMU_SCLK: - ret = yellow_carp_get_current_clk_freq(smu, clk_type, &cur_value); - if (ret) - goto print_clk_out; - min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; - max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; - if (cur_value == max) - i = 2; - else if (cur_value == min) - i = 0; - else - i = 1; - size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, - i == 0 ? "*" : ""); - size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", - i == 1 ? cur_value : YELLOW_CARP_UMD_PSTATE_GFXCLK, - i == 1 ? "*" : ""); - size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, - i == 2 ? "*" : ""); - break; default: break; } @@ -1176,6 +1233,8 @@ static const struct pptable_funcs yellow_carp_ppt_funcs = { .read_sensor = yellow_carp_read_sensor, .is_dpm_running = yellow_carp_is_dpm_running, .set_watermarks_table = yellow_carp_set_watermarks_table, + .get_power_profile_mode = yellow_carp_get_power_profile_mode, + .set_power_profile_mode = yellow_carp_set_power_profile_mode, .get_gpu_metrics = yellow_carp_get_gpu_metrics, .get_enabled_mask = smu_cmn_get_enabled_32_bits_mask, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, @@ -1197,5 +1256,6 @@ void yellow_carp_set_ppt_funcs(struct smu_context *smu) smu->message_map = yellow_carp_message_map; smu->feature_map = yellow_carp_feature_mask_map; smu->table_map = yellow_carp_table_map; + smu->workload_map = yellow_carp_workload_map; smu->is_apu = true; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h index a9205a8ea3..b3ad8352c6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.h @@ -24,6 +24,5 @@ #define __YELLOW_CARP_PPT_H__ extern void yellow_carp_set_ppt_funcs(struct smu_context *smu); -#define YELLOW_CARP_UMD_PSTATE_GFXCLK 1100 #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index ee1a312fd4..843d2cbfc7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -94,10 +94,10 @@ static void smu_cmn_read_arg(struct smu_context *smu, /** * __smu_cmn_poll_stat -- poll for a status from the SMU - * @smu: a pointer to SMU context + * smu: a pointer to SMU context * * Returns the status of the SMU, which could be, - * 0, the SMU is busy with your command; + * 0, the SMU is busy with your previous command; * 1, execution status: success, execution result: success; * 0xFF, execution status: success, execution result: failure; * 0xFE, unknown command; @@ -139,13 +139,9 @@ static void __smu_cmn_reg_print_error(struct smu_context *smu, const char *message = smu_get_message_name(smu, msg); switch (reg_c2pmsg_90) { - case SMU_RESP_NONE: { - u32 msg_idx = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66); - u32 prm = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82); + case SMU_RESP_NONE: dev_err_ratelimited(adev->dev, - "SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x%08X SMN_C2PMSG_82:0x%08X", - msg_idx, prm); - } + "SMU: I'm not done with your previous command!"); break; case SMU_RESP_OK: /* The SMU executed the command. It completed with a @@ -257,11 +253,10 @@ int smu_cmn_send_msg_without_waiting(struct smu_context *smu, uint16_t msg_index, uint32_t param) { - struct amdgpu_device *adev = smu->adev; u32 reg; int res; - if (adev->no_hw_access) + if (smu->adev->no_hw_access) return 0; reg = __smu_cmn_poll_stat(smu); @@ -273,12 +268,6 @@ int smu_cmn_send_msg_without_waiting(struct smu_context *smu, __smu_cmn_send_msg(smu, msg_index, param); res = 0; Out: - if (unlikely(adev->pm.smu_debug_mask & SMU_DEBUG_HALT_ON_ERROR) && - res && (res != -ETIME)) { - amdgpu_device_halt(adev); - WARN_ON(1); - } - return res; } @@ -295,18 +284,9 @@ int smu_cmn_send_msg_without_waiting(struct smu_context *smu, int smu_cmn_wait_for_response(struct smu_context *smu) { u32 reg; - int res; reg = __smu_cmn_poll_stat(smu); - res = __smu_cmn_reg2errno(smu, reg); - - if (unlikely(smu->adev->pm.smu_debug_mask & SMU_DEBUG_HALT_ON_ERROR) && - res && (res != -ETIME)) { - amdgpu_device_halt(smu->adev); - WARN_ON(1); - } - - return res; + return __smu_cmn_reg2errno(smu, reg); } /** @@ -344,11 +324,10 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu, uint32_t param, uint32_t *read_arg) { - struct amdgpu_device *adev = smu->adev; int res, index; u32 reg; - if (adev->no_hw_access) + if (smu->adev->no_hw_access) return 0; index = smu_cmn_to_asic_specific_index(smu, @@ -369,16 +348,11 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu, __smu_cmn_send_msg(smu, (uint16_t) index, param); reg = __smu_cmn_poll_stat(smu); res = __smu_cmn_reg2errno(smu, reg); - if (res != 0) + if (res == -EREMOTEIO) __smu_cmn_reg_print_error(smu, reg, index, param, msg); if (read_arg) smu_cmn_read_arg(smu, read_arg); Out: - if (unlikely(adev->pm.smu_debug_mask & SMU_DEBUG_HALT_ON_ERROR) && res) { - amdgpu_device_halt(adev); - WARN_ON(1); - } - mutex_unlock(&smu->message_lock); return res; } diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig index 58a242871b..3a9e966e0e 100644 --- a/drivers/gpu/drm/arm/Kconfig +++ b/drivers/gpu/drm/arm/Kconfig @@ -6,6 +6,7 @@ config DRM_HDLCD depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on COMMON_CLK select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER help Choose this option if you have an ARM High Definition Colour LCD controller. @@ -26,6 +27,7 @@ config DRM_MALI_DISPLAY depends on DRM && OF && (ARM || ARM64 || COMPILE_TEST) depends on COMMON_CLK select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER select VIDEOMODE_HELPERS help diff --git a/drivers/gpu/drm/arm/display/Kconfig b/drivers/gpu/drm/arm/display/Kconfig index e91598b607..cec0639e3a 100644 --- a/drivers/gpu/drm/arm/display/Kconfig +++ b/drivers/gpu/drm/arm/display/Kconfig @@ -4,6 +4,7 @@ config DRM_KOMEDA depends on DRM && OF depends on COMMON_CLK select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER select VIDEOMODE_HELPERS help diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 0562bdaac0..8c2ab3d653 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -165,7 +165,7 @@ bool malidp_format_mod_supported(struct drm_device *drm, return !malidp_hw_format_is_afbc_only(format); } - if (!fourcc_mod_is_vendor(modifier, ARM)) { + if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) { DRM_ERROR("Unknown modifier (not Arm)\n"); return false; } diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 147abf1a39..21909642ee 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -15,8 +15,6 @@ #include "armada_gem.h" #include "armada_ioctlP.h" -MODULE_IMPORT_NS(DMA_BUF); - static vm_fault_t armada_gem_vm_fault(struct vm_fault *vmf) { struct drm_gem_object *gobj = vmf->vma->vm_private_data; @@ -338,7 +336,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_armada_gem_pwrite *args = data; struct armada_gem_object *dobj; char __user *ptr; - int ret = 0; + int ret; DRM_DEBUG_DRIVER("handle %u off %u size %u ptr 0x%llx\n", args->handle, args->offset, args->size, args->ptr); @@ -351,8 +349,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (!access_ok(ptr, args->size)) return -EFAULT; - if (fault_in_readable(ptr, args->size)) - return -EFAULT; + ret = fault_in_pages_readable(ptr, args->size); + if (ret) + return ret; dobj = armada_gem_object_lookup(file, args->handle); if (dobj == NULL) diff --git a/drivers/gpu/drm/ast/Makefile b/drivers/gpu/drm/ast/Makefile index 21f71160bc..438a2d05b1 100644 --- a/drivers/gpu/drm/ast/Makefile +++ b/drivers/gpu/drm/ast/Makefile @@ -3,6 +3,6 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -ast-y := ast_drv.o ast_i2c.o ast_main.o ast_mm.o ast_mode.o ast_post.o ast_dp501.o +ast-y := ast_drv.o ast_main.o ast_mm.o ast_mode.o ast_post.o ast_dp501.o obj-$(CONFIG_DRM_AST) := ast.o diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 6d8613f6fe..86d5cd7b63 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -26,6 +26,7 @@ * Authors: Dave Airlie */ +#include #include #include @@ -232,7 +233,7 @@ static struct pci_driver ast_pci_driver = { static int __init ast_init(void) { - if (drm_firmware_drivers_only() && ast_modeset == -1) + if (vgacon_text_force() && ast_modeset == -1) return -EINVAL; if (ast_modeset == 0) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 00bfa41ff7..39ca338eb8 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -158,6 +158,8 @@ struct ast_private { uint32_t dram_type; uint32_t mclk; + int fb_mtrr; + struct drm_plane primary_plane; struct ast_cursor_plane cursor_plane; struct drm_crtc crtc; @@ -357,7 +359,4 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata); u8 ast_get_dp501_max_clk(struct drm_device *dev); void ast_init_3rdtx(struct drm_device *dev); -/* ast_i2c.c */ -struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); - #endif diff --git a/drivers/gpu/drm/ast/ast_mm.c b/drivers/gpu/drm/ast/ast_mm.c index 6e999408dd..7592f1b9e1 100644 --- a/drivers/gpu/drm/ast/ast_mm.c +++ b/drivers/gpu/drm/ast/ast_mm.c @@ -74,28 +74,35 @@ static u32 ast_get_vram_size(struct ast_private *ast) return vram_size; } +static void ast_mm_release(struct drm_device *dev, void *ptr) +{ + struct ast_private *ast = to_ast_private(dev); + struct pci_dev *pdev = to_pci_dev(dev->dev); + + arch_phys_wc_del(ast->fb_mtrr); + arch_io_free_memtype_wc(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); +} + int ast_mm_init(struct ast_private *ast) { struct drm_device *dev = &ast->base; struct pci_dev *pdev = to_pci_dev(dev->dev); - resource_size_t base, size; u32 vram_size; int ret; - base = pci_resource_start(pdev, 0); - size = pci_resource_len(pdev, 0); - - /* Don't fail on errors, but performance might be reduced. */ - devm_arch_io_reserve_memtype_wc(dev->dev, base, size); - devm_arch_phys_wc_add(dev->dev, base, size); - vram_size = ast_get_vram_size(ast); - ret = drmm_vram_helper_init(dev, base, vram_size); + ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), vram_size); if (ret) { drm_err(dev, "Error initializing VRAM MM; %d\n", ret); return ret; } - return 0; + arch_io_reserve_memtype_wc(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + + return drmm_add_action_or_reset(dev, ast_mm_release, NULL); } diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 956c898219..d5c98f79d5 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -47,6 +47,9 @@ #include "ast_drv.h" #include "ast_tables.h" +static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); +static void ast_i2c_destroy(struct ast_i2c_chan *i2c); + static inline void ast_load_palette_index(struct ast_private *ast, u8 index, u8 red, u8 green, u8 blue) @@ -1210,9 +1213,9 @@ static int ast_get_modes(struct drm_connector *connector) { struct ast_connector *ast_connector = to_ast_connector(connector); struct ast_private *ast = to_ast_private(connector->dev); - struct edid *edid = NULL; - bool flags = false; + struct edid *edid; int ret; + bool flags = false; if (ast->tx_chip_type == AST_TX_DP501) { ast->dp501_maxclk = 0xff; @@ -1226,7 +1229,7 @@ static int ast_get_modes(struct drm_connector *connector) else kfree(edid); } - if (!flags && ast_connector->i2c) + if (!flags) edid = drm_get_edid(connector, &ast_connector->i2c->adapter); if (edid) { drm_connector_update_edid_property(&ast_connector->base, edid); @@ -1300,6 +1303,14 @@ static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, return flags; } +static void ast_connector_destroy(struct drm_connector *connector) +{ + struct ast_connector *ast_connector = to_ast_connector(connector); + + ast_i2c_destroy(ast_connector->i2c); + drm_connector_cleanup(connector); +} + static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { .get_modes = ast_get_modes, .mode_valid = ast_mode_valid, @@ -1308,7 +1319,7 @@ static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { static const struct drm_connector_funcs ast_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = drm_connector_cleanup, + .destroy = ast_connector_destroy, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; @@ -1324,13 +1335,10 @@ static int ast_connector_init(struct drm_device *dev) if (!ast_connector->i2c) drm_err(dev, "failed to add ddc bus for connector\n"); - if (ast_connector->i2c) - drm_connector_init_with_ddc(dev, connector, &ast_connector_funcs, - DRM_MODE_CONNECTOR_VGA, - &ast_connector->i2c->adapter); - else - drm_connector_init(dev, connector, &ast_connector_funcs, - DRM_MODE_CONNECTOR_VGA); + drm_connector_init_with_ddc(dev, connector, + &ast_connector_funcs, + DRM_MODE_CONNECTOR_VGA, + &ast_connector->i2c->adapter); drm_connector_helper_add(connector, &ast_connector_helper_funcs); @@ -1408,3 +1416,124 @@ int ast_mode_config_init(struct ast_private *ast) return 0; } + +static int get_clock(void *i2c_priv) +{ + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = to_ast_private(i2c->dev); + uint32_t val, val2, count, pass; + + count = 0; + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + do { + val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + if (val == val2) { + pass++; + } else { + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + } + } while ((pass < 5) && (count++ < 0x10000)); + + return val & 1 ? 1 : 0; +} + +static int get_data(void *i2c_priv) +{ + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = to_ast_private(i2c->dev); + uint32_t val, val2, count, pass; + + count = 0; + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + do { + val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + if (val == val2) { + pass++; + } else { + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + } + } while ((pass < 5) && (count++ < 0x10000)); + + return val & 1 ? 1 : 0; +} + +static void set_clock(void *i2c_priv, int clock) +{ + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = to_ast_private(i2c->dev); + int i; + u8 ujcrb7, jtemp; + + for (i = 0; i < 0x10000; i++) { + ujcrb7 = ((clock & 0x01) ? 0 : 1); + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); + if (ujcrb7 == jtemp) + break; + } +} + +static void set_data(void *i2c_priv, int data) +{ + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = to_ast_private(i2c->dev); + int i; + u8 ujcrb7, jtemp; + + for (i = 0; i < 0x10000; i++) { + ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); + if (ujcrb7 == jtemp) + break; + } +} + +static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev) +{ + struct ast_i2c_chan *i2c; + int ret; + + i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL); + if (!i2c) + return NULL; + + i2c->adapter.owner = THIS_MODULE; + i2c->adapter.class = I2C_CLASS_DDC; + i2c->adapter.dev.parent = dev->dev; + i2c->dev = dev; + i2c_set_adapdata(&i2c->adapter, i2c); + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "AST i2c bit bus"); + i2c->adapter.algo_data = &i2c->bit; + + i2c->bit.udelay = 20; + i2c->bit.timeout = 2; + i2c->bit.data = i2c; + i2c->bit.setsda = set_data; + i2c->bit.setscl = set_clock; + i2c->bit.getsda = get_data; + i2c->bit.getscl = get_clock; + ret = i2c_bit_add_bus(&i2c->adapter); + if (ret) { + drm_err(dev, "Failed to register bit i2c\n"); + goto out_free; + } + + return i2c; +out_free: + kfree(i2c); + return NULL; +} + +static void ast_i2c_destroy(struct ast_i2c_chan *i2c) +{ + if (!i2c) + return; + i2c_del_adapter(&i2c->adapter); + kfree(i2c); +} diff --git a/drivers/gpu/drm/atmel-hlcdc/Kconfig b/drivers/gpu/drm/atmel-hlcdc/Kconfig index 8ae679f1a5..5f67f00155 100644 --- a/drivers/gpu/drm/atmel-hlcdc/Kconfig +++ b/drivers/gpu/drm/atmel-hlcdc/Kconfig @@ -4,6 +4,7 @@ config DRM_ATMEL_HLCDC depends on DRM && OF && COMMON_CLK && MFD_ATMEL_HLCDC && ARM select DRM_GEM_CMA_HELPER select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER select DRM_PANEL help Choose this option if you have an ATMEL SoC with an HLCDC display diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 61db5a66b4..431b6e12a8 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -182,7 +182,6 @@ config DRM_PARADE_PS8622 config DRM_PARADE_PS8640 tristate "Parade PS8640 MIPI DSI to eDP Converter" depends on OF - select DRM_DP_AUX_BUS select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 592ecfcf00..05e3abb5a0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -401,6 +401,7 @@ void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode); int adv7533_patch_registers(struct adv7511 *adv); int adv7533_patch_cec_registers(struct adv7511 *adv); int adv7533_attach_dsi(struct adv7511 *adv); +void adv7533_detach_dsi(struct adv7511 *adv); int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv); #ifdef CONFIG_DRM_I2C_ADV7511_AUDIO diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 28d9becc93..a20a45c0b3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -1,8 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0-only /* * adv7511_cec.c - Analog Devices ADV7511/33 cec driver * * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * */ #include diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index f8e5da1485..76555ae64e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -910,6 +910,9 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge, return ret; } + if (adv->type == ADV7533 || adv->type == ADV7535) + ret = adv7533_attach_dsi(adv); + if (adv->i2c_main->irq) regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0), ADV7511_INT0_HPD); @@ -1285,18 +1288,8 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) drm_bridge_add(&adv7511->bridge); adv7511_audio_init(dev, adv7511); - - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { - ret = adv7533_attach_dsi(adv7511); - if (ret) - goto err_unregister_audio; - } - return 0; -err_unregister_audio: - adv7511_audio_exit(adv7511); - drm_bridge_remove(&adv7511->bridge); err_unregister_cec: i2c_unregister_device(adv7511->i2c_cec); clk_disable_unprepare(adv7511->cec_clk); @@ -1314,6 +1307,8 @@ static int adv7511_remove(struct i2c_client *i2c) { struct adv7511 *adv7511 = i2c_get_clientdata(i2c); + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + adv7533_detach_dsi(adv7511); i2c_unregister_device(adv7511->i2c_cec); clk_disable_unprepare(adv7511->cec_clk); diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index eb7579dec4..59d718bde8 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -153,10 +153,11 @@ int adv7533_attach_dsi(struct adv7511 *adv) return -EPROBE_DEFER; } - dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + dsi = mipi_dsi_device_register_full(host, &info); if (IS_ERR(dsi)) { dev_err(dev, "failed to create dsi device\n"); - return PTR_ERR(dsi); + ret = PTR_ERR(dsi); + goto err_dsi_device; } adv->dsi = dsi; @@ -166,13 +167,24 @@ int adv7533_attach_dsi(struct adv7511 *adv) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE; - ret = devm_mipi_dsi_attach(dev, dsi); + ret = mipi_dsi_attach(dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host\n"); - return ret; + goto err_dsi_attach; } return 0; + +err_dsi_attach: + mipi_dsi_device_unregister(dsi); +err_dsi_device: + return ret; +} + +void adv7533_detach_dsi(struct adv7511 *adv) +{ + mipi_dsi_detach(adv->dsi); + mipi_dsi_device_unregister(adv->dsi); } int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 2346dbcc50..ea414cd349 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -32,8 +32,6 @@ #include #include -#include -#include #include