This is the 6.1.30 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmRuPHsACgkQONu9yGCS aT6USxAAx2uklTRE3mmIS9qytOjb8Z3gsA8LVaaQ3f25CWNiuverNj0mFyNtI9KX 84ZBS/G8aHA6z0dtdyMupHznHehQp7pVo0LOeVMz2bR+CjkpRQei2NimG8bGRcFK W6c40w99lD9dYpaal3yajs+k+LF3BktmBNc0SynCjjyEy4YA5RbWOhtGX6P4VRqs sPXcmmAHsqDPLfqsgsHiBNsiw+dCP7jY1a17rTxz1g49/4zS6BEGtxxpU4UZNbph rKrX0sgF8UM15IfdFc0CiOXhAcL7QQfUbucJ/94180gclF4j6QqAMueAr6mLWkFd Pj7vLn/KD2wA2dzTBekHZ9SYp31xcXomkzfdLoMMnazfy3RL4sO7WhJks0k0T2En 3LIlsRZx/C2ztf3SLq2z2Bw/ExaefrydLI9cWJBi7CQ5yUVO15edcv40W4pxoMOL xFDZhCksC+JNc74HPYKTmg+SJQsxtYeLrwb6zW43aJByY+rls70crfhdS5fORvmH G8qDS2PCNAqpulxyxQtYxiIcRiM4SqPskves+3nu7gBFGfsv2AJU1gNCorIpZuW8 DS2jrMwPv7gH+eUvqrnrtdA+Vk4TYWslg0mPlVNavX98i9/dC9Vjss3yXCYh7Q6u 0+BpSBLtKM4pahaMgKpYv/V/r+GKvIt7Npki8o/bs1nuykF04aw= =hAQM -----END PGP SIGNATURE----- Merge 6.1.30 into android14-6.1-lts Changes in 6.1.30 drm/fbdev-generic: prohibit potential out-of-bounds access drm/mipi-dsi: Set the fwnode for mipi_dsi_device ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings net: skb_partial_csum_set() fix against transport header magic value net: mdio: mvusb: Fix an error handling path in mvusb_mdio_probe() scsi: ufs: core: Fix I/O hang that occurs when BKOPS fails in W-LUN suspend tick/broadcast: Make broadcast device replacement work correctly linux/dim: Do nothing if no time delta between samples net: stmmac: Initialize MAC_ONEUS_TIC_COUNTER register net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs(). net: phy: bcm7xx: Correct read from expansion register netfilter: nf_tables: always release netdev hooks from notifier netfilter: conntrack: fix possible bug_on with enable_hooks=1 bonding: fix send_peer_notif overflow netlink: annotate accesses to nlk->cb_running net: annotate sk->sk_err write from do_recvmmsg() net: deal with most data-races in sk_wait_event() net: add vlan_get_protocol_and_depth() helper tcp: add annotations around sk->sk_shutdown accesses gve: Remove the code of clearing PBA bit ipvlan:Fix out-of-bounds caused by unclear skb->cb net: mscc: ocelot: fix stat counter register values net: datagram: fix data-races in datagram_poll() af_unix: Fix a data race of sk->sk_receive_queue->qlen. af_unix: Fix data races around sk->sk_shutdown. drm/i915/guc: Don't capture Gen8 regs on Xe devices drm/i915: Fix NULL ptr deref by checking new_crtc_state drm/i915/dp: prevent potential div-by-zero drm/i915: Expand force_probe to block probe of devices as well. drm/i915: taint kernel when force probing unsupported devices fbdev: arcfb: Fix error handling in arcfb_probe() ext4: reflect error codes from ext4_multi_mount_protect() to its callers ext4: don't clear SB_RDONLY when remounting r/w until quota is re-enabled ext4: allow to find by goal if EXT4_MB_HINT_GOAL_ONLY is set ext4: allow ext4_get_group_info() to fail refscale: Move shutdown from wait_event() to wait_event_idle() selftests: cgroup: Add 'malloc' failures checks in test_memcontrol rcu: Protect rcu_print_task_exp_stall() ->exp_tasks access open: return EINVAL for O_DIRECTORY | O_CREAT fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode() drm/displayid: add displayid_get_header() and check bounds better drm/amd/display: populate subvp cmd info only for the top pipe drm/amd/display: Correct DML calculation to align HW formula platform/x86: x86-android-tablets: Add Acer Iconia One 7 B1-750 data drm/amd/display: Enable HostVM based on rIOMMU active drm/amd/display: Use DC_LOG_DC in the trasform pixel function regmap: cache: Return error in cache sync operations for REGCACHE_NONE remoteproc: imx_dsp_rproc: Add custom memory copy implementation for i.MX DSP Cores arm64: dts: qcom: msm8996: Add missing DWC3 quirks media: cx23885: Fix a null-ptr-deref bug in buffer_prepare() and buffer_finish() media: pci: tw68: Fix null-ptr-deref bug in buf prepare and finish media: pvrusb2: VIDEO_PVRUSB2 depends on DVB_CORE to use dvb_* symbols ACPI: processor: Check for null return of devm_kzalloc() in fch_misc_setup() drm/rockchip: dw_hdmi: cleanup drm encoder during unbind memstick: r592: Fix UAF bug in r592_remove due to race condition arm64: dts: imx8mq-librem5: Remove dis_u3_susphy_quirk from usb_dwc3_0 firmware: arm_sdei: Fix sleep from invalid context BUG ACPI: EC: Fix oops when removing custom query handlers drm/amd/display: fixed dcn30+ underflow issue remoteproc: stm32_rproc: Add mutex protection for workqueue drm/tegra: Avoid potential 32-bit integer overflow drm/msm/dp: Clean up handling of DP AUX interrupts ACPICA: Avoid undefined behavior: applying zero offset to null pointer ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in acpi_db_display_objects arm64: dts: qcom: sdm845-polaris: Drop inexistent properties irqchip/gicv3: Workaround for NVIDIA erratum T241-FABRIC-4 ACPI: video: Remove desktops without backlight DMI quirks drm/amd/display: Correct DML calculation to follow HW SPEC drm/amd: Fix an out of bounds error in BIOS parser drm/amdgpu: Fix sdma v4 sw fini error media: Prefer designated initializers over memset for subdev pad ops media: mediatek: vcodec: Fix potential array out-of-bounds in decoder queue_setup wifi: ath: Silence memcpy run-time false positive warning bpf: Annotate data races in bpf_local_storage wifi: brcmfmac: pcie: Provide a buffer of random bytes to the device wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex ext2: Check block size validity during mount scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow scsi: lpfc: Correct used_rpi count when devloss tmo fires with no recovery bnxt: avoid overflow in bnxt_get_nvram_directory() net: pasemi: Fix return type of pasemi_mac_start_tx() net: Catch invalid index in XPS mapping netdev: Enforce index cap in netdev_get_tx_queue scsi: target: iscsit: Free cmds before session free lib: cpu_rmap: Avoid use after free on rmap->obj array entries scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race condition gfs2: Fix inode height consistency check scsi: ufs: ufs-pci: Add support for Intel Lunar Lake ext4: set goal start correctly in ext4_mb_normalize_request ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa() crypto: jitter - permanent and intermittent health errors f2fs: Fix system crash due to lack of free space in LFS f2fs: fix to drop all dirty pages during umount() if cp_error is set f2fs: fix to check readonly condition correctly samples/bpf: Fix fout leak in hbm's run_bpf_prog bpf: Add preempt_count_{sub,add} into btf id deny list md: fix soft lockup in status_resync wifi: iwlwifi: pcie: fix possible NULL pointer dereference wifi: iwlwifi: add a new PCI device ID for BZ device wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf wifi: iwlwifi: mvm: fix ptk_pn memory leak block, bfq: Fix division by zero error on zero wsum wifi: ath11k: Ignore frags from uninitialized peer in dp. wifi: iwlwifi: fix iwl_mvm_max_amsdu_size() for MLO null_blk: Always check queue mode setting from configfs wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace wifi: ath11k: Fix SKB corruption in REO destination ring nbd: fix incomplete validation of ioctl arg ipvs: Update width of source for ip_vs_sync_conn_options Bluetooth: btusb: Add new PID/VID 04ca:3801 for MT7663 Bluetooth: Add new quirk for broken local ext features page 2 Bluetooth: btrtl: add support for the RTL8723CS Bluetooth: Improve support for Actions Semi ATS2851 based devices Bluetooth: btrtl: check for NULL in btrtl_set_quirks() Bluetooth: btintel: Add LE States quirk support Bluetooth: hci_bcm: Fall back to getting bdaddr from EFI if not set Bluetooth: Add new quirk for broken set random RPA timeout for ATS2851 Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp Bluetooth: btrtl: Add the support for RTL8851B staging: rtl8192e: Replace macro RTL_PCI_DEVICE with PCI_DEVICE HID: apple: Set the tilde quirk flag on the Geyser 4 and later staging: axis-fifo: initialize timeouts in init only ASoC: amd: yc: Add DMI entries to support HP OMEN 16-n0xxx (8A42) HID: logitech-hidpp: Don't use the USB serial for USB devices HID: logitech-hidpp: Reconcile USB and Unifying serials spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3 usb: typec: ucsi: acpi: add quirk for ASUS Zenbook UM325 ALSA: hda: LNL: add HD Audio PCI ID ASoC: amd: Add Dell G15 5525 to quirks list ASoC: amd: yc: Add ThinkBook 14 G5+ ARP to quirks list for acp6x HID: apple: Set the tilde quirk flag on the Geyser 3 HID: Ignore battery for ELAN touchscreen on ROG Flow X13 GV301RA HID: wacom: generic: Set battery quirk only when we see battery data usb: typec: tcpm: fix multiple times discover svids error serial: 8250: Reinit port->pm on port specific driver unbind mcb-pci: Reallocate memory region to avoid memory overlapping sched: Fix KCSAN noinstr violation lkdtm/stackleak: Fix noinstr violation recordmcount: Fix memory leaks in the uwrite function soundwire: dmi-quirks: add remapping for Intel 'Rooks County' NUC M15 phy: st: miphy28lp: use _poll_timeout functions for waits soundwire: qcom: gracefully handle too many ports in DT soundwire: bus: Fix unbalanced pm_runtime_put() causing usage count underflow mfd: intel_soc_pmic_chtwc: Add Lenovo Yoga Book X90F to intel_cht_wc_models mfd: dln2: Fix memory leak in dln2_probe() mfd: intel-lpss: Add Intel Meteor Lake PCH-S LPSS PCI IDs parisc: Replace regular spinlock with spin_trylock on panic path platform/x86: Move existing HP drivers to a new hp subdir platform/x86: hp-wmi: add micmute to hp_wmi_keymap struct drm/amdgpu: drop gfx_v11_0_cp_ecc_error_irq_funcs xfrm: don't check the default policy if the policy allows the packet Revert "Fix XFRM-I support for nested ESP tunnels" drm/msm/dp: unregister audio driver during unbind drm/msm/dpu: Assign missing writeback log_mask drm/msm/dpu: Move non-MDP_TOP INTF_INTR offsets out of hwio header drm/msm/dpu: Remove duplicate register defines from INTF dt-bindings: display/msm: dsi-controller-main: Document qcom, master-dsi and qcom, sync-dual-dsi platform: Provide a remove callback that returns no value ASoC: fsl_micfil: Fix error handler with pm_runtime_enable cpupower: Make TSC read per CPU for Mperf monitor xfrm: Reject optional tunnel/BEET mode templates in outbound policies af_key: Reject optional tunnel/BEET mode templates in outbound policies drm/msm: Fix submit error-path leaks selftests: seg6: disable DAD on IPv6 router cfg for srv6_end_dt4_l3vpn_test selftets: seg6: disable rp_filter by default in srv6_end_dt4_l3vpn_test net: fec: Better handle pm_runtime_get() failing in .remove() net: phy: dp83867: add w/a for packet errors seen with short cables ALSA: firewire-digi00x: prevent potential use after free wifi: mt76: connac: fix stats->tx_bytes calculation ALSA: hda/realtek: Apply HP B&O top speaker profile to Pavilion 15 sfc: disable RXFCS and RXALL features by default vsock: avoid to close connected socket after the timeout tcp: fix possible sk_priority leak in tcp_v4_send_reset() serial: arc_uart: fix of_iomap leak in `arc_serial_probe` serial: 8250_bcm7271: balance clk_enable calls serial: 8250_bcm7271: fix leak in `brcmuart_probe` erspan: get the proto with the md version for collect_md net: dsa: rzn1-a5psw: enable management frames for CPU port net: dsa: rzn1-a5psw: fix STP states handling net: dsa: rzn1-a5psw: disable learning for standalone ports net: hns3: fix output information incomplete for dumping tx queue info with debugfs net: hns3: fix sending pfc frames after reset issue net: hns3: fix reset delay time to avoid configuration timeout net: hns3: fix reset timeout when enable full VF media: netup_unidvb: fix use-after-free at del_timer() SUNRPC: double free xprt_ctxt while still in use SUNRPC: always free ctxt when freeing deferred request SUNRPC: Fix trace_svc_register() call site ASoC: mediatek: mt8186: Fix use-after-free in driver remove path ASoC: SOF: topology: Fix logic for copying tuples drm/exynos: fix g2d_open/close helper function definitions net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment() virtio-net: Maintain reverse cleanup order virtio_net: Fix error unwinding of XDP initialization tipc: add tipc_bearer_min_mtu to calculate min mtu tipc: do not update mtu if msg_max is too small in mtu negotiation tipc: check the bearer min mtu properly when setting it by netlink s390/cio: include subchannels without devices also for evaluation can: dev: fix missing CAN XL support in can_put_echo_skb() net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop() net: bcmgenet: Restore phy_stop() depending upon suspend/close ice: introduce clear_reset_state operation ice: Fix ice VF reset during iavf initialization wifi: cfg80211: Drop entries with invalid BSSIDs in RNR wifi: mac80211: fortify the spinlock against deadlock by interrupt wifi: mac80211: fix min center freq offset tracing wifi: mac80211: Abort running color change when stopping the AP wifi: iwlwifi: mvm: fix cancel_delayed_work_sync() deadlock wifi: iwlwifi: fw: fix DBGI dump wifi: iwlwifi: fix OEM's name in the ppag approved list wifi: iwlwifi: mvm: fix OEM's name in the tas approved list wifi: iwlwifi: mvm: don't trust firmware n_channels scsi: storvsc: Don't pass unused PFNs to Hyper-V host net: tun: rebuild error handling in tun_get_user tun: Fix memory leak for detached NAPI queue. cassini: Fix a memory leak in the error handling path of cas_init_one() net: dsa: mv88e6xxx: Fix mv88e6393x EPC write command offset igb: fix bit_shift to be in [1..8] range vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit() net: wwan: iosm: fix NULL pointer dereference when removing device net: pcs: xpcs: fix C73 AN not getting enabled net: selftests: Fix optstring netfilter: nf_tables: fix nft_trans type confusion netfilter: nft_set_rbtree: fix null deref on element insertion bridge: always declare tunnel functions ALSA: usb-audio: Add a sample rate workaround for Line6 Pod Go USB: usbtmc: Fix direction for 0-length ioctl control messages usb-storage: fix deadlock when a scsi command timeouts more than once USB: UHCI: adjust zhaoxin UHCI controllers OverCurrent bit value usb: dwc3: gadget: Improve dwc3_gadget_suspend() and dwc3_gadget_resume() usb: dwc3: debugfs: Resume dwc3 before accessing registers usb: gadget: u_ether: Fix host MAC address case usb: typec: altmodes/displayport: fix pin_assignment_show Revert "usb: gadget: udc: core: Prevent redundant calls to pullup" Revert "usb: gadget: udc: core: Invoke usb_gadget_connect only when started" xhci-pci: Only run d3cold avoidance quirk for s2idle xhci: Fix incorrect tracking of free space on transfer rings ALSA: hda: Fix Oops by 9.1 surround channel names ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table ALSA: hda/realtek: Add quirk for Clevo L140AU ALSA: hda/realtek: Add a quirk for HP EliteDesk 805 ALSA: hda/realtek: Add quirk for 2nd ASUS GU603 ALSA: hda/realtek: Add quirk for HP EliteBook G10 laptops ALSA: hda/realtek: Fix mute and micmute LEDs for yet another HP laptop can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag can: isotp: recvmsg(): allow MSG_CMSG_COMPAT flag can: kvaser_pciefd: Set CAN_STATE_STOPPED in kvaser_pciefd_stop() can: kvaser_pciefd: Call request_irq() before enabling interrupts can: kvaser_pciefd: Empty SRB buffer in probe can: kvaser_pciefd: Clear listen-only bit if not explicitly requested can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt can: kvaser_pciefd: Disable interrupts in probe error path wifi: rtw88: use work to update rate to avoid RCU warning SMB3: Close all deferred handles of inode in case of handle lease break SMB3: drop reference to cfile before sending oplock break ksmbd: smb2: Allow messages padded to 8byte boundary ksmbd: allocate one more byte for implied bcc[0] ksmbd: fix wrong UserName check in session_user ksmbd: fix global-out-of-bounds in smb2_find_context_vals KVM: Fix vcpu_array[0] races statfs: enforce statfs[64] structure initialization maple_tree: make maple state reusable after mas_empty_area() mm: fix zswap writeback race condition serial: Add support for Advantech PCI-1611U card serial: 8250_exar: Add support for USR298x PCI Modems serial: qcom-geni: fix enabling deactivated interrupt thunderbolt: Clear registers properly when auto clear isn't in use vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF ceph: force updating the msg pointer in non-split case drm/amd/pm: fix possible power mode mismatch between driver and PMFW drm/amdgpu/gmc11: implement get_vbios_fb_size() drm/amdgpu/gfx10: Disable gfxoff before disabling powergating. drm/amdgpu/gfx11: Adjust gfxoff before powergating on gfx11 as well drm/amdgpu: refine get gpu clock counter method drm/amdgpu/gfx11: update gpu_clock_counter logic dt-bindings: ata: ahci-ceva: Cover all 4 iommus entries powerpc/iommu: DMA address offset is incorrectly calculated with 2MB TCEs powerpc/iommu: Incorrect DDW Table is referenced for SR-IOV device tpm/tpm_tis: Disable interrupts for more Lenovo devices powerpc/64s/radix: Fix soft dirty tracking nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode() s390/dasd: fix command reject error on ESE devices s390/crypto: use vector instructions only if available for ChaCha20 s390/qdio: fix do_sqbs() inline assembly constraint arm64: mte: Do not set PG_mte_tagged if tags were not initialized rethook: use preempt_{disable, enable}_notrace in rethook_trampoline_handler rethook, fprobe: do not trace rethook related functions remoteproc: imx_dsp_rproc: Fix kernel test robot sparse warning crypto: testmgr - fix RNG performance in fuzz tests drm/amdgpu: declare firmware for new MES 11.0.4 drm/amd/amdgpu: introduce gc_*_mes_2.bin v2 drm/amdgpu: reserve the old gc_11_0_*_mes.bin Linux 6.1.30 Change-Id: I411885affcf017410aab34bf3fba2dde96df6593 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
26c1cc6858
@ -32,7 +32,7 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
maxItems: 4
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
@ -65,6 +65,18 @@ properties:
|
||||
Indicates if the DSI controller is driving a panel which needs
|
||||
2 DSI links.
|
||||
|
||||
qcom,master-dsi:
|
||||
type: boolean
|
||||
description: |
|
||||
Indicates if the DSI controller is the master DSI controller when
|
||||
qcom,dual-dsi-mode enabled.
|
||||
|
||||
qcom,sync-dual-dsi:
|
||||
type: boolean
|
||||
description: |
|
||||
Indicates if the DSI controller needs to sync the other DSI controller
|
||||
with MIPI DCS commands when qcom,dual-dsi-mode enabled.
|
||||
|
||||
assigned-clocks:
|
||||
maxItems: 2
|
||||
description: |
|
||||
|
@ -9384,7 +9384,7 @@ F: drivers/net/wireless/intersil/hostap/
|
||||
HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Orphan
|
||||
F: drivers/platform/x86/tc1100-wmi.c
|
||||
F: drivers/platform/x86/hp/tc1100-wmi.c
|
||||
|
||||
HPET: High Precision Event Timers driver
|
||||
M: Clemens Ladisch <clemens@ladisch.de>
|
||||
@ -11887,7 +11887,7 @@ M: Eric Piel <eric.piel@tremplin-utc.net>
|
||||
S: Maintained
|
||||
F: Documentation/misc-devices/lis3lv02d.rst
|
||||
F: drivers/misc/lis3lv02d/
|
||||
F: drivers/platform/x86/hp_accel.c
|
||||
F: drivers/platform/x86/hp/hp_accel.c
|
||||
|
||||
LIST KUNIT TEST
|
||||
M: David Gow <davidgow@google.com>
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 29
|
||||
SUBLEVEL = 30
|
||||
EXTRAVERSION =
|
||||
NAME = Curry Ramen
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/**
|
||||
/*
|
||||
* arch/arm/mac-sa1100/jornada720_ssp.c
|
||||
*
|
||||
* Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
|
||||
@ -26,6 +26,7 @@ static unsigned long jornada_ssp_flags;
|
||||
|
||||
/**
|
||||
* jornada_ssp_reverse - reverses input byte
|
||||
* @byte: input byte to reverse
|
||||
*
|
||||
* we need to reverse all data we receive from the mcu due to its physical location
|
||||
* returns : 01110111 -> 11101110
|
||||
@ -46,6 +47,7 @@ EXPORT_SYMBOL(jornada_ssp_reverse);
|
||||
|
||||
/**
|
||||
* jornada_ssp_byte - waits for ready ssp bus and sends byte
|
||||
* @byte: input byte to transmit
|
||||
*
|
||||
* waits for fifo buffer to clear and then transmits, if it doesn't then we will
|
||||
* timeout after <timeout> rounds. Needs mcu running before its called.
|
||||
@ -77,6 +79,7 @@ EXPORT_SYMBOL(jornada_ssp_byte);
|
||||
|
||||
/**
|
||||
* jornada_ssp_inout - decide if input is command or trading byte
|
||||
* @byte: input byte to send (may be %TXDUMMY)
|
||||
*
|
||||
* returns : (jornada_ssp_byte(byte)) on success
|
||||
* : %-ETIMEDOUT on timeout failure
|
||||
|
@ -1299,7 +1299,6 @@ &usb_dwc3_0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
dr_mode = "otg";
|
||||
snps,dis_u3_susphy_quirk;
|
||||
usb-role-switch;
|
||||
status = "okay";
|
||||
|
||||
|
@ -2979,8 +2979,11 @@ usb3_dwc3: usb@6a00000 {
|
||||
interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&hsusb_phy1>, <&ssusb_phy_0>;
|
||||
phy-names = "usb2-phy", "usb3-phy";
|
||||
snps,hird-threshold = /bits/ 8 <0>;
|
||||
snps,dis_u2_susphy_quirk;
|
||||
snps,dis_enblslpm_quirk;
|
||||
snps,is-utmi-l1-suspend;
|
||||
tx-fifo-resize;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -731,8 +731,6 @@ &wifi {
|
||||
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
||||
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
||||
vdd-3.3-ch1-supply = <&vreg_l23a_3p3>;
|
||||
|
||||
qcom,snoc-host-cap-skip-quirk;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -80,6 +80,7 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
|
||||
int pdc_do_reset(void);
|
||||
int pdc_soft_power_info(unsigned long *power_reg);
|
||||
int pdc_soft_power_button(int sw_control);
|
||||
int pdc_soft_power_button_panic(int sw_control);
|
||||
void pdc_io_reset(void);
|
||||
void pdc_io_reset_devices(void);
|
||||
int pdc_iodc_getc(void);
|
||||
|
@ -1232,15 +1232,18 @@ int __init pdc_soft_power_info(unsigned long *power_reg)
|
||||
}
|
||||
|
||||
/*
|
||||
* pdc_soft_power_button - Control the soft power button behaviour
|
||||
* @sw_control: 0 for hardware control, 1 for software control
|
||||
* pdc_soft_power_button{_panic} - Control the soft power button behaviour
|
||||
* @sw_control: 0 for hardware control, 1 for software control
|
||||
*
|
||||
*
|
||||
* This PDC function places the soft power button under software or
|
||||
* hardware control.
|
||||
* Under software control the OS may control to when to allow to shut
|
||||
* down the system. Under hardware control pressing the power button
|
||||
* Under software control the OS may control to when to allow to shut
|
||||
* down the system. Under hardware control pressing the power button
|
||||
* powers off the system immediately.
|
||||
*
|
||||
* The _panic version relies on spin_trylock to prevent deadlock
|
||||
* on panic path.
|
||||
*/
|
||||
int pdc_soft_power_button(int sw_control)
|
||||
{
|
||||
@ -1254,6 +1257,22 @@ int pdc_soft_power_button(int sw_control)
|
||||
return retval;
|
||||
}
|
||||
|
||||
int pdc_soft_power_button_panic(int sw_control)
|
||||
{
|
||||
int retval;
|
||||
unsigned long flags;
|
||||
|
||||
if (!spin_trylock_irqsave(&pdc_lock, flags)) {
|
||||
pr_emerg("Couldn't enable soft power button\n");
|
||||
return -EBUSY; /* ignored by the panic notifier */
|
||||
}
|
||||
|
||||
retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
|
||||
spin_unlock_irqrestore(&pdc_lock, flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
|
||||
* Primarily a problem on T600 (which parisc-linux doesn't support) but
|
||||
|
@ -144,7 +144,7 @@ static bool dma_iommu_bypass_supported(struct device *dev, u64 mask)
|
||||
/* We support DMA to/from any memory page via the iommu */
|
||||
int dma_iommu_dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
struct iommu_table *tbl = get_iommu_table_base(dev);
|
||||
struct iommu_table *tbl;
|
||||
|
||||
if (dev_is_pci(dev) && dma_iommu_bypass_supported(dev, mask)) {
|
||||
/*
|
||||
@ -162,6 +162,8 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask)
|
||||
return 1;
|
||||
}
|
||||
|
||||
tbl = get_iommu_table_base(dev);
|
||||
|
||||
if (!tbl) {
|
||||
dev_err(dev, "Warning: IOMMU dma not supported: mask 0x%08llx, table unavailable\n", mask);
|
||||
return 0;
|
||||
|
@ -517,7 +517,7 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
/* Convert entry to a dma_addr_t */
|
||||
entry += tbl->it_offset;
|
||||
dma_addr = entry << tbl->it_page_shift;
|
||||
dma_addr |= (s->offset & ~IOMMU_PAGE_MASK(tbl));
|
||||
dma_addr |= (vaddr & ~IOMMU_PAGE_MASK(tbl));
|
||||
|
||||
DBG(" - %lu pages, entry: %lx, dma_addr: %lx\n",
|
||||
npages, entry, dma_addr);
|
||||
@ -904,6 +904,7 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
|
||||
unsigned int order;
|
||||
unsigned int nio_pages, io_order;
|
||||
struct page *page;
|
||||
int tcesize = (1 << tbl->it_page_shift);
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
order = get_order(size);
|
||||
@ -930,7 +931,8 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
|
||||
memset(ret, 0, size);
|
||||
|
||||
/* Set up tces to cover the allocated range */
|
||||
nio_pages = size >> tbl->it_page_shift;
|
||||
nio_pages = IOMMU_PAGE_ALIGN(size, tbl) >> tbl->it_page_shift;
|
||||
|
||||
io_order = get_iommu_order(size, tbl);
|
||||
mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
|
||||
mask >> tbl->it_page_shift, io_order, 0);
|
||||
@ -938,7 +940,8 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
|
||||
free_pages((unsigned long)ret, order);
|
||||
return NULL;
|
||||
}
|
||||
*dma_handle = mapping;
|
||||
|
||||
*dma_handle = mapping | ((u64)ret & (tcesize - 1));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -949,7 +952,7 @@ void iommu_free_coherent(struct iommu_table *tbl, size_t size,
|
||||
unsigned int nio_pages;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
nio_pages = size >> tbl->it_page_shift;
|
||||
nio_pages = IOMMU_PAGE_ALIGN(size, tbl) >> tbl->it_page_shift;
|
||||
iommu_free(tbl, dma_handle, nio_pages);
|
||||
size = PAGE_ALIGN(size);
|
||||
free_pages((unsigned long)vaddr, get_order(size));
|
||||
|
@ -1040,8 +1040,8 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
|
||||
pte_t entry, unsigned long address, int psize)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
|
||||
_PAGE_RW | _PAGE_EXEC);
|
||||
unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY |
|
||||
_PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
|
||||
|
||||
unsigned long change = pte_val(entry) ^ pte_val(*ptep);
|
||||
/*
|
||||
|
@ -85,19 +85,24 @@ static struct iommu_table_group *iommu_pseries_alloc_group(int node)
|
||||
static void iommu_pseries_free_group(struct iommu_table_group *table_group,
|
||||
const char *node_name)
|
||||
{
|
||||
struct iommu_table *tbl;
|
||||
|
||||
if (!table_group)
|
||||
return;
|
||||
|
||||
tbl = table_group->tables[0];
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
if (table_group->group) {
|
||||
iommu_group_put(table_group->group);
|
||||
BUG_ON(table_group->group);
|
||||
}
|
||||
#endif
|
||||
iommu_tce_table_put(tbl);
|
||||
|
||||
/* Default DMA window table is at index 0, while DDW at 1. SR-IOV
|
||||
* adapters only have table on index 1.
|
||||
*/
|
||||
if (table_group->tables[0])
|
||||
iommu_tce_table_put(table_group->tables[0]);
|
||||
|
||||
if (table_group->tables[1])
|
||||
iommu_tce_table_put(table_group->tables[1]);
|
||||
|
||||
kfree(table_group);
|
||||
}
|
||||
|
@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES) += kprobes_trampoline.o
|
||||
obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_UPROBES) += uprobes.o decode-insn.o simulate-insn.o
|
||||
CFLAGS_REMOVE_simulate-insn.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_rethook_trampoline.o = $(CC_FLAGS_FTRACE)
|
||||
|
@ -82,7 +82,7 @@ void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src,
|
||||
* it cannot handle a block of data or less, but otherwise
|
||||
* it can handle data of arbitrary size
|
||||
*/
|
||||
if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20)
|
||||
if (bytes <= CHACHA_BLOCK_SIZE || nrounds != 20 || !MACHINE_HAS_VX)
|
||||
chacha_crypt_generic(state, dst, src, bytes, nrounds);
|
||||
else
|
||||
chacha20_crypt_s390(state, dst, src, bytes,
|
||||
|
@ -10,6 +10,7 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
|
||||
|
||||
# Do not trace early setup code
|
||||
CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE)
|
||||
CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE)
|
||||
|
||||
endif
|
||||
|
||||
|
@ -17,6 +17,7 @@ CFLAGS_REMOVE_ftrace.o = -pg
|
||||
CFLAGS_REMOVE_early_printk.o = -pg
|
||||
CFLAGS_REMOVE_head64.o = -pg
|
||||
CFLAGS_REMOVE_sev.o = -pg
|
||||
CFLAGS_REMOVE_rethook.o = -pg
|
||||
endif
|
||||
|
||||
KASAN_SANITIZE_head$(BITS).o := n
|
||||
|
@ -637,6 +637,8 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
|
||||
sched_data->service_tree[i].wsum;
|
||||
}
|
||||
}
|
||||
if (!wsum)
|
||||
continue;
|
||||
limit = DIV_ROUND_CLOSEST(limit * entity->weight, wsum);
|
||||
if (entity->allocated >= limit) {
|
||||
bfq_log_bfqq(bfqq->bfqd, bfqq,
|
||||
|
@ -37,6 +37,7 @@
|
||||
* DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/fips.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
@ -59,11 +60,6 @@ void jent_zfree(void *ptr)
|
||||
kfree_sensitive(ptr);
|
||||
}
|
||||
|
||||
void jent_panic(char *s)
|
||||
{
|
||||
panic("%s", s);
|
||||
}
|
||||
|
||||
void jent_memcpy(void *dest, const void *src, unsigned int n)
|
||||
{
|
||||
memcpy(dest, src, n);
|
||||
@ -102,7 +98,6 @@ void jent_get_nstime(__u64 *out)
|
||||
struct jitterentropy {
|
||||
spinlock_t jent_lock;
|
||||
struct rand_data *entropy_collector;
|
||||
unsigned int reset_cnt;
|
||||
};
|
||||
|
||||
static int jent_kcapi_init(struct crypto_tfm *tfm)
|
||||
@ -138,32 +133,30 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
|
||||
|
||||
spin_lock(&rng->jent_lock);
|
||||
|
||||
/* Return a permanent error in case we had too many resets in a row. */
|
||||
if (rng->reset_cnt > (1<<10)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
|
||||
|
||||
/* Reset RNG in case of health failures */
|
||||
if (ret < -1) {
|
||||
pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
|
||||
(ret == -2) ? "Repetition Count Test" :
|
||||
"Adaptive Proportion Test");
|
||||
|
||||
rng->reset_cnt++;
|
||||
if (ret == -3) {
|
||||
/* Handle permanent health test error */
|
||||
/*
|
||||
* If the kernel was booted with fips=1, it implies that
|
||||
* the entire kernel acts as a FIPS 140 module. In this case
|
||||
* an SP800-90B permanent health test error is treated as
|
||||
* a FIPS module error.
|
||||
*/
|
||||
if (fips_enabled)
|
||||
panic("Jitter RNG permanent health test failure\n");
|
||||
|
||||
pr_err("Jitter RNG permanent health test failure\n");
|
||||
ret = -EFAULT;
|
||||
} else if (ret == -2) {
|
||||
/* Handle intermittent health test error */
|
||||
pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
|
||||
ret = -EAGAIN;
|
||||
} else {
|
||||
rng->reset_cnt = 0;
|
||||
|
||||
/* Convert the Jitter RNG error into a usable error code */
|
||||
if (ret == -1)
|
||||
ret = -EINVAL;
|
||||
} else if (ret == -1) {
|
||||
/* Handle other errors */
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock(&rng->jent_lock);
|
||||
|
||||
return ret;
|
||||
@ -197,6 +190,10 @@ static int __init jent_mod_init(void)
|
||||
|
||||
ret = jent_entropy_init();
|
||||
if (ret) {
|
||||
/* Handle permanent health test error */
|
||||
if (fips_enabled)
|
||||
panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
|
||||
|
||||
pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -85,10 +85,14 @@ struct rand_data {
|
||||
* bit generation */
|
||||
|
||||
/* Repetition Count Test */
|
||||
int rct_count; /* Number of stuck values */
|
||||
unsigned int rct_count; /* Number of stuck values */
|
||||
|
||||
/* Adaptive Proportion Test for a significance level of 2^-30 */
|
||||
/* Intermittent health test failure threshold of 2^-30 */
|
||||
#define JENT_RCT_CUTOFF 30 /* Taken from SP800-90B sec 4.4.1 */
|
||||
#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */
|
||||
/* Permanent health test failure threshold of 2^-60 */
|
||||
#define JENT_RCT_CUTOFF_PERMANENT 60
|
||||
#define JENT_APT_CUTOFF_PERMANENT 355
|
||||
#define JENT_APT_WINDOW_SIZE 512 /* Data window size */
|
||||
/* LSB of time stamp to process */
|
||||
#define JENT_APT_LSB 16
|
||||
@ -97,8 +101,6 @@ struct rand_data {
|
||||
unsigned int apt_count; /* APT counter */
|
||||
unsigned int apt_base; /* APT base reference */
|
||||
unsigned int apt_base_set:1; /* APT base reference set? */
|
||||
|
||||
unsigned int health_failure:1; /* Permanent health failure */
|
||||
};
|
||||
|
||||
/* Flags that can be used to initialize the RNG */
|
||||
@ -169,19 +171,26 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
|
||||
return;
|
||||
}
|
||||
|
||||
if (delta_masked == ec->apt_base) {
|
||||
if (delta_masked == ec->apt_base)
|
||||
ec->apt_count++;
|
||||
|
||||
if (ec->apt_count >= JENT_APT_CUTOFF)
|
||||
ec->health_failure = 1;
|
||||
}
|
||||
|
||||
ec->apt_observations++;
|
||||
|
||||
if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
|
||||
jent_apt_reset(ec, delta_masked);
|
||||
}
|
||||
|
||||
/* APT health test failure detection */
|
||||
static int jent_apt_permanent_failure(struct rand_data *ec)
|
||||
{
|
||||
return (ec->apt_count >= JENT_APT_CUTOFF_PERMANENT) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int jent_apt_failure(struct rand_data *ec)
|
||||
{
|
||||
return (ec->apt_count >= JENT_APT_CUTOFF) ? 1 : 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Stuck Test and its use as Repetition Count Test
|
||||
*
|
||||
@ -206,55 +215,14 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
|
||||
*/
|
||||
static void jent_rct_insert(struct rand_data *ec, int stuck)
|
||||
{
|
||||
/*
|
||||
* If we have a count less than zero, a previous RCT round identified
|
||||
* a failure. We will not overwrite it.
|
||||
*/
|
||||
if (ec->rct_count < 0)
|
||||
return;
|
||||
|
||||
if (stuck) {
|
||||
ec->rct_count++;
|
||||
|
||||
/*
|
||||
* The cutoff value is based on the following consideration:
|
||||
* alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
|
||||
* In addition, we require an entropy value H of 1/OSR as this
|
||||
* is the minimum entropy required to provide full entropy.
|
||||
* Note, we collect 64 * OSR deltas for inserting them into
|
||||
* the entropy pool which should then have (close to) 64 bits
|
||||
* of entropy.
|
||||
*
|
||||
* Note, ec->rct_count (which equals to value B in the pseudo
|
||||
* code of SP800-90B section 4.4.1) starts with zero. Hence
|
||||
* we need to subtract one from the cutoff value as calculated
|
||||
* following SP800-90B.
|
||||
*/
|
||||
if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
|
||||
ec->rct_count = -1;
|
||||
ec->health_failure = 1;
|
||||
}
|
||||
} else {
|
||||
/* Reset RCT */
|
||||
ec->rct_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Is there an RCT health test failure?
|
||||
*
|
||||
* @ec [in] Reference to entropy collector
|
||||
*
|
||||
* @return
|
||||
* 0 No health test failure
|
||||
* 1 Permanent health test failure
|
||||
*/
|
||||
static int jent_rct_failure(struct rand_data *ec)
|
||||
{
|
||||
if (ec->rct_count < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline __u64 jent_delta(__u64 prev, __u64 next)
|
||||
{
|
||||
#define JENT_UINT64_MAX (__u64)(~((__u64) 0))
|
||||
@ -303,18 +271,26 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report any health test failures
|
||||
*
|
||||
* @ec [in] Reference to entropy collector
|
||||
*
|
||||
* @return
|
||||
* 0 No health test failure
|
||||
* 1 Permanent health test failure
|
||||
*/
|
||||
/* RCT health test failure detection */
|
||||
static int jent_rct_permanent_failure(struct rand_data *ec)
|
||||
{
|
||||
return (ec->rct_count >= JENT_RCT_CUTOFF_PERMANENT) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int jent_rct_failure(struct rand_data *ec)
|
||||
{
|
||||
return (ec->rct_count >= JENT_RCT_CUTOFF) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Report of health test failures */
|
||||
static int jent_health_failure(struct rand_data *ec)
|
||||
{
|
||||
return ec->health_failure;
|
||||
return jent_rct_failure(ec) | jent_apt_failure(ec);
|
||||
}
|
||||
|
||||
static int jent_permanent_health_failure(struct rand_data *ec)
|
||||
{
|
||||
return jent_rct_permanent_failure(ec) | jent_apt_permanent_failure(ec);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -600,8 +576,8 @@ static void jent_gen_entropy(struct rand_data *ec)
|
||||
*
|
||||
* The following error codes can occur:
|
||||
* -1 entropy_collector is NULL
|
||||
* -2 RCT failed
|
||||
* -3 APT test failed
|
||||
* -2 Intermittent health failure
|
||||
* -3 Permanent health failure
|
||||
*/
|
||||
int jent_read_entropy(struct rand_data *ec, unsigned char *data,
|
||||
unsigned int len)
|
||||
@ -616,39 +592,23 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
|
||||
|
||||
jent_gen_entropy(ec);
|
||||
|
||||
if (jent_health_failure(ec)) {
|
||||
int ret;
|
||||
|
||||
if (jent_rct_failure(ec))
|
||||
ret = -2;
|
||||
else
|
||||
ret = -3;
|
||||
|
||||
if (jent_permanent_health_failure(ec)) {
|
||||
/*
|
||||
* Re-initialize the noise source
|
||||
*
|
||||
* If the health test fails, the Jitter RNG remains
|
||||
* in failure state and will return a health failure
|
||||
* during next invocation.
|
||||
* At this point, the Jitter RNG instance is considered
|
||||
* as a failed instance. There is no rerun of the
|
||||
* startup test any more, because the caller
|
||||
* is assumed to not further use this instance.
|
||||
*/
|
||||
return -3;
|
||||
} else if (jent_health_failure(ec)) {
|
||||
/*
|
||||
* Perform startup health tests and return permanent
|
||||
* error if it fails.
|
||||
*/
|
||||
if (jent_entropy_init())
|
||||
return ret;
|
||||
return -3;
|
||||
|
||||
/* Set APT to initial state */
|
||||
jent_apt_reset(ec, 0);
|
||||
ec->apt_base_set = 0;
|
||||
|
||||
/* Set RCT to initial state */
|
||||
ec->rct_count = 0;
|
||||
|
||||
/* Re-enable Jitter RNG */
|
||||
ec->health_failure = 0;
|
||||
|
||||
/*
|
||||
* Return the health test failure status to the
|
||||
* caller as the generated value is not appropriate.
|
||||
*/
|
||||
return ret;
|
||||
return -2;
|
||||
}
|
||||
|
||||
if ((DATA_SIZE_BITS / 8) < len)
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
extern void *jent_zalloc(unsigned int len);
|
||||
extern void jent_zfree(void *ptr);
|
||||
extern void jent_panic(char *s);
|
||||
extern void jent_memcpy(void *dest, const void *src, unsigned int n);
|
||||
extern void jent_get_nstime(__u64 *out);
|
||||
|
||||
|
270
crypto/testmgr.c
270
crypto/testmgr.c
@ -852,12 +852,50 @@ static int prepare_keybuf(const u8 *key, unsigned int ksize,
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
|
||||
/* Generate a random length in range [0, max_len], but prefer smaller values */
|
||||
static unsigned int generate_random_length(unsigned int max_len)
|
||||
{
|
||||
unsigned int len = prandom_u32_max(max_len + 1);
|
||||
/*
|
||||
* The fuzz tests use prandom instead of the normal Linux RNG since they don't
|
||||
* need cryptographically secure random numbers. This greatly improves the
|
||||
* performance of these tests, especially if they are run before the Linux RNG
|
||||
* has been initialized or if they are run on a lockdep-enabled kernel.
|
||||
*/
|
||||
|
||||
switch (prandom_u32_max(4)) {
|
||||
static inline void init_rnd_state(struct rnd_state *rng)
|
||||
{
|
||||
prandom_seed_state(rng, get_random_u64());
|
||||
}
|
||||
|
||||
static inline u8 prandom_u8(struct rnd_state *rng)
|
||||
{
|
||||
return prandom_u32_state(rng);
|
||||
}
|
||||
|
||||
static inline u32 prandom_u32_below(struct rnd_state *rng, u32 ceil)
|
||||
{
|
||||
/*
|
||||
* This is slightly biased for non-power-of-2 values of 'ceil', but this
|
||||
* isn't important here.
|
||||
*/
|
||||
return prandom_u32_state(rng) % ceil;
|
||||
}
|
||||
|
||||
static inline bool prandom_bool(struct rnd_state *rng)
|
||||
{
|
||||
return prandom_u32_below(rng, 2);
|
||||
}
|
||||
|
||||
static inline u32 prandom_u32_inclusive(struct rnd_state *rng,
|
||||
u32 floor, u32 ceil)
|
||||
{
|
||||
return floor + prandom_u32_below(rng, ceil - floor + 1);
|
||||
}
|
||||
|
||||
/* Generate a random length in range [0, max_len], but prefer smaller values */
|
||||
static unsigned int generate_random_length(struct rnd_state *rng,
|
||||
unsigned int max_len)
|
||||
{
|
||||
unsigned int len = prandom_u32_below(rng, max_len + 1);
|
||||
|
||||
switch (prandom_u32_below(rng, 4)) {
|
||||
case 0:
|
||||
return len % 64;
|
||||
case 1:
|
||||
@ -870,43 +908,44 @@ static unsigned int generate_random_length(unsigned int max_len)
|
||||
}
|
||||
|
||||
/* Flip a random bit in the given nonempty data buffer */
|
||||
static void flip_random_bit(u8 *buf, size_t size)
|
||||
static void flip_random_bit(struct rnd_state *rng, u8 *buf, size_t size)
|
||||
{
|
||||
size_t bitpos;
|
||||
|
||||
bitpos = prandom_u32_max(size * 8);
|
||||
bitpos = prandom_u32_below(rng, size * 8);
|
||||
buf[bitpos / 8] ^= 1 << (bitpos % 8);
|
||||
}
|
||||
|
||||
/* Flip a random byte in the given nonempty data buffer */
|
||||
static void flip_random_byte(u8 *buf, size_t size)
|
||||
static void flip_random_byte(struct rnd_state *rng, u8 *buf, size_t size)
|
||||
{
|
||||
buf[prandom_u32_max(size)] ^= 0xff;
|
||||
buf[prandom_u32_below(rng, size)] ^= 0xff;
|
||||
}
|
||||
|
||||
/* Sometimes make some random changes to the given nonempty data buffer */
|
||||
static void mutate_buffer(u8 *buf, size_t size)
|
||||
static void mutate_buffer(struct rnd_state *rng, u8 *buf, size_t size)
|
||||
{
|
||||
size_t num_flips;
|
||||
size_t i;
|
||||
|
||||
/* Sometimes flip some bits */
|
||||
if (prandom_u32_max(4) == 0) {
|
||||
num_flips = min_t(size_t, 1 << prandom_u32_max(8), size * 8);
|
||||
if (prandom_u32_below(rng, 4) == 0) {
|
||||
num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8),
|
||||
size * 8);
|
||||
for (i = 0; i < num_flips; i++)
|
||||
flip_random_bit(buf, size);
|
||||
flip_random_bit(rng, buf, size);
|
||||
}
|
||||
|
||||
/* Sometimes flip some bytes */
|
||||
if (prandom_u32_max(4) == 0) {
|
||||
num_flips = min_t(size_t, 1 << prandom_u32_max(8), size);
|
||||
if (prandom_u32_below(rng, 4) == 0) {
|
||||
num_flips = min_t(size_t, 1 << prandom_u32_below(rng, 8), size);
|
||||
for (i = 0; i < num_flips; i++)
|
||||
flip_random_byte(buf, size);
|
||||
flip_random_byte(rng, buf, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Randomly generate 'count' bytes, but sometimes make them "interesting" */
|
||||
static void generate_random_bytes(u8 *buf, size_t count)
|
||||
static void generate_random_bytes(struct rnd_state *rng, u8 *buf, size_t count)
|
||||
{
|
||||
u8 b;
|
||||
u8 increment;
|
||||
@ -915,11 +954,11 @@ static void generate_random_bytes(u8 *buf, size_t count)
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
switch (prandom_u32_max(8)) { /* Choose a generation strategy */
|
||||
switch (prandom_u32_below(rng, 8)) { /* Choose a generation strategy */
|
||||
case 0:
|
||||
case 1:
|
||||
/* All the same byte, plus optional mutations */
|
||||
switch (prandom_u32_max(4)) {
|
||||
switch (prandom_u32_below(rng, 4)) {
|
||||
case 0:
|
||||
b = 0x00;
|
||||
break;
|
||||
@ -927,28 +966,28 @@ static void generate_random_bytes(u8 *buf, size_t count)
|
||||
b = 0xff;
|
||||
break;
|
||||
default:
|
||||
b = get_random_u8();
|
||||
b = prandom_u8(rng);
|
||||
break;
|
||||
}
|
||||
memset(buf, b, count);
|
||||
mutate_buffer(buf, count);
|
||||
mutate_buffer(rng, buf, count);
|
||||
break;
|
||||
case 2:
|
||||
/* Ascending or descending bytes, plus optional mutations */
|
||||
increment = get_random_u8();
|
||||
b = get_random_u8();
|
||||
increment = prandom_u8(rng);
|
||||
b = prandom_u8(rng);
|
||||
for (i = 0; i < count; i++, b += increment)
|
||||
buf[i] = b;
|
||||
mutate_buffer(buf, count);
|
||||
mutate_buffer(rng, buf, count);
|
||||
break;
|
||||
default:
|
||||
/* Fully random bytes */
|
||||
for (i = 0; i < count; i++)
|
||||
buf[i] = get_random_u8();
|
||||
prandom_bytes_state(rng, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
||||
static char *generate_random_sgl_divisions(struct rnd_state *rng,
|
||||
struct test_sg_division *divs,
|
||||
size_t max_divs, char *p, char *end,
|
||||
bool gen_flushes, u32 req_flags)
|
||||
{
|
||||
@ -959,24 +998,26 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
||||
unsigned int this_len;
|
||||
const char *flushtype_str;
|
||||
|
||||
if (div == &divs[max_divs - 1] || prandom_u32_max(2) == 0)
|
||||
if (div == &divs[max_divs - 1] || prandom_bool(rng))
|
||||
this_len = remaining;
|
||||
else
|
||||
this_len = 1 + prandom_u32_max(remaining);
|
||||
this_len = prandom_u32_inclusive(rng, 1, remaining);
|
||||
div->proportion_of_total = this_len;
|
||||
|
||||
if (prandom_u32_max(4) == 0)
|
||||
div->offset = (PAGE_SIZE - 128) + prandom_u32_max(128);
|
||||
else if (prandom_u32_max(2) == 0)
|
||||
div->offset = prandom_u32_max(32);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
div->offset = prandom_u32_inclusive(rng,
|
||||
PAGE_SIZE - 128,
|
||||
PAGE_SIZE - 1);
|
||||
else if (prandom_bool(rng))
|
||||
div->offset = prandom_u32_below(rng, 32);
|
||||
else
|
||||
div->offset = prandom_u32_max(PAGE_SIZE);
|
||||
if (prandom_u32_max(8) == 0)
|
||||
div->offset = prandom_u32_below(rng, PAGE_SIZE);
|
||||
if (prandom_u32_below(rng, 8) == 0)
|
||||
div->offset_relative_to_alignmask = true;
|
||||
|
||||
div->flush_type = FLUSH_TYPE_NONE;
|
||||
if (gen_flushes) {
|
||||
switch (prandom_u32_max(4)) {
|
||||
switch (prandom_u32_below(rng, 4)) {
|
||||
case 0:
|
||||
div->flush_type = FLUSH_TYPE_REIMPORT;
|
||||
break;
|
||||
@ -988,7 +1029,7 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
||||
|
||||
if (div->flush_type != FLUSH_TYPE_NONE &&
|
||||
!(req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
|
||||
prandom_u32_max(2) == 0)
|
||||
prandom_bool(rng))
|
||||
div->nosimd = true;
|
||||
|
||||
switch (div->flush_type) {
|
||||
@ -1023,7 +1064,8 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
|
||||
}
|
||||
|
||||
/* Generate a random testvec_config for fuzz testing */
|
||||
static void generate_random_testvec_config(struct testvec_config *cfg,
|
||||
static void generate_random_testvec_config(struct rnd_state *rng,
|
||||
struct testvec_config *cfg,
|
||||
char *name, size_t max_namelen)
|
||||
{
|
||||
char *p = name;
|
||||
@ -1035,7 +1077,7 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
|
||||
|
||||
p += scnprintf(p, end - p, "random:");
|
||||
|
||||
switch (prandom_u32_max(4)) {
|
||||
switch (prandom_u32_below(rng, 4)) {
|
||||
case 0:
|
||||
case 1:
|
||||
cfg->inplace_mode = OUT_OF_PLACE;
|
||||
@ -1050,12 +1092,12 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
|
||||
break;
|
||||
}
|
||||
|
||||
if (prandom_u32_max(2) == 0) {
|
||||
if (prandom_bool(rng)) {
|
||||
cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
p += scnprintf(p, end - p, " may_sleep");
|
||||
}
|
||||
|
||||
switch (prandom_u32_max(4)) {
|
||||
switch (prandom_u32_below(rng, 4)) {
|
||||
case 0:
|
||||
cfg->finalization_type = FINALIZATION_TYPE_FINAL;
|
||||
p += scnprintf(p, end - p, " use_final");
|
||||
@ -1070,36 +1112,37 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
|
||||
prandom_u32_max(2) == 0) {
|
||||
if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) && prandom_bool(rng)) {
|
||||
cfg->nosimd = true;
|
||||
p += scnprintf(p, end - p, " nosimd");
|
||||
}
|
||||
|
||||
p += scnprintf(p, end - p, " src_divs=[");
|
||||
p = generate_random_sgl_divisions(cfg->src_divs,
|
||||
p = generate_random_sgl_divisions(rng, cfg->src_divs,
|
||||
ARRAY_SIZE(cfg->src_divs), p, end,
|
||||
(cfg->finalization_type !=
|
||||
FINALIZATION_TYPE_DIGEST),
|
||||
cfg->req_flags);
|
||||
p += scnprintf(p, end - p, "]");
|
||||
|
||||
if (cfg->inplace_mode == OUT_OF_PLACE && prandom_u32_max(2) == 0) {
|
||||
if (cfg->inplace_mode == OUT_OF_PLACE && prandom_bool(rng)) {
|
||||
p += scnprintf(p, end - p, " dst_divs=[");
|
||||
p = generate_random_sgl_divisions(cfg->dst_divs,
|
||||
p = generate_random_sgl_divisions(rng, cfg->dst_divs,
|
||||
ARRAY_SIZE(cfg->dst_divs),
|
||||
p, end, false,
|
||||
cfg->req_flags);
|
||||
p += scnprintf(p, end - p, "]");
|
||||
}
|
||||
|
||||
if (prandom_u32_max(2) == 0) {
|
||||
cfg->iv_offset = 1 + prandom_u32_max(MAX_ALGAPI_ALIGNMASK);
|
||||
if (prandom_bool(rng)) {
|
||||
cfg->iv_offset = prandom_u32_inclusive(rng, 1,
|
||||
MAX_ALGAPI_ALIGNMASK);
|
||||
p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset);
|
||||
}
|
||||
|
||||
if (prandom_u32_max(2) == 0) {
|
||||
cfg->key_offset = 1 + prandom_u32_max(MAX_ALGAPI_ALIGNMASK);
|
||||
if (prandom_bool(rng)) {
|
||||
cfg->key_offset = prandom_u32_inclusive(rng, 1,
|
||||
MAX_ALGAPI_ALIGNMASK);
|
||||
p += scnprintf(p, end - p, " key_offset=%u", cfg->key_offset);
|
||||
}
|
||||
|
||||
@ -1612,11 +1655,14 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
if (!noextratests) {
|
||||
struct rnd_state rng;
|
||||
struct testvec_config cfg;
|
||||
char cfgname[TESTVEC_CONFIG_NAMELEN];
|
||||
|
||||
init_rnd_state(&rng);
|
||||
|
||||
for (i = 0; i < fuzz_iterations; i++) {
|
||||
generate_random_testvec_config(&cfg, cfgname,
|
||||
generate_random_testvec_config(&rng, &cfg, cfgname,
|
||||
sizeof(cfgname));
|
||||
err = test_hash_vec_cfg(vec, vec_name, &cfg,
|
||||
req, desc, tsgl, hashstate);
|
||||
@ -1634,15 +1680,16 @@ static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
|
||||
* Generate a hash test vector from the given implementation.
|
||||
* Assumes the buffers in 'vec' were already allocated.
|
||||
*/
|
||||
static void generate_random_hash_testvec(struct shash_desc *desc,
|
||||
static void generate_random_hash_testvec(struct rnd_state *rng,
|
||||
struct shash_desc *desc,
|
||||
struct hash_testvec *vec,
|
||||
unsigned int maxkeysize,
|
||||
unsigned int maxdatasize,
|
||||
char *name, size_t max_namelen)
|
||||
{
|
||||
/* Data */
|
||||
vec->psize = generate_random_length(maxdatasize);
|
||||
generate_random_bytes((u8 *)vec->plaintext, vec->psize);
|
||||
vec->psize = generate_random_length(rng, maxdatasize);
|
||||
generate_random_bytes(rng, (u8 *)vec->plaintext, vec->psize);
|
||||
|
||||
/*
|
||||
* Key: length in range [1, maxkeysize], but usually choose maxkeysize.
|
||||
@ -1652,9 +1699,9 @@ static void generate_random_hash_testvec(struct shash_desc *desc,
|
||||
vec->ksize = 0;
|
||||
if (maxkeysize) {
|
||||
vec->ksize = maxkeysize;
|
||||
if (prandom_u32_max(4) == 0)
|
||||
vec->ksize = 1 + prandom_u32_max(maxkeysize);
|
||||
generate_random_bytes((u8 *)vec->key, vec->ksize);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
vec->ksize = prandom_u32_inclusive(rng, 1, maxkeysize);
|
||||
generate_random_bytes(rng, (u8 *)vec->key, vec->ksize);
|
||||
|
||||
vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key,
|
||||
vec->ksize);
|
||||
@ -1688,6 +1735,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
|
||||
const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
|
||||
const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
|
||||
const char *driver = crypto_ahash_driver_name(tfm);
|
||||
struct rnd_state rng;
|
||||
char _generic_driver[CRYPTO_MAX_ALG_NAME];
|
||||
struct crypto_shash *generic_tfm = NULL;
|
||||
struct shash_desc *generic_desc = NULL;
|
||||
@ -1701,6 +1749,8 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
|
||||
if (noextratests)
|
||||
return 0;
|
||||
|
||||
init_rnd_state(&rng);
|
||||
|
||||
if (!generic_driver) { /* Use default naming convention? */
|
||||
err = build_generic_driver_name(algname, _generic_driver);
|
||||
if (err)
|
||||
@ -1769,10 +1819,11 @@ static int test_hash_vs_generic_impl(const char *generic_driver,
|
||||
}
|
||||
|
||||
for (i = 0; i < fuzz_iterations * 8; i++) {
|
||||
generate_random_hash_testvec(generic_desc, &vec,
|
||||
generate_random_hash_testvec(&rng, generic_desc, &vec,
|
||||
maxkeysize, maxdatasize,
|
||||
vec_name, sizeof(vec_name));
|
||||
generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
|
||||
generate_random_testvec_config(&rng, cfg, cfgname,
|
||||
sizeof(cfgname));
|
||||
|
||||
err = test_hash_vec_cfg(&vec, vec_name, cfg,
|
||||
req, desc, tsgl, hashstate);
|
||||
@ -2174,11 +2225,14 @@ static int test_aead_vec(int enc, const struct aead_testvec *vec,
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
if (!noextratests) {
|
||||
struct rnd_state rng;
|
||||
struct testvec_config cfg;
|
||||
char cfgname[TESTVEC_CONFIG_NAMELEN];
|
||||
|
||||
init_rnd_state(&rng);
|
||||
|
||||
for (i = 0; i < fuzz_iterations; i++) {
|
||||
generate_random_testvec_config(&cfg, cfgname,
|
||||
generate_random_testvec_config(&rng, &cfg, cfgname,
|
||||
sizeof(cfgname));
|
||||
err = test_aead_vec_cfg(enc, vec, vec_name,
|
||||
&cfg, req, tsgls);
|
||||
@ -2194,6 +2248,7 @@ static int test_aead_vec(int enc, const struct aead_testvec *vec,
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
|
||||
struct aead_extra_tests_ctx {
|
||||
struct rnd_state rng;
|
||||
struct aead_request *req;
|
||||
struct crypto_aead *tfm;
|
||||
const struct alg_test_desc *test_desc;
|
||||
@ -2212,24 +2267,26 @@ struct aead_extra_tests_ctx {
|
||||
* here means the full ciphertext including the authentication tag. The
|
||||
* authentication tag (and hence also the ciphertext) is assumed to be nonempty.
|
||||
*/
|
||||
static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
|
||||
static void mutate_aead_message(struct rnd_state *rng,
|
||||
struct aead_testvec *vec, bool aad_iv,
|
||||
unsigned int ivsize)
|
||||
{
|
||||
const unsigned int aad_tail_size = aad_iv ? ivsize : 0;
|
||||
const unsigned int authsize = vec->clen - vec->plen;
|
||||
|
||||
if (prandom_u32_max(2) == 0 && vec->alen > aad_tail_size) {
|
||||
if (prandom_bool(rng) && vec->alen > aad_tail_size) {
|
||||
/* Mutate the AAD */
|
||||
flip_random_bit((u8 *)vec->assoc, vec->alen - aad_tail_size);
|
||||
if (prandom_u32_max(2) == 0)
|
||||
flip_random_bit(rng, (u8 *)vec->assoc,
|
||||
vec->alen - aad_tail_size);
|
||||
if (prandom_bool(rng))
|
||||
return;
|
||||
}
|
||||
if (prandom_u32_max(2) == 0) {
|
||||
if (prandom_bool(rng)) {
|
||||
/* Mutate auth tag (assuming it's at the end of ciphertext) */
|
||||
flip_random_bit((u8 *)vec->ctext + vec->plen, authsize);
|
||||
flip_random_bit(rng, (u8 *)vec->ctext + vec->plen, authsize);
|
||||
} else {
|
||||
/* Mutate any part of the ciphertext */
|
||||
flip_random_bit((u8 *)vec->ctext, vec->clen);
|
||||
flip_random_bit(rng, (u8 *)vec->ctext, vec->clen);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2240,7 +2297,8 @@ static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
|
||||
*/
|
||||
#define MIN_COLLISION_FREE_AUTHSIZE 8
|
||||
|
||||
static void generate_aead_message(struct aead_request *req,
|
||||
static void generate_aead_message(struct rnd_state *rng,
|
||||
struct aead_request *req,
|
||||
const struct aead_test_suite *suite,
|
||||
struct aead_testvec *vec,
|
||||
bool prefer_inauthentic)
|
||||
@ -2249,17 +2307,18 @@ static void generate_aead_message(struct aead_request *req,
|
||||
const unsigned int ivsize = crypto_aead_ivsize(tfm);
|
||||
const unsigned int authsize = vec->clen - vec->plen;
|
||||
const bool inauthentic = (authsize >= MIN_COLLISION_FREE_AUTHSIZE) &&
|
||||
(prefer_inauthentic || prandom_u32_max(4) == 0);
|
||||
(prefer_inauthentic ||
|
||||
prandom_u32_below(rng, 4) == 0);
|
||||
|
||||
/* Generate the AAD. */
|
||||
generate_random_bytes((u8 *)vec->assoc, vec->alen);
|
||||
generate_random_bytes(rng, (u8 *)vec->assoc, vec->alen);
|
||||
if (suite->aad_iv && vec->alen >= ivsize)
|
||||
/* Avoid implementation-defined behavior. */
|
||||
memcpy((u8 *)vec->assoc + vec->alen - ivsize, vec->iv, ivsize);
|
||||
|
||||
if (inauthentic && prandom_u32_max(2) == 0) {
|
||||
if (inauthentic && prandom_bool(rng)) {
|
||||
/* Generate a random ciphertext. */
|
||||
generate_random_bytes((u8 *)vec->ctext, vec->clen);
|
||||
generate_random_bytes(rng, (u8 *)vec->ctext, vec->clen);
|
||||
} else {
|
||||
int i = 0;
|
||||
struct scatterlist src[2], dst;
|
||||
@ -2271,7 +2330,7 @@ static void generate_aead_message(struct aead_request *req,
|
||||
if (vec->alen)
|
||||
sg_set_buf(&src[i++], vec->assoc, vec->alen);
|
||||
if (vec->plen) {
|
||||
generate_random_bytes((u8 *)vec->ptext, vec->plen);
|
||||
generate_random_bytes(rng, (u8 *)vec->ptext, vec->plen);
|
||||
sg_set_buf(&src[i++], vec->ptext, vec->plen);
|
||||
}
|
||||
sg_init_one(&dst, vec->ctext, vec->alen + vec->clen);
|
||||
@ -2291,7 +2350,7 @@ static void generate_aead_message(struct aead_request *req,
|
||||
* Mutate the authentic (ciphertext, AAD) pair to get an
|
||||
* inauthentic one.
|
||||
*/
|
||||
mutate_aead_message(vec, suite->aad_iv, ivsize);
|
||||
mutate_aead_message(rng, vec, suite->aad_iv, ivsize);
|
||||
}
|
||||
vec->novrfy = 1;
|
||||
if (suite->einval_allowed)
|
||||
@ -2305,7 +2364,8 @@ static void generate_aead_message(struct aead_request *req,
|
||||
* If 'prefer_inauthentic' is true, then this function will generate inauthentic
|
||||
* test vectors (i.e. vectors with 'vec->novrfy=1') more often.
|
||||
*/
|
||||
static void generate_random_aead_testvec(struct aead_request *req,
|
||||
static void generate_random_aead_testvec(struct rnd_state *rng,
|
||||
struct aead_request *req,
|
||||
struct aead_testvec *vec,
|
||||
const struct aead_test_suite *suite,
|
||||
unsigned int maxkeysize,
|
||||
@ -2321,18 +2381,18 @@ static void generate_random_aead_testvec(struct aead_request *req,
|
||||
|
||||
/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
|
||||
vec->klen = maxkeysize;
|
||||
if (prandom_u32_max(4) == 0)
|
||||
vec->klen = prandom_u32_max(maxkeysize + 1);
|
||||
generate_random_bytes((u8 *)vec->key, vec->klen);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
vec->klen = prandom_u32_below(rng, maxkeysize + 1);
|
||||
generate_random_bytes(rng, (u8 *)vec->key, vec->klen);
|
||||
vec->setkey_error = crypto_aead_setkey(tfm, vec->key, vec->klen);
|
||||
|
||||
/* IV */
|
||||
generate_random_bytes((u8 *)vec->iv, ivsize);
|
||||
generate_random_bytes(rng, (u8 *)vec->iv, ivsize);
|
||||
|
||||
/* Tag length: in [0, maxauthsize], but usually choose maxauthsize */
|
||||
authsize = maxauthsize;
|
||||
if (prandom_u32_max(4) == 0)
|
||||
authsize = prandom_u32_max(maxauthsize + 1);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
authsize = prandom_u32_below(rng, maxauthsize + 1);
|
||||
if (prefer_inauthentic && authsize < MIN_COLLISION_FREE_AUTHSIZE)
|
||||
authsize = MIN_COLLISION_FREE_AUTHSIZE;
|
||||
if (WARN_ON(authsize > maxdatasize))
|
||||
@ -2341,11 +2401,11 @@ static void generate_random_aead_testvec(struct aead_request *req,
|
||||
vec->setauthsize_error = crypto_aead_setauthsize(tfm, authsize);
|
||||
|
||||
/* AAD, plaintext, and ciphertext lengths */
|
||||
total_len = generate_random_length(maxdatasize);
|
||||
if (prandom_u32_max(4) == 0)
|
||||
total_len = generate_random_length(rng, maxdatasize);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
vec->alen = 0;
|
||||
else
|
||||
vec->alen = generate_random_length(total_len);
|
||||
vec->alen = generate_random_length(rng, total_len);
|
||||
vec->plen = total_len - vec->alen;
|
||||
vec->clen = vec->plen + authsize;
|
||||
|
||||
@ -2356,7 +2416,7 @@ static void generate_random_aead_testvec(struct aead_request *req,
|
||||
vec->novrfy = 0;
|
||||
vec->crypt_error = 0;
|
||||
if (vec->setkey_error == 0 && vec->setauthsize_error == 0)
|
||||
generate_aead_message(req, suite, vec, prefer_inauthentic);
|
||||
generate_aead_message(rng, req, suite, vec, prefer_inauthentic);
|
||||
snprintf(name, max_namelen,
|
||||
"\"random: alen=%u plen=%u authsize=%u klen=%u novrfy=%d\"",
|
||||
vec->alen, vec->plen, authsize, vec->klen, vec->novrfy);
|
||||
@ -2368,7 +2428,7 @@ static void try_to_generate_inauthentic_testvec(
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
generate_random_aead_testvec(ctx->req, &ctx->vec,
|
||||
generate_random_aead_testvec(&ctx->rng, ctx->req, &ctx->vec,
|
||||
&ctx->test_desc->suite.aead,
|
||||
ctx->maxkeysize, ctx->maxdatasize,
|
||||
ctx->vec_name,
|
||||
@ -2399,7 +2459,8 @@ static int test_aead_inauthentic_inputs(struct aead_extra_tests_ctx *ctx)
|
||||
*/
|
||||
try_to_generate_inauthentic_testvec(ctx);
|
||||
if (ctx->vec.novrfy) {
|
||||
generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
|
||||
generate_random_testvec_config(&ctx->rng, &ctx->cfg,
|
||||
ctx->cfgname,
|
||||
sizeof(ctx->cfgname));
|
||||
err = test_aead_vec_cfg(DECRYPT, &ctx->vec,
|
||||
ctx->vec_name, &ctx->cfg,
|
||||
@ -2489,12 +2550,13 @@ static int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx)
|
||||
* the other implementation against them.
|
||||
*/
|
||||
for (i = 0; i < fuzz_iterations * 8; i++) {
|
||||
generate_random_aead_testvec(generic_req, &ctx->vec,
|
||||
generate_random_aead_testvec(&ctx->rng, generic_req, &ctx->vec,
|
||||
&ctx->test_desc->suite.aead,
|
||||
ctx->maxkeysize, ctx->maxdatasize,
|
||||
ctx->vec_name,
|
||||
sizeof(ctx->vec_name), false);
|
||||
generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
|
||||
generate_random_testvec_config(&ctx->rng, &ctx->cfg,
|
||||
ctx->cfgname,
|
||||
sizeof(ctx->cfgname));
|
||||
if (!ctx->vec.novrfy) {
|
||||
err = test_aead_vec_cfg(ENCRYPT, &ctx->vec,
|
||||
@ -2533,6 +2595,7 @@ static int test_aead_extra(const struct alg_test_desc *test_desc,
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
init_rnd_state(&ctx->rng);
|
||||
ctx->req = req;
|
||||
ctx->tfm = crypto_aead_reqtfm(req);
|
||||
ctx->test_desc = test_desc;
|
||||
@ -2922,11 +2985,14 @@ static int test_skcipher_vec(int enc, const struct cipher_testvec *vec,
|
||||
|
||||
#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
|
||||
if (!noextratests) {
|
||||
struct rnd_state rng;
|
||||
struct testvec_config cfg;
|
||||
char cfgname[TESTVEC_CONFIG_NAMELEN];
|
||||
|
||||
init_rnd_state(&rng);
|
||||
|
||||
for (i = 0; i < fuzz_iterations; i++) {
|
||||
generate_random_testvec_config(&cfg, cfgname,
|
||||
generate_random_testvec_config(&rng, &cfg, cfgname,
|
||||
sizeof(cfgname));
|
||||
err = test_skcipher_vec_cfg(enc, vec, vec_name,
|
||||
&cfg, req, tsgls);
|
||||
@ -2944,7 +3010,8 @@ static int test_skcipher_vec(int enc, const struct cipher_testvec *vec,
|
||||
* Generate a symmetric cipher test vector from the given implementation.
|
||||
* Assumes the buffers in 'vec' were already allocated.
|
||||
*/
|
||||
static void generate_random_cipher_testvec(struct skcipher_request *req,
|
||||
static void generate_random_cipher_testvec(struct rnd_state *rng,
|
||||
struct skcipher_request *req,
|
||||
struct cipher_testvec *vec,
|
||||
unsigned int maxdatasize,
|
||||
char *name, size_t max_namelen)
|
||||
@ -2958,17 +3025,17 @@ static void generate_random_cipher_testvec(struct skcipher_request *req,
|
||||
|
||||
/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
|
||||
vec->klen = maxkeysize;
|
||||
if (prandom_u32_max(4) == 0)
|
||||
vec->klen = prandom_u32_max(maxkeysize + 1);
|
||||
generate_random_bytes((u8 *)vec->key, vec->klen);
|
||||
if (prandom_u32_below(rng, 4) == 0)
|
||||
vec->klen = prandom_u32_below(rng, maxkeysize + 1);
|
||||
generate_random_bytes(rng, (u8 *)vec->key, vec->klen);
|
||||
vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen);
|
||||
|
||||
/* IV */
|
||||
generate_random_bytes((u8 *)vec->iv, ivsize);
|
||||
generate_random_bytes(rng, (u8 *)vec->iv, ivsize);
|
||||
|
||||
/* Plaintext */
|
||||
vec->len = generate_random_length(maxdatasize);
|
||||
generate_random_bytes((u8 *)vec->ptext, vec->len);
|
||||
vec->len = generate_random_length(rng, maxdatasize);
|
||||
generate_random_bytes(rng, (u8 *)vec->ptext, vec->len);
|
||||
|
||||
/* If the key couldn't be set, no need to continue to encrypt. */
|
||||
if (vec->setkey_error)
|
||||
@ -3010,6 +3077,7 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
|
||||
const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
|
||||
const char *algname = crypto_skcipher_alg(tfm)->base.cra_name;
|
||||
const char *driver = crypto_skcipher_driver_name(tfm);
|
||||
struct rnd_state rng;
|
||||
char _generic_driver[CRYPTO_MAX_ALG_NAME];
|
||||
struct crypto_skcipher *generic_tfm = NULL;
|
||||
struct skcipher_request *generic_req = NULL;
|
||||
@ -3027,6 +3095,8 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
|
||||
if (strncmp(algname, "kw(", 3) == 0)
|
||||
return 0;
|
||||
|
||||
init_rnd_state(&rng);
|
||||
|
||||
if (!generic_driver) { /* Use default naming convention? */
|
||||
err = build_generic_driver_name(algname, _generic_driver);
|
||||
if (err)
|
||||
@ -3111,9 +3181,11 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver,
|
||||
}
|
||||
|
||||
for (i = 0; i < fuzz_iterations * 8; i++) {
|
||||
generate_random_cipher_testvec(generic_req, &vec, maxdatasize,
|
||||
generate_random_cipher_testvec(&rng, generic_req, &vec,
|
||||
maxdatasize,
|
||||
vec_name, sizeof(vec_name));
|
||||
generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
|
||||
generate_random_testvec_config(&rng, cfg, cfgname,
|
||||
sizeof(cfgname));
|
||||
|
||||
err = test_skcipher_vec_cfg(ENCRYPT, &vec, vec_name,
|
||||
cfg, req, tsgls);
|
||||
|
@ -83,6 +83,8 @@ static int fch_misc_setup(struct apd_private_data *pdata)
|
||||
if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
|
||||
clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
|
||||
GFP_KERNEL);
|
||||
if (!clk_data->name)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(clk_data->name, obj->string.pointer);
|
||||
} else {
|
||||
|
@ -652,6 +652,9 @@ acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
|
||||
object_info =
|
||||
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
|
||||
|
||||
if (!object_info)
|
||||
return (AE_NO_MEMORY);
|
||||
|
||||
/* Walk the namespace from the root */
|
||||
|
||||
(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
|
||||
|
@ -576,9 +576,14 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
|
||||
ACPI_FUNCTION_TRACE(ds_init_aml_walk);
|
||||
|
||||
walk_state->parser_state.aml =
|
||||
walk_state->parser_state.aml_start = aml_start;
|
||||
walk_state->parser_state.aml_end =
|
||||
walk_state->parser_state.pkg_end = aml_start + aml_length;
|
||||
walk_state->parser_state.aml_start =
|
||||
walk_state->parser_state.aml_end =
|
||||
walk_state->parser_state.pkg_end = aml_start;
|
||||
/* Avoid undefined behavior: applying zero offset to null pointer */
|
||||
if (aml_length != 0) {
|
||||
walk_state->parser_state.aml_end += aml_length;
|
||||
walk_state->parser_state.pkg_end += aml_length;
|
||||
}
|
||||
|
||||
/* The next_op of the next_walk will be the beginning of the method */
|
||||
|
||||
|
@ -1121,6 +1121,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,
|
||||
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
|
||||
{
|
||||
acpi_ec_remove_query_handlers(ec, false, query_bit);
|
||||
flush_workqueue(ec_query_wq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
|
||||
|
||||
|
@ -130,12 +130,6 @@ static int video_detect_force_native(const struct dmi_system_id *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int video_detect_force_none(const struct dmi_system_id *d)
|
||||
{
|
||||
acpi_backlight_dmi = acpi_backlight_none;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
/*
|
||||
* Models which should use the vendor backlight interface,
|
||||
@ -752,35 +746,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* Desktops which falsely report a backlight and which our heuristics
|
||||
* for this do not catch.
|
||||
*/
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
/* Dell OptiPlex 9020M */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
/* GIGABYTE GB-BXBT-2807 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_none,
|
||||
/* MSI MS-7721 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
|
||||
},
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -1416,7 +1416,9 @@ static void platform_remove(struct device *_dev)
|
||||
struct platform_driver *drv = to_platform_driver(_dev->driver);
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
|
||||
if (drv->remove) {
|
||||
if (drv->remove_new) {
|
||||
drv->remove_new(dev);
|
||||
} else if (drv->remove) {
|
||||
int ret = drv->remove(dev);
|
||||
|
||||
if (ret)
|
||||
|
@ -349,6 +349,9 @@ int regcache_sync(struct regmap *map)
|
||||
const char *name;
|
||||
bool bypass;
|
||||
|
||||
if (WARN_ON(map->cache_type == REGCACHE_NONE))
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(!map->cache_ops);
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
@ -418,6 +421,9 @@ int regcache_sync_region(struct regmap *map, unsigned int min,
|
||||
const char *name;
|
||||
bool bypass;
|
||||
|
||||
if (WARN_ON(map->cache_type == REGCACHE_NONE))
|
||||
return -EINVAL;
|
||||
|
||||
BUG_ON(!map->cache_ops);
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
|
@ -325,6 +325,9 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize,
|
||||
if (blk_validate_block_size(blksize))
|
||||
return -EINVAL;
|
||||
|
||||
if (bytesize < 0)
|
||||
return -EINVAL;
|
||||
|
||||
nbd->config->bytesize = bytesize;
|
||||
nbd->config->blksize_bits = __ffs(blksize);
|
||||
|
||||
@ -1110,6 +1113,9 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
|
||||
struct nbd_sock *nsock;
|
||||
int err;
|
||||
|
||||
/* Arg will be cast to int, check it to avoid overflow */
|
||||
if (arg > INT_MAX)
|
||||
return -EINVAL;
|
||||
sock = nbd_get_socket(nbd, arg, &err);
|
||||
if (!sock)
|
||||
return err;
|
||||
|
@ -1945,6 +1945,11 @@ static int null_init_tag_set(struct nullb *nullb, struct blk_mq_tag_set *set)
|
||||
|
||||
static int null_validate_conf(struct nullb_device *dev)
|
||||
{
|
||||
if (dev->queue_mode == NULL_Q_RQ) {
|
||||
pr_err("legacy IO path is no longer available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev->blocksize = round_down(dev->blocksize, 512);
|
||||
dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Copyright (C) 2015 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/dmi.h>
|
||||
@ -34,6 +35,43 @@
|
||||
/* For kmalloc-ing the fw-name array instead of putting it on the stack */
|
||||
typedef char bcm_fw_name[BCM_FW_NAME_LEN];
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
|
||||
{
|
||||
efi_guid_t guid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61, 0xb5, 0x1f,
|
||||
0x43, 0x26, 0x81, 0x23, 0xd1, 0x13);
|
||||
bdaddr_t efi_bdaddr, bdaddr;
|
||||
efi_status_t status;
|
||||
unsigned long len;
|
||||
int ret;
|
||||
|
||||
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
len = sizeof(efi_bdaddr);
|
||||
status = efi.get_variable(L"BDADDR", &guid, NULL, &len, &efi_bdaddr);
|
||||
if (status != EFI_SUCCESS)
|
||||
return -ENXIO;
|
||||
|
||||
if (len != sizeof(efi_bdaddr))
|
||||
return -EIO;
|
||||
|
||||
baswap(&bdaddr, &efi_bdaddr);
|
||||
|
||||
ret = btbcm_set_bdaddr(hdev, &bdaddr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bt_dev_info(hdev, "BCM: Using EFI device address (%pMR)", &bdaddr);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
int btbcm_check_bdaddr(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_rp_read_bd_addr *bda;
|
||||
@ -87,9 +125,12 @@ int btbcm_check_bdaddr(struct hci_dev *hdev)
|
||||
!bacmp(&bda->bdaddr, BDADDR_BCM4345C5) ||
|
||||
!bacmp(&bda->bdaddr, BDADDR_BCM43430A0) ||
|
||||
!bacmp(&bda->bdaddr, BDADDR_BCM43341B)) {
|
||||
bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
|
||||
&bda->bdaddr);
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
/* Try falling back to BDADDR EFI variable */
|
||||
if (btbcm_set_bdaddr_from_efi(hdev) != 0) {
|
||||
bt_dev_info(hdev, "BCM: Using default device address (%pMR)",
|
||||
&bda->bdaddr);
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
}
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
|
@ -2553,9 +2553,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
*/
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* Valid LE States quirk for GfP */
|
||||
if (INTEL_HW_VARIANT(ver_tlv.cnvi_bt) == 0x18)
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
/* Apply LE States quirk from solar onwards */
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
|
||||
/* Setup MSFT Extension support */
|
||||
btintel_set_msft_opcode(hdev,
|
||||
|
@ -17,19 +17,25 @@
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
#define RTL_CHIP_8723CS_CG 3
|
||||
#define RTL_CHIP_8723CS_VF 4
|
||||
#define RTL_CHIP_8723CS_XX 5
|
||||
#define RTL_EPATCH_SIGNATURE "Realtech"
|
||||
#define RTL_ROM_LMP_8703B 0x8703
|
||||
#define RTL_ROM_LMP_8723A 0x1200
|
||||
#define RTL_ROM_LMP_8723B 0x8723
|
||||
#define RTL_ROM_LMP_8821A 0x8821
|
||||
#define RTL_ROM_LMP_8761A 0x8761
|
||||
#define RTL_ROM_LMP_8822B 0x8822
|
||||
#define RTL_ROM_LMP_8852A 0x8852
|
||||
#define RTL_ROM_LMP_8851B 0x8851
|
||||
#define RTL_CONFIG_MAGIC 0x8723ab55
|
||||
|
||||
#define IC_MATCH_FL_LMPSUBV (1 << 0)
|
||||
#define IC_MATCH_FL_HCIREV (1 << 1)
|
||||
#define IC_MATCH_FL_HCIVER (1 << 2)
|
||||
#define IC_MATCH_FL_HCIBUS (1 << 3)
|
||||
#define IC_MATCH_FL_CHIP_TYPE (1 << 4)
|
||||
#define IC_INFO(lmps, hcir, hciv, bus) \
|
||||
.match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV | \
|
||||
IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS, \
|
||||
@ -51,6 +57,7 @@ enum btrtl_chip_id {
|
||||
CHIP_ID_8852A = 18,
|
||||
CHIP_ID_8852B = 20,
|
||||
CHIP_ID_8852C = 25,
|
||||
CHIP_ID_8851B = 36,
|
||||
};
|
||||
|
||||
struct id_table {
|
||||
@ -59,6 +66,7 @@ struct id_table {
|
||||
__u16 hci_rev;
|
||||
__u8 hci_ver;
|
||||
__u8 hci_bus;
|
||||
__u8 chip_type;
|
||||
bool config_needed;
|
||||
bool has_rom_version;
|
||||
bool has_msft_ext;
|
||||
@ -99,6 +107,39 @@ static const struct id_table ic_id_table[] = {
|
||||
.fw_name = "rtl_bt/rtl8723b_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723b_config" },
|
||||
|
||||
/* 8723CS-CG */
|
||||
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
IC_MATCH_FL_HCIBUS,
|
||||
.lmp_subver = RTL_ROM_LMP_8703B,
|
||||
.chip_type = RTL_CHIP_8723CS_CG,
|
||||
.hci_bus = HCI_UART,
|
||||
.config_needed = true,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8723cs_cg_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723cs_cg_config" },
|
||||
|
||||
/* 8723CS-VF */
|
||||
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
IC_MATCH_FL_HCIBUS,
|
||||
.lmp_subver = RTL_ROM_LMP_8703B,
|
||||
.chip_type = RTL_CHIP_8723CS_VF,
|
||||
.hci_bus = HCI_UART,
|
||||
.config_needed = true,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8723cs_vf_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723cs_vf_config" },
|
||||
|
||||
/* 8723CS-XX */
|
||||
{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
IC_MATCH_FL_HCIBUS,
|
||||
.lmp_subver = RTL_ROM_LMP_8703B,
|
||||
.chip_type = RTL_CHIP_8723CS_XX,
|
||||
.hci_bus = HCI_UART,
|
||||
.config_needed = true,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8723cs_xx_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723cs_xx_config" },
|
||||
|
||||
/* 8723D */
|
||||
{ IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB),
|
||||
.config_needed = true,
|
||||
@ -205,10 +246,19 @@ static const struct id_table ic_id_table[] = {
|
||||
.has_msft_ext = true,
|
||||
.fw_name = "rtl_bt/rtl8852cu_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8852cu_config" },
|
||||
|
||||
/* 8851B */
|
||||
{ IC_INFO(RTL_ROM_LMP_8851B, 0xb, 0xc, HCI_USB),
|
||||
.config_needed = false,
|
||||
.has_rom_version = true,
|
||||
.has_msft_ext = false,
|
||||
.fw_name = "rtl_bt/rtl8851bu_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8851bu_config" },
|
||||
};
|
||||
|
||||
static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
|
||||
u8 hci_ver, u8 hci_bus)
|
||||
u8 hci_ver, u8 hci_bus,
|
||||
u8 chip_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -225,6 +275,9 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
|
||||
if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
|
||||
(ic_id_table[i].hci_bus != hci_bus))
|
||||
continue;
|
||||
if ((ic_id_table[i].match_flags & IC_MATCH_FL_CHIP_TYPE) &&
|
||||
(ic_id_table[i].chip_type != chip_type))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -307,6 +360,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
|
||||
{ RTL_ROM_LMP_8723B, 1 },
|
||||
{ RTL_ROM_LMP_8821A, 2 },
|
||||
{ RTL_ROM_LMP_8761A, 3 },
|
||||
{ RTL_ROM_LMP_8703B, 7 },
|
||||
{ RTL_ROM_LMP_8822B, 8 },
|
||||
{ RTL_ROM_LMP_8723B, 9 }, /* 8723D */
|
||||
{ RTL_ROM_LMP_8821A, 10 }, /* 8821C */
|
||||
@ -315,6 +369,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
|
||||
{ RTL_ROM_LMP_8852A, 18 }, /* 8852A */
|
||||
{ RTL_ROM_LMP_8852A, 20 }, /* 8852B */
|
||||
{ RTL_ROM_LMP_8852A, 25 }, /* 8852C */
|
||||
{ RTL_ROM_LMP_8851B, 36 }, /* 8851B */
|
||||
};
|
||||
|
||||
min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
|
||||
@ -587,6 +642,48 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool rtl_has_chip_type(u16 lmp_subver)
|
||||
{
|
||||
switch (lmp_subver) {
|
||||
case RTL_ROM_LMP_8703B:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type)
|
||||
{
|
||||
struct rtl_chip_type_evt *chip_type;
|
||||
struct sk_buff *skb;
|
||||
const unsigned char cmd_buf[] = {0x00, 0x94, 0xa0, 0x00, 0xb0};
|
||||
|
||||
/* Read RTL chip type command */
|
||||
skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
rtl_dev_err(hdev, "Read chip type failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
chip_type = skb_pull_data(skb, sizeof(*chip_type));
|
||||
if (!chip_type) {
|
||||
rtl_dev_err(hdev, "RTL chip type event length mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rtl_dev_info(hdev, "chip_type status=%x type=%x",
|
||||
chip_type->status, chip_type->type);
|
||||
|
||||
*type = chip_type->type & 0x0f;
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btrtl_free(struct btrtl_device_info *btrtl_dev)
|
||||
{
|
||||
kvfree(btrtl_dev->fw_data);
|
||||
@ -603,7 +700,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
||||
struct hci_rp_read_local_version *resp;
|
||||
char cfg_name[40];
|
||||
u16 hci_rev, lmp_subver;
|
||||
u8 hci_ver;
|
||||
u8 hci_ver, chip_type = 0;
|
||||
int ret;
|
||||
u16 opcode;
|
||||
u8 cmd[2];
|
||||
@ -629,8 +726,14 @@ 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);
|
||||
|
||||
if (rtl_has_chip_type(lmp_subver)) {
|
||||
ret = rtl_read_chip_type(hdev, &chip_type);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
|
||||
hdev->bus);
|
||||
hdev->bus, chip_type);
|
||||
|
||||
if (!btrtl_dev->ic_info)
|
||||
btrtl_dev->drop_fw = true;
|
||||
@ -673,7 +776,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
||||
lmp_subver = le16_to_cpu(resp->lmp_subver);
|
||||
|
||||
btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
|
||||
hdev->bus);
|
||||
hdev->bus, chip_type);
|
||||
}
|
||||
out_free:
|
||||
kfree_skb(skb);
|
||||
@ -755,6 +858,8 @@ int btrtl_download_firmware(struct hci_dev *hdev,
|
||||
case RTL_ROM_LMP_8761A:
|
||||
case RTL_ROM_LMP_8822B:
|
||||
case RTL_ROM_LMP_8852A:
|
||||
case RTL_ROM_LMP_8703B:
|
||||
case RTL_ROM_LMP_8851B:
|
||||
return btrtl_setup_rtl8723b(hdev, btrtl_dev);
|
||||
default:
|
||||
rtl_dev_info(hdev, "assuming no firmware upload needed");
|
||||
@ -779,6 +884,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
case CHIP_ID_8852A:
|
||||
case CHIP_ID_8852B:
|
||||
case CHIP_ID_8852C:
|
||||
case CHIP_ID_8851B:
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
hci_set_aosp_capable(hdev);
|
||||
@ -788,6 +894,22 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
rtl_dev_dbg(hdev, "WBS supported not enabled.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!btrtl_dev->ic_info)
|
||||
return;
|
||||
|
||||
switch (btrtl_dev->ic_info->lmp_subver) {
|
||||
case RTL_ROM_LMP_8703B:
|
||||
/* 8723CS reports two pages for local ext features,
|
||||
* but it doesn't support any features from page 2 -
|
||||
* it either responds with garbage or with error status
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FEATURES_PAGE_2,
|
||||
&hdev->quirks);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_set_quirks);
|
||||
|
||||
@ -946,6 +1068,12 @@ MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
|
||||
@ -960,3 +1088,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8851bu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8851bu_config.bin");
|
||||
|
@ -14,6 +14,11 @@
|
||||
|
||||
struct btrtl_device_info;
|
||||
|
||||
struct rtl_chip_type_evt {
|
||||
__u8 status;
|
||||
__u8 type;
|
||||
} __packed;
|
||||
|
||||
struct rtl_download_cmd {
|
||||
__u8 index;
|
||||
__u8 data[RTL_FRAG_LEN];
|
||||
|
@ -549,6 +549,9 @@ static const struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3801), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Additional MediaTek MT7668 Bluetooth devices */
|
||||
{ USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
|
||||
@ -4016,6 +4019,9 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (id->driver_info & BTUSB_ACTIONS_SEMI) {
|
||||
/* Support is advertised, but not implemented */
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
|
||||
}
|
||||
|
||||
if (!reset)
|
||||
|
@ -936,6 +936,8 @@ static int h5_btrtl_setup(struct h5 *h5)
|
||||
err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev);
|
||||
/* Give the device some time before the hci-core sends it a reset */
|
||||
usleep_range(10000, 20000);
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
btrtl_set_quirks(h5->hu->hdev, btrtl_dev);
|
||||
|
||||
@ -1100,6 +1102,8 @@ static const struct of_device_id rtl_bluetooth_of_match[] = {
|
||||
.data = (const void *)&h5_data_rtl8822cs },
|
||||
{ .compatible = "realtek,rtl8723bs-bt",
|
||||
.data = (const void *)&h5_data_rtl8723bs },
|
||||
{ .compatible = "realtek,rtl8723cs-bt",
|
||||
.data = (const void *)&h5_data_rtl8723bs },
|
||||
{ .compatible = "realtek,rtl8723ds-bt",
|
||||
.data = (const void *)&h5_data_rtl8723bs },
|
||||
#endif
|
||||
|
@ -83,6 +83,22 @@ static const struct dmi_system_id tpm_tis_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = tpm_tis_disable_irq,
|
||||
.ident = "ThinkStation P360 Tiny",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = tpm_tis_disable_irq,
|
||||
.ident = "ThinkPad L490",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,8 @@ static asmlinkage void (*sdei_firmware_call)(unsigned long function_id,
|
||||
/* entry point from firmware to arch asm code */
|
||||
static unsigned long sdei_entry_point;
|
||||
|
||||
static int sdei_hp_state;
|
||||
|
||||
struct sdei_event {
|
||||
/* These three are protected by the sdei_list_lock */
|
||||
struct list_head list;
|
||||
@ -301,8 +303,6 @@ int sdei_mask_local_cpu(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL);
|
||||
if (err && err != -EIO) {
|
||||
pr_warn_once("failed to mask CPU[%u]: %d\n",
|
||||
@ -315,6 +315,7 @@ int sdei_mask_local_cpu(void)
|
||||
|
||||
static void _ipi_mask_cpu(void *ignored)
|
||||
{
|
||||
WARN_ON_ONCE(preemptible());
|
||||
sdei_mask_local_cpu();
|
||||
}
|
||||
|
||||
@ -322,8 +323,6 @@ int sdei_unmask_local_cpu(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL);
|
||||
if (err && err != -EIO) {
|
||||
pr_warn_once("failed to unmask CPU[%u]: %d\n",
|
||||
@ -336,6 +335,7 @@ int sdei_unmask_local_cpu(void)
|
||||
|
||||
static void _ipi_unmask_cpu(void *ignored)
|
||||
{
|
||||
WARN_ON_ONCE(preemptible());
|
||||
sdei_unmask_local_cpu();
|
||||
}
|
||||
|
||||
@ -343,6 +343,8 @@ static void _ipi_private_reset(void *ignored)
|
||||
{
|
||||
int err;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0,
|
||||
NULL);
|
||||
if (err && err != -EIO)
|
||||
@ -389,8 +391,6 @@ static void _local_event_enable(void *data)
|
||||
int err;
|
||||
struct sdei_crosscall_args *arg = data;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
err = sdei_api_event_enable(arg->event->event_num);
|
||||
|
||||
sdei_cross_call_return(arg, err);
|
||||
@ -479,8 +479,6 @@ static void _local_event_unregister(void *data)
|
||||
int err;
|
||||
struct sdei_crosscall_args *arg = data;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
err = sdei_api_event_unregister(arg->event->event_num);
|
||||
|
||||
sdei_cross_call_return(arg, err);
|
||||
@ -561,8 +559,6 @@ static void _local_event_register(void *data)
|
||||
struct sdei_registered_event *reg;
|
||||
struct sdei_crosscall_args *arg = data;
|
||||
|
||||
WARN_ON(preemptible());
|
||||
|
||||
reg = per_cpu_ptr(arg->event->private_registered, smp_processor_id());
|
||||
err = sdei_api_event_register(arg->event->event_num, sdei_entry_point,
|
||||
reg, 0, 0);
|
||||
@ -717,6 +713,8 @@ static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action,
|
||||
{
|
||||
int rv;
|
||||
|
||||
WARN_ON_ONCE(preemptible());
|
||||
|
||||
switch (action) {
|
||||
case CPU_PM_ENTER:
|
||||
rv = sdei_mask_local_cpu();
|
||||
@ -765,7 +763,7 @@ static int sdei_device_freeze(struct device *dev)
|
||||
int err;
|
||||
|
||||
/* unregister private events */
|
||||
cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
|
||||
cpuhp_remove_state(sdei_entry_point);
|
||||
|
||||
err = sdei_unregister_shared();
|
||||
if (err)
|
||||
@ -786,12 +784,15 @@ static int sdei_device_thaw(struct device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
|
||||
err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",
|
||||
&sdei_cpuhp_up, &sdei_cpuhp_down);
|
||||
if (err)
|
||||
if (err < 0) {
|
||||
pr_warn("Failed to re-register CPU hotplug notifier...\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
sdei_hp_state = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdei_device_restore(struct device *dev)
|
||||
@ -823,7 +824,7 @@ static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action,
|
||||
* We are going to reset the interface, after this there is no point
|
||||
* doing work when we take CPUs offline.
|
||||
*/
|
||||
cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
|
||||
cpuhp_remove_state(sdei_hp_state);
|
||||
|
||||
sdei_platform_reset();
|
||||
|
||||
@ -1003,13 +1004,15 @@ static int sdei_probe(struct platform_device *pdev)
|
||||
goto remove_cpupm;
|
||||
}
|
||||
|
||||
err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
|
||||
err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI",
|
||||
&sdei_cpuhp_up, &sdei_cpuhp_down);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
pr_warn("Failed to register CPU hotplug notifier...\n");
|
||||
goto remove_reboot;
|
||||
}
|
||||
|
||||
sdei_hp_state = err;
|
||||
|
||||
return 0;
|
||||
|
||||
remove_reboot:
|
||||
|
@ -683,9 +683,11 @@ int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *r
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
if (r)
|
||||
goto late_fini;
|
||||
if (adev->gfx.cp_ecc_error_irq.funcs) {
|
||||
r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0);
|
||||
if (r)
|
||||
goto late_fini;
|
||||
}
|
||||
} else {
|
||||
amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0);
|
||||
}
|
||||
|
@ -1432,13 +1432,31 @@ int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe)
|
||||
struct amdgpu_firmware_info *info;
|
||||
char ucode_prefix[30];
|
||||
char fw_name[40];
|
||||
bool need_retry = false;
|
||||
int r;
|
||||
|
||||
amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin",
|
||||
ucode_prefix,
|
||||
pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1");
|
||||
amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix,
|
||||
sizeof(ucode_prefix));
|
||||
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin",
|
||||
ucode_prefix,
|
||||
pipe == AMDGPU_MES_SCHED_PIPE ? "_2" : "1");
|
||||
need_retry = true;
|
||||
} else {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin",
|
||||
ucode_prefix,
|
||||
pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1");
|
||||
}
|
||||
|
||||
r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe], fw_name);
|
||||
if (r && need_retry && pipe == AMDGPU_MES_SCHED_PIPE) {
|
||||
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
|
||||
ucode_prefix);
|
||||
DRM_INFO("try to fall back to %s\n", fw_name);
|
||||
r = amdgpu_ucode_request(adev, &adev->mes.fw[pipe],
|
||||
fw_name);
|
||||
}
|
||||
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
|
@ -8236,8 +8236,14 @@ static int gfx_v10_0_set_powergating_state(void *handle,
|
||||
case IP_VERSION(10, 3, 3):
|
||||
case IP_VERSION(10, 3, 6):
|
||||
case IP_VERSION(10, 3, 7):
|
||||
if (!enable)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
gfx_v10_cntl_pg(adev, enable);
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
|
||||
if (enable)
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -4641,13 +4641,29 @@ static int gfx_v11_0_post_soft_reset(void *handle)
|
||||
static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t clock;
|
||||
uint64_t clock_counter_lo, clock_counter_hi_pre, clock_counter_hi_after;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
mutex_lock(&adev->gfx.gpu_clock_mutex);
|
||||
clock_counter_hi_pre = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_HI);
|
||||
clock_counter_lo = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_LO);
|
||||
clock_counter_hi_after = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_HI);
|
||||
if (clock_counter_hi_pre != clock_counter_hi_after)
|
||||
clock_counter_lo = (uint64_t)RREG32_SOC15(GC, 0, regCP_MES_MTIME_LO);
|
||||
mutex_unlock(&adev->gfx.gpu_clock_mutex);
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
} else {
|
||||
preempt_disable();
|
||||
clock_counter_hi_pre = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
|
||||
clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
|
||||
clock_counter_hi_after = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER);
|
||||
if (clock_counter_hi_pre != clock_counter_hi_after)
|
||||
clock_counter_lo = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER);
|
||||
preempt_enable();
|
||||
}
|
||||
clock = clock_counter_lo | (clock_counter_hi_after << 32ULL);
|
||||
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
mutex_lock(&adev->gfx.gpu_clock_mutex);
|
||||
clock = (uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_LOWER) |
|
||||
((uint64_t)RREG32_SOC15(SMUIO, 0, regGOLDEN_TSC_COUNT_UPPER) << 32ULL);
|
||||
mutex_unlock(&adev->gfx.gpu_clock_mutex);
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
return clock;
|
||||
}
|
||||
|
||||
@ -5085,8 +5101,14 @@ static int gfx_v11_0_set_powergating_state(void *handle,
|
||||
break;
|
||||
case IP_VERSION(11, 0, 1):
|
||||
case IP_VERSION(11, 0, 4):
|
||||
if (!enable)
|
||||
amdgpu_gfx_off_ctrl(adev, false);
|
||||
|
||||
gfx_v11_cntl_pg(adev, enable);
|
||||
amdgpu_gfx_off_ctrl(adev, enable);
|
||||
|
||||
if (enable)
|
||||
amdgpu_gfx_off_ctrl(adev, true);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "umc_v8_10.h"
|
||||
#include "athub/athub_3_0_0_sh_mask.h"
|
||||
#include "athub/athub_3_0_0_offset.h"
|
||||
#include "dcn/dcn_3_2_0_offset.h"
|
||||
#include "dcn/dcn_3_2_0_sh_mask.h"
|
||||
#include "oss/osssys_6_0_0_offset.h"
|
||||
#include "ivsrcid/vmc/irqsrcs_vmc_1_0.h"
|
||||
#include "navi10_enum.h"
|
||||
@ -523,7 +525,24 @@ static void gmc_v11_0_get_vm_pte(struct amdgpu_device *adev,
|
||||
|
||||
static unsigned gmc_v11_0_get_vbios_fb_size(struct amdgpu_device *adev)
|
||||
{
|
||||
return 0;
|
||||
u32 d1vga_control = RREG32_SOC15(DCE, 0, regD1VGA_CONTROL);
|
||||
unsigned size;
|
||||
|
||||
if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL, D1VGA_MODE_ENABLE)) {
|
||||
size = AMDGPU_VBIOS_VGA_ALLOCATION;
|
||||
} else {
|
||||
u32 viewport;
|
||||
u32 pitch;
|
||||
|
||||
viewport = RREG32_SOC15(DCE, 0, regHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION);
|
||||
pitch = RREG32_SOC15(DCE, 0, regHUBPREQ0_DCSURF_SURFACE_PITCH);
|
||||
size = (REG_GET_FIELD(viewport,
|
||||
HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) *
|
||||
REG_GET_FIELD(pitch, HUBPREQ0_DCSURF_SURFACE_PITCH, PITCH) *
|
||||
4);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static const struct amdgpu_gmc_funcs gmc_v11_0_gmc_funcs = {
|
||||
|
@ -33,13 +33,20 @@
|
||||
#include "mes_v11_api_def.h"
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mes1.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes_2.bin");
|
||||
MODULE_FIRMWARE("amdgpu/gc_11_0_4_mes1.bin");
|
||||
|
||||
static int mes_v11_0_hw_fini(void *handle);
|
||||
static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev);
|
||||
|
@ -1908,7 +1908,7 @@ static int sdma_v4_0_sw_fini(void *handle)
|
||||
amdgpu_ring_fini(&adev->sdma.instance[i].page);
|
||||
}
|
||||
|
||||
if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 0) ||
|
||||
if (adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 2, 2) ||
|
||||
adev->ip_versions[SDMA0_HWIP][0] == IP_VERSION(4, 4, 0))
|
||||
amdgpu_sdma_destroy_inst_ctx(adev, true);
|
||||
else
|
||||
|
@ -516,11 +516,8 @@ static enum bp_result get_gpio_i2c_info(
|
||||
info->i2c_slave_address = record->i2c_slave_addr;
|
||||
|
||||
/* TODO: check how to get register offset for en, Y, etc. */
|
||||
info->gpio_info.clk_a_register_index =
|
||||
le16_to_cpu(
|
||||
header->gpio_pin[table_index].data_a_reg_index);
|
||||
info->gpio_info.clk_a_shift =
|
||||
header->gpio_pin[table_index].gpio_bitshift;
|
||||
info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index);
|
||||
info->gpio_info.clk_a_shift = pin->gpio_bitshift;
|
||||
|
||||
return BP_RESULT_OK;
|
||||
}
|
||||
|
@ -764,7 +764,8 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe &&
|
||||
pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
|
||||
populate_subvp_cmd_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
|
||||
} else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE) {
|
||||
} else if (pipe->plane_state && pipe->stream->mall_stream_config.type == SUBVP_NONE &&
|
||||
!pipe->top_pipe && !pipe->prev_odm_pipe) {
|
||||
// Don't need to check for ActiveDRAMClockChangeMargin < 0, not valid in cases where
|
||||
// we run through DML without calculating "natural" P-state support
|
||||
populate_subvp_cmd_vblank_pipe_info(dc, context, &cmd, pipe, cmd_pipe_index++);
|
||||
|
@ -1009,7 +1009,7 @@ static void dce_transform_set_pixel_storage_depth(
|
||||
color_depth = COLOR_DEPTH_101010;
|
||||
pixel_depth = 0;
|
||||
expan_mode = 1;
|
||||
BREAK_TO_DEBUGGER();
|
||||
DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1023,8 +1023,7 @@ static void dce_transform_set_pixel_storage_depth(
|
||||
if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
|
||||
/*we should use unsupported capabilities
|
||||
* unless it is required by w/a*/
|
||||
DC_LOG_WARNING("%s: Capability not supported",
|
||||
__func__);
|
||||
DC_LOG_DC("%s: Capability not supported", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,7 +629,8 @@ void dcn30_init_hw(struct dc *dc)
|
||||
if (dc->clk_mgr->funcs->notify_wm_ranges)
|
||||
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
|
||||
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk)
|
||||
//if softmax is enabled then hardmax will be set by a different call
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
|
||||
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
|
||||
|
@ -284,7 +284,7 @@ void dcn31_init_hw(struct dc *dc)
|
||||
if (dc->clk_mgr->funcs->notify_wm_ranges)
|
||||
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
|
||||
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk)
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
|
||||
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
|
||||
|
@ -970,7 +970,7 @@ void dcn32_init_hw(struct dc *dc)
|
||||
if (dc->clk_mgr->funcs->notify_wm_ranges)
|
||||
dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
|
||||
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk)
|
||||
if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
|
||||
dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
|
||||
|
||||
if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
|
||||
|
@ -4866,7 +4866,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
v->DETBufferSizeCThisState[k],
|
||||
&v->UrgentBurstFactorCursorPre[k],
|
||||
&v->UrgentBurstFactorLumaPre[k],
|
||||
&v->UrgentBurstFactorChroma[k],
|
||||
&v->UrgentBurstFactorChromaPre[k],
|
||||
&v->NoUrgentLatencyHidingPre[k]);
|
||||
}
|
||||
|
||||
|
@ -4305,11 +4305,11 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
|
||||
} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
|
||||
if (v->DSCEnable[k] == true) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
if (v->Output[k] == dm_dp) {
|
||||
if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresFEC[i][k] = false;
|
||||
@ -4317,107 +4317,201 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
} else {
|
||||
v->RequiresDSC[i][k] = false;
|
||||
v->LinkDSCEnable = false;
|
||||
v->RequiresFEC[i][k] = false;
|
||||
if (v->Output[k] == dm_dp2p0) {
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresFEC[i][k] = false;
|
||||
}
|
||||
}
|
||||
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKPerState[i] >= 270.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 2700,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 5400,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 8100,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
|
||||
if (v->Output[k] == dm_dp2p0) {
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
|
||||
v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
|
||||
v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID &&
|
||||
(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
|
||||
v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 13500,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
|
||||
v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 13500,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID &&
|
||||
(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
|
||||
v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 20000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
|
||||
v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 20000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
|
||||
}
|
||||
} else {
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKPerState[i] >= 270.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 2700,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 5400,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 8100,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -5095,7 +5189,7 @@ void dml31_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
v->DETBufferSizeCThisState[k],
|
||||
&v->UrgentBurstFactorCursorPre[k],
|
||||
&v->UrgentBurstFactorLumaPre[k],
|
||||
&v->UrgentBurstFactorChroma[k],
|
||||
&v->UrgentBurstFactorChromaPre[k],
|
||||
&v->NotUrgentLatencyHidingPre[k]);
|
||||
}
|
||||
|
||||
|
@ -310,6 +310,10 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
|
||||
pipe->plane_state->src_rect.width < pipe->plane_state->dst_rect.width))
|
||||
upscaled = true;
|
||||
|
||||
/* Apply HostVM policy - either based on hypervisor globally enabled, or rIOMMU active */
|
||||
if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
|
||||
pipes[i].pipe.src.hostvm = dc->vm_pa_config.is_hvm_enabled || dc->res_pool->hubbub->riommu_active;
|
||||
|
||||
/*
|
||||
* Immediate flip can be set dynamically after enabling the plane.
|
||||
* We need to require support for immediate flip or underflow can be
|
||||
|
@ -4403,11 +4403,11 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) {
|
||||
} else if (v->Output[k] == dm_dp || v->Output[k] == dm_edp || v->Output[k] == dm_dp2p0) {
|
||||
if (v->DSCEnable[k] == true) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
if (v->Output[k] == dm_dp) {
|
||||
if (v->Output[k] == dm_dp || v->Output[k] == dm_dp2p0) {
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresFEC[i][k] = false;
|
||||
@ -4415,107 +4415,201 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
||||
} else {
|
||||
v->RequiresDSC[i][k] = false;
|
||||
v->LinkDSCEnable = false;
|
||||
v->RequiresFEC[i][k] = false;
|
||||
if (v->Output[k] == dm_dp2p0) {
|
||||
v->RequiresFEC[i][k] = true;
|
||||
} else {
|
||||
v->RequiresFEC[i][k] = false;
|
||||
}
|
||||
}
|
||||
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKPerState[i] >= 270.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 2700,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 5400,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 8100,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 10000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "10x4";
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[i] >= 12000.0 / 18) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
12000,
|
||||
4,
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
//v->OutputTypeAndRatePerState[i][k] = v->Output[k] & "12x4";
|
||||
if (v->Output[k] == dm_dp2p0) {
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if ((v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr10) &&
|
||||
v->PHYCLKD18PerState[k] >= 10000.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 13500.0 / 18.0 &&
|
||||
v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 10000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR10"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID &&
|
||||
(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr13p5) &&
|
||||
v->PHYCLKD18PerState[k] >= 13500.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 13500,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKD18PerState[k] < 20000.0 / 18.0 &&
|
||||
v->DSCEnable[k] == true && v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 13500,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR13p5"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID &&
|
||||
(v->OutputLinkDPRate[k] == dm_dp_rate_na || v->OutputLinkDPRate[k] == dm_dp_rate_uhbr20) &&
|
||||
v->PHYCLKD18PerState[k] >= 20000.0 / 18.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 20000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
if (v->Outbpp == BPP_INVALID && v->DSCEnable[k] == true &&
|
||||
v->ForcedOutputLinkBPP[k] == 0) {
|
||||
v->RequiresDSC[i][k] = true;
|
||||
v->LinkDSCEnable = true;
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 20000,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
}
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " UHBR20"
|
||||
}
|
||||
} else {
|
||||
v->Outbpp = BPP_INVALID;
|
||||
if (v->PHYCLKPerState[i] >= 270.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 2700,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 540.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 5400,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR2"
|
||||
}
|
||||
if (v->Outbpp == BPP_INVALID && v->PHYCLKPerState[i] >= 810.0) {
|
||||
v->Outbpp = TruncToValidBPP(
|
||||
(1.0 - v->Downspreading / 100.0) * 8100,
|
||||
v->OutputLinkDPLanes[k],
|
||||
v->HTotal[k],
|
||||
v->HActive[k],
|
||||
v->PixelClockBackEnd[k],
|
||||
v->ForcedOutputLinkBPP[k],
|
||||
v->LinkDSCEnable,
|
||||
v->Output[k],
|
||||
v->OutputFormat[k],
|
||||
v->DSCInputBitPerComponent[k],
|
||||
v->NumberOfDSCSlices[k],
|
||||
v->AudioSampleRate[k],
|
||||
v->AudioSampleLayout[k],
|
||||
v->ODMCombineEnablePerState[i][k]);
|
||||
v->OutputBppPerState[i][k] = v->Outbpp;
|
||||
// TODO: Need some other way to handle this nonsense
|
||||
// v->OutputTypeAndRatePerState[i][k] = v->Output[k] & " HBR3"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -5192,7 +5286,7 @@ void dml314_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_
|
||||
v->DETBufferSizeCThisState[k],
|
||||
&v->UrgentBurstFactorCursorPre[k],
|
||||
&v->UrgentBurstFactorLumaPre[k],
|
||||
&v->UrgentBurstFactorChroma[k],
|
||||
&v->UrgentBurstFactorChromaPre[k],
|
||||
&v->NotUrgentLatencyHidingPre[k]);
|
||||
}
|
||||
|
||||
|
@ -3333,7 +3333,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
|
||||
/* Output */
|
||||
&mode_lib->vba.UrgentBurstFactorCursorPre[k],
|
||||
&mode_lib->vba.UrgentBurstFactorLumaPre[k],
|
||||
&mode_lib->vba.UrgentBurstFactorChroma[k],
|
||||
&mode_lib->vba.UrgentBurstFactorChromaPre[k],
|
||||
&mode_lib->vba.NotUrgentLatencyHidingPre[k]);
|
||||
}
|
||||
|
||||
|
@ -723,6 +723,24 @@ static int smu_late_init(void *handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Explicitly notify PMFW the power mode the system in. Since
|
||||
* the PMFW may boot the ASIC with a different mode.
|
||||
* For those supporting ACDC switch via gpio, PMFW will
|
||||
* handle the switch automatically. Driver involvement
|
||||
* is unnecessary.
|
||||
*/
|
||||
if (!smu->dc_controlled_by_gpio) {
|
||||
ret = smu_set_power_source(smu,
|
||||
adev->pm.ac_power ? SMU_POWER_SOURCE_AC :
|
||||
SMU_POWER_SOURCE_DC);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to switch to %s mode!\n",
|
||||
adev->pm.ac_power ? "AC" : "DC");
|
||||
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)))
|
||||
return 0;
|
||||
|
@ -3406,26 +3406,8 @@ static int navi10_post_smu_init(struct smu_context *smu)
|
||||
return 0;
|
||||
|
||||
ret = navi10_run_umc_cdr_workaround(smu);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
dev_err(adev->dev, "Failed to apply umc cdr workaround!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!smu->dc_controlled_by_gpio) {
|
||||
/*
|
||||
* For Navi1X, manually switch it to AC mode as PMFW
|
||||
* may boot it with DC mode.
|
||||
*/
|
||||
ret = smu_v11_0_set_power_source(smu,
|
||||
adev->pm.ac_power ?
|
||||
SMU_POWER_SOURCE_AC :
|
||||
SMU_POWER_SOURCE_DC);
|
||||
if (ret) {
|
||||
dev_err(adev->dev, "Failed to switch to %s mode!\n",
|
||||
adev->pm.ac_power ? "AC" : "DC");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1767,6 +1767,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
|
||||
.enable_mgpu_fan_boost = smu_v13_0_7_enable_mgpu_fan_boost,
|
||||
.get_power_limit = smu_v13_0_7_get_power_limit,
|
||||
.set_power_limit = smu_v13_0_set_power_limit,
|
||||
.set_power_source = smu_v13_0_set_power_source,
|
||||
.get_power_profile_mode = smu_v13_0_7_get_power_profile_mode,
|
||||
.set_power_profile_mode = smu_v13_0_7_set_power_profile_mode,
|
||||
.set_tool_table_location = smu_v13_0_set_tool_table_location,
|
||||
|
@ -7,13 +7,28 @@
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
static const struct displayid_header *
|
||||
displayid_get_header(const u8 *displayid, int length, int index)
|
||||
{
|
||||
const struct displayid_header *base;
|
||||
|
||||
if (sizeof(*base) > length - index)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
base = (const struct displayid_header *)&displayid[index];
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static int validate_displayid(const u8 *displayid, int length, int idx)
|
||||
{
|
||||
int i, dispid_length;
|
||||
u8 csum = 0;
|
||||
const struct displayid_header *base;
|
||||
|
||||
base = (const struct displayid_header *)&displayid[idx];
|
||||
base = displayid_get_header(displayid, length, idx);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
|
||||
base->rev, base->bytes, base->prod_id, base->ext_count);
|
||||
|
@ -708,19 +708,27 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y,
|
||||
static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len,
|
||||
struct drm_rect *clip)
|
||||
{
|
||||
u32 line_length = info->fix.line_length;
|
||||
u32 fb_height = info->var.yres;
|
||||
off_t end = off + len;
|
||||
u32 x1 = 0;
|
||||
u32 y1 = off / info->fix.line_length;
|
||||
u32 y1 = off / line_length;
|
||||
u32 x2 = info->var.xres;
|
||||
u32 y2 = DIV_ROUND_UP(end, info->fix.line_length);
|
||||
u32 y2 = DIV_ROUND_UP(end, line_length);
|
||||
|
||||
/* Don't allow any of them beyond the bottom bound of display area */
|
||||
if (y1 > fb_height)
|
||||
y1 = fb_height;
|
||||
if (y2 > fb_height)
|
||||
y2 = fb_height;
|
||||
|
||||
if ((y2 - y1) == 1) {
|
||||
/*
|
||||
* We've only written to a single scanline. Try to reduce
|
||||
* the number of horizontal pixels that need an update.
|
||||
*/
|
||||
off_t bit_off = (off % info->fix.line_length) * 8;
|
||||
off_t bit_end = (end % info->fix.line_length) * 8;
|
||||
off_t bit_off = (off % line_length) * 8;
|
||||
off_t bit_end = (end % line_length) * 8;
|
||||
|
||||
x1 = bit_off / info->var.bits_per_pixel;
|
||||
x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel);
|
||||
|
@ -221,7 +221,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,
|
||||
return dsi;
|
||||
}
|
||||
|
||||
dsi->dev.of_node = info->node;
|
||||
device_set_node(&dsi->dev, of_fwnode_handle(info->node));
|
||||
dsi->channel = info->channel;
|
||||
strlcpy(dsi->name, info->type, sizeof(dsi->name));
|
||||
|
||||
|
@ -34,11 +34,11 @@ static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int g2d_open(struct drm_device *drm_dev, struct drm_file *file)
|
||||
static inline int g2d_open(struct drm_device *drm_dev, struct drm_file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void g2d_close(struct drm_device *drm_dev, struct drm_file *file)
|
||||
static inline void g2d_close(struct drm_device *drm_dev, struct drm_file *file)
|
||||
{ }
|
||||
#endif
|
||||
|
@ -54,23 +54,34 @@ config DRM_I915
|
||||
If "M" is selected, the module will be called i915.
|
||||
|
||||
config DRM_I915_FORCE_PROBE
|
||||
string "Force probe driver for selected new Intel hardware"
|
||||
string "Force probe i915 for selected Intel hardware IDs"
|
||||
depends on DRM_I915
|
||||
help
|
||||
This is the default value for the i915.force_probe module
|
||||
parameter. Using the module parameter overrides this option.
|
||||
|
||||
Force probe the driver for new Intel graphics devices that are
|
||||
recognized but not properly supported by this kernel version. It is
|
||||
recommended to upgrade to a kernel version with proper support as soon
|
||||
as it is available.
|
||||
Force probe the i915 driver for Intel graphics devices that are
|
||||
recognized but not properly supported by this kernel version. Force
|
||||
probing an unsupported device taints the kernel. It is recommended to
|
||||
upgrade to a kernel version with proper support as soon as it is
|
||||
available.
|
||||
|
||||
It can also be used to block the probe of recognized and fully
|
||||
supported devices.
|
||||
|
||||
Use "" to disable force probe. If in doubt, use this.
|
||||
|
||||
Use "<pci-id>[,<pci-id>,...]" to force probe the driver for listed
|
||||
Use "<pci-id>[,<pci-id>,...]" to force probe the i915 for listed
|
||||
devices. For example, "4500" or "4500,4571".
|
||||
|
||||
Use "*" to force probe the driver for all known devices.
|
||||
Use "*" to force probe the driver for all known devices. Not
|
||||
recommended.
|
||||
|
||||
Use "!" right before the ID to block the probe of the device. For
|
||||
example, "4500,!4571" forces the probe of 4500 and blocks the probe of
|
||||
4571.
|
||||
|
||||
Use "!*" to block the probe of the driver for all known devices.
|
||||
|
||||
config DRM_I915_CAPTURE_ERROR
|
||||
bool "Enable capturing GPU state following a hang"
|
||||
|
@ -988,7 +988,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
||||
int ret;
|
||||
|
||||
if (old_obj) {
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state,
|
||||
to_intel_crtc(old_plane_state->hw.crtc));
|
||||
|
||||
@ -1003,7 +1003,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
||||
* This should only fail upon a hung GPU, in which case we
|
||||
* can safely continue.
|
||||
*/
|
||||
if (intel_crtc_needs_modeset(crtc_state)) {
|
||||
if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) {
|
||||
ret = i915_sw_fence_await_reservation(&state->commit_ready,
|
||||
old_obj->base.resv, NULL,
|
||||
false, 0,
|
||||
|
@ -1512,6 +1512,11 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
pipe_config->dsc.slice_count =
|
||||
drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
|
||||
true);
|
||||
if (!pipe_config->dsc.slice_count) {
|
||||
drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n",
|
||||
pipe_config->dsc.slice_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
u16 dsc_max_output_bpp;
|
||||
u8 dsc_dp_slice_count;
|
||||
|
@ -30,12 +30,14 @@
|
||||
{ FORCEWAKE_MT, 0, 0, "FORCEWAKE" }
|
||||
|
||||
#define COMMON_GEN9BASE_GLOBAL \
|
||||
{ GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \
|
||||
{ GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" }, \
|
||||
{ ERROR_GEN6, 0, 0, "ERROR_GEN6" }, \
|
||||
{ DONE_REG, 0, 0, "DONE_REG" }, \
|
||||
{ HSW_GTT_CACHE_EN, 0, 0, "HSW_GTT_CACHE_EN" }
|
||||
|
||||
#define GEN9_GLOBAL \
|
||||
{ GEN8_FAULT_TLB_DATA0, 0, 0, "GEN8_FAULT_TLB_DATA0" }, \
|
||||
{ GEN8_FAULT_TLB_DATA1, 0, 0, "GEN8_FAULT_TLB_DATA1" }
|
||||
|
||||
#define COMMON_GEN12BASE_GLOBAL \
|
||||
{ GEN12_FAULT_TLB_DATA0, 0, 0, "GEN12_FAULT_TLB_DATA0" }, \
|
||||
{ GEN12_FAULT_TLB_DATA1, 0, 0, "GEN12_FAULT_TLB_DATA1" }, \
|
||||
@ -136,6 +138,7 @@ static const struct __guc_mmio_reg_descr xe_lpd_blt_inst_regs[] = {
|
||||
static const struct __guc_mmio_reg_descr default_global_regs[] = {
|
||||
COMMON_BASE_GLOBAL,
|
||||
COMMON_GEN9BASE_GLOBAL,
|
||||
GEN9_GLOBAL,
|
||||
};
|
||||
|
||||
static const struct __guc_mmio_reg_descr default_rc_class_regs[] = {
|
||||
|
@ -122,7 +122,7 @@ i915_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
|
||||
"Default: 0");
|
||||
|
||||
i915_param_named_unsafe(force_probe, charp, 0400,
|
||||
"Force probe the driver for specified devices. "
|
||||
"Force probe options for specified supported devices. "
|
||||
"See CONFIG_DRM_I915_FORCE_PROBE for details.");
|
||||
|
||||
i915_param_named_unsafe(disable_power_well, int, 0400,
|
||||
|
@ -1252,7 +1252,7 @@ static void i915_pci_remove(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
/* is device_id present in comma separated list of ids */
|
||||
static bool force_probe(u16 device_id, const char *devices)
|
||||
static bool device_id_in_list(u16 device_id, const char *devices, bool negative)
|
||||
{
|
||||
char *s, *p, *tok;
|
||||
bool ret;
|
||||
@ -1261,7 +1261,9 @@ static bool force_probe(u16 device_id, const char *devices)
|
||||
return false;
|
||||
|
||||
/* match everything */
|
||||
if (strcmp(devices, "*") == 0)
|
||||
if (negative && strcmp(devices, "!*") == 0)
|
||||
return true;
|
||||
if (!negative && strcmp(devices, "*") == 0)
|
||||
return true;
|
||||
|
||||
s = kstrdup(devices, GFP_KERNEL);
|
||||
@ -1271,6 +1273,12 @@ static bool force_probe(u16 device_id, const char *devices)
|
||||
for (p = s, ret = false; (tok = strsep(&p, ",")) != NULL; ) {
|
||||
u16 val;
|
||||
|
||||
if (negative && tok[0] == '!')
|
||||
tok++;
|
||||
else if ((negative && tok[0] != '!') ||
|
||||
(!negative && tok[0] == '!'))
|
||||
continue;
|
||||
|
||||
if (kstrtou16(tok, 16, &val) == 0 && val == device_id) {
|
||||
ret = true;
|
||||
break;
|
||||
@ -1282,6 +1290,16 @@ static bool force_probe(u16 device_id, const char *devices)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool id_forced(u16 device_id)
|
||||
{
|
||||
return device_id_in_list(device_id, i915_modparams.force_probe, false);
|
||||
}
|
||||
|
||||
static bool id_blocked(u16 device_id)
|
||||
{
|
||||
return device_id_in_list(device_id, i915_modparams.force_probe, true);
|
||||
}
|
||||
|
||||
bool i915_pci_resource_valid(struct pci_dev *pdev, int bar)
|
||||
{
|
||||
if (!pci_resource_flags(pdev, bar))
|
||||
@ -1309,10 +1327,9 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
(struct intel_device_info *) ent->driver_data;
|
||||
int err;
|
||||
|
||||
if (intel_info->require_force_probe &&
|
||||
!force_probe(pdev->device, i915_modparams.force_probe)) {
|
||||
if (intel_info->require_force_probe && !id_forced(pdev->device)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Your graphics device %04x is not properly supported by the driver in this\n"
|
||||
"Your graphics device %04x is not properly supported by i915 in this\n"
|
||||
"kernel version. To force driver probe anyway, use i915.force_probe=%04x\n"
|
||||
"module parameter or CONFIG_DRM_I915_FORCE_PROBE=%04x configuration option,\n"
|
||||
"or (recommended) check for kernel updates.\n",
|
||||
@ -1320,6 +1337,18 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (id_blocked(pdev->device)) {
|
||||
dev_info(&pdev->dev, "I915 probe blocked for Device ID %04x.\n",
|
||||
pdev->device);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (intel_info->require_force_probe) {
|
||||
dev_info(&pdev->dev, "Force probing unsupported Device ID %04x, tainting kernel\n",
|
||||
pdev->device);
|
||||
add_taint(TAINT_USER, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
/* Only bind to function 0 of the device. Early generations
|
||||
* used function 1 as a placeholder for multi-head. This causes
|
||||
* us confusion instead, especially on the systems where both
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
/*
|
||||
* Register offsets in MDSS register file for the interrupt registers
|
||||
* w.r.t. to the MDP base
|
||||
* w.r.t. the MDP base
|
||||
*/
|
||||
#define MDP_SSPP_TOP0_OFF 0x0
|
||||
#define MDP_INTF_0_OFF 0x6A000
|
||||
@ -24,6 +24,9 @@
|
||||
#define MDP_INTF_3_OFF 0x6B800
|
||||
#define MDP_INTF_4_OFF 0x6C000
|
||||
#define MDP_INTF_5_OFF 0x6C800
|
||||
#define INTF_INTR_EN 0x1c0
|
||||
#define INTF_INTR_STATUS 0x1c4
|
||||
#define INTF_INTR_CLEAR 0x1c8
|
||||
#define MDP_AD4_0_OFF 0x7C000
|
||||
#define MDP_AD4_1_OFF 0x7D000
|
||||
#define MDP_AD4_INTR_EN_OFF 0x41c
|
||||
|
@ -56,11 +56,6 @@
|
||||
#define INTF_TPG_RGB_MAPPING 0x11C
|
||||
#define INTF_PROG_FETCH_START 0x170
|
||||
#define INTF_PROG_ROT_START 0x174
|
||||
|
||||
#define INTF_FRAME_LINE_COUNT_EN 0x0A8
|
||||
#define INTF_FRAME_COUNT 0x0AC
|
||||
#define INTF_LINE_COUNT 0x0B0
|
||||
|
||||
#define INTF_MUX 0x25C
|
||||
|
||||
#define INTF_CFG_ACTIVE_H_EN BIT(29)
|
||||
|
@ -61,6 +61,7 @@ static const struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb,
|
||||
for (i = 0; i < m->wb_count; i++) {
|
||||
if (wb == m->wb[i].id) {
|
||||
b->blk_addr = addr + m->wb[i].base;
|
||||
b->log_mask = DPU_DBG_MASK_WB;
|
||||
return &m->wb[i];
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,6 @@
|
||||
#define HIST_INTR_EN 0x01c
|
||||
#define HIST_INTR_STATUS 0x020
|
||||
#define HIST_INTR_CLEAR 0x024
|
||||
#define INTF_INTR_EN 0x1C0
|
||||
#define INTF_INTR_STATUS 0x1C4
|
||||
#define INTF_INTR_CLEAR 0x1C8
|
||||
#define SPLIT_DISPLAY_EN 0x2F4
|
||||
#define SPLIT_DISPLAY_UPPER_PIPE_CTRL 0x2F8
|
||||
#define DSPP_IGC_COLOR0_RAM_LUTN 0x300
|
||||
|
@ -593,6 +593,18 @@ static struct hdmi_codec_pdata codec_data = {
|
||||
.i2s = 1,
|
||||
};
|
||||
|
||||
void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio)
|
||||
{
|
||||
struct dp_audio_private *audio_priv;
|
||||
|
||||
audio_priv = container_of(dp_audio, struct dp_audio_private, dp_audio);
|
||||
|
||||
if (audio_priv->audio_pdev) {
|
||||
platform_device_unregister(audio_priv->audio_pdev);
|
||||
audio_priv->audio_pdev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int dp_register_audio_driver(struct device *dev,
|
||||
struct dp_audio *dp_audio)
|
||||
{
|
||||
|
@ -53,6 +53,8 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev,
|
||||
int dp_register_audio_driver(struct device *dev,
|
||||
struct dp_audio *dp_audio);
|
||||
|
||||
void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio);
|
||||
|
||||
/**
|
||||
* dp_audio_put()
|
||||
*
|
||||
|
@ -162,47 +162,6 @@ static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private *aux,
|
||||
return i;
|
||||
}
|
||||
|
||||
static void dp_aux_native_handler(struct dp_aux_private *aux, u32 isr)
|
||||
{
|
||||
if (isr & DP_INTR_AUX_I2C_DONE)
|
||||
aux->aux_error_num = DP_AUX_ERR_NONE;
|
||||
else if (isr & DP_INTR_WRONG_ADDR)
|
||||
aux->aux_error_num = DP_AUX_ERR_ADDR;
|
||||
else if (isr & DP_INTR_TIMEOUT)
|
||||
aux->aux_error_num = DP_AUX_ERR_TOUT;
|
||||
if (isr & DP_INTR_NACK_DEFER)
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK;
|
||||
if (isr & DP_INTR_AUX_ERROR) {
|
||||
aux->aux_error_num = DP_AUX_ERR_PHY;
|
||||
dp_catalog_aux_clear_hw_interrupts(aux->catalog);
|
||||
}
|
||||
}
|
||||
|
||||
static void dp_aux_i2c_handler(struct dp_aux_private *aux, u32 isr)
|
||||
{
|
||||
if (isr & DP_INTR_AUX_I2C_DONE) {
|
||||
if (isr & (DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER))
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK;
|
||||
else
|
||||
aux->aux_error_num = DP_AUX_ERR_NONE;
|
||||
} else {
|
||||
if (isr & DP_INTR_WRONG_ADDR)
|
||||
aux->aux_error_num = DP_AUX_ERR_ADDR;
|
||||
else if (isr & DP_INTR_TIMEOUT)
|
||||
aux->aux_error_num = DP_AUX_ERR_TOUT;
|
||||
if (isr & DP_INTR_NACK_DEFER)
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
|
||||
if (isr & DP_INTR_I2C_NACK)
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK;
|
||||
if (isr & DP_INTR_I2C_DEFER)
|
||||
aux->aux_error_num = DP_AUX_ERR_DEFER;
|
||||
if (isr & DP_INTR_AUX_ERROR) {
|
||||
aux->aux_error_num = DP_AUX_ERR_PHY;
|
||||
dp_catalog_aux_clear_hw_interrupts(aux->catalog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,
|
||||
struct drm_dp_aux_msg *input_msg)
|
||||
{
|
||||
@ -427,13 +386,42 @@ void dp_aux_isr(struct drm_dp_aux *dp_aux)
|
||||
if (!isr)
|
||||
return;
|
||||
|
||||
if (!aux->cmd_busy)
|
||||
if (!aux->cmd_busy) {
|
||||
DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aux->native)
|
||||
dp_aux_native_handler(aux, isr);
|
||||
else
|
||||
dp_aux_i2c_handler(aux, isr);
|
||||
/*
|
||||
* The logic below assumes only one error bit is set (other than "done"
|
||||
* which can apparently be set at the same time as some of the other
|
||||
* bits). Warn if more than one get set so we know we need to improve
|
||||
* the logic.
|
||||
*/
|
||||
if (hweight32(isr & ~DP_INTR_AUX_XFER_DONE) > 1)
|
||||
DRM_WARN("Some DP AUX interrupts unhandled: %#010x\n", isr);
|
||||
|
||||
if (isr & DP_INTR_AUX_ERROR) {
|
||||
aux->aux_error_num = DP_AUX_ERR_PHY;
|
||||
dp_catalog_aux_clear_hw_interrupts(aux->catalog);
|
||||
} else if (isr & DP_INTR_NACK_DEFER) {
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
|
||||
} else if (isr & DP_INTR_WRONG_ADDR) {
|
||||
aux->aux_error_num = DP_AUX_ERR_ADDR;
|
||||
} else if (isr & DP_INTR_TIMEOUT) {
|
||||
aux->aux_error_num = DP_AUX_ERR_TOUT;
|
||||
} else if (!aux->native && (isr & DP_INTR_I2C_NACK)) {
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK;
|
||||
} else if (!aux->native && (isr & DP_INTR_I2C_DEFER)) {
|
||||
if (isr & DP_INTR_AUX_XFER_DONE)
|
||||
aux->aux_error_num = DP_AUX_ERR_NACK;
|
||||
else
|
||||
aux->aux_error_num = DP_AUX_ERR_DEFER;
|
||||
} else if (isr & DP_INTR_AUX_XFER_DONE) {
|
||||
aux->aux_error_num = DP_AUX_ERR_NONE;
|
||||
} else {
|
||||
DRM_WARN("Unexpected interrupt: %#010x\n", isr);
|
||||
return;
|
||||
}
|
||||
|
||||
complete(&aux->comp);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define DP_INTF_CONFIG_DATABUS_WIDEN BIT(4)
|
||||
|
||||
#define DP_INTERRUPT_STATUS1 \
|
||||
(DP_INTR_AUX_I2C_DONE| \
|
||||
(DP_INTR_AUX_XFER_DONE| \
|
||||
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
|
||||
DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
|
||||
DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/* interrupts */
|
||||
#define DP_INTR_HPD BIT(0)
|
||||
#define DP_INTR_AUX_I2C_DONE BIT(3)
|
||||
#define DP_INTR_AUX_XFER_DONE BIT(3)
|
||||
#define DP_INTR_WRONG_ADDR BIT(6)
|
||||
#define DP_INTR_TIMEOUT BIT(9)
|
||||
#define DP_INTR_NACK_DEFER BIT(12)
|
||||
|
@ -323,6 +323,7 @@ static void dp_display_unbind(struct device *dev, struct device *master,
|
||||
kthread_stop(dp->ev_tsk);
|
||||
|
||||
dp_power_client_deinit(dp->power);
|
||||
dp_unregister_audio_driver(dev, dp->audio);
|
||||
dp_aux_unregister(dp->aux);
|
||||
dp->drm_dev = NULL;
|
||||
dp->aux->drm_dev = NULL;
|
||||
|
@ -709,7 +709,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct drm_msm_gem_submit *args = data;
|
||||
struct msm_file_private *ctx = file->driver_priv;
|
||||
struct msm_gem_submit *submit;
|
||||
struct msm_gem_submit *submit = NULL;
|
||||
struct msm_gpu *gpu = priv->gpu;
|
||||
struct msm_gpu_submitqueue *queue;
|
||||
struct msm_ringbuffer *ring;
|
||||
@ -756,13 +756,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||
out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
|
||||
if (out_fence_fd < 0) {
|
||||
ret = out_fence_fd;
|
||||
return ret;
|
||||
goto out_post_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds);
|
||||
if (IS_ERR(submit))
|
||||
return PTR_ERR(submit);
|
||||
if (IS_ERR(submit)) {
|
||||
ret = PTR_ERR(submit);
|
||||
goto out_post_unlock;
|
||||
}
|
||||
|
||||
trace_msm_gpu_submit(pid_nr(submit->pid), ring->id, submit->ident,
|
||||
args->nr_bos, args->nr_cmds);
|
||||
@ -945,11 +947,20 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||
if (has_ww_ticket)
|
||||
ww_acquire_fini(&submit->ticket);
|
||||
out_unlock:
|
||||
if (ret && (out_fence_fd >= 0))
|
||||
put_unused_fd(out_fence_fd);
|
||||
mutex_unlock(&queue->lock);
|
||||
out_post_unlock:
|
||||
msm_gem_submit_put(submit);
|
||||
if (ret && (out_fence_fd >= 0))
|
||||
put_unused_fd(out_fence_fd);
|
||||
|
||||
if (!IS_ERR_OR_NULL(submit)) {
|
||||
msm_gem_submit_put(submit);
|
||||
} else {
|
||||
/*
|
||||
* If the submit hasn't yet taken ownership of the queue
|
||||
* then we need to drop the reference ourself:
|
||||
*/
|
||||
msm_submitqueue_put(queue);
|
||||
}
|
||||
if (!IS_ERR_OR_NULL(post_deps)) {
|
||||
for (i = 0; i < args->nr_out_syncobjs; ++i) {
|
||||
kfree(post_deps[i].chain);
|
||||
|
@ -640,6 +640,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
|
||||
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
|
||||
|
||||
dw_hdmi_unbind(hdmi->hdmi);
|
||||
drm_encoder_cleanup(&hdmi->encoder.encoder);
|
||||
clk_disable_unprepare(hdmi->ref_clk);
|
||||
|
||||
regulator_disable(hdmi->avdd_1v8);
|
||||
|
@ -1153,7 +1153,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor,
|
||||
struct drm_dp_link *link)
|
||||
{
|
||||
const u64 f = 100000, link_rate = link->rate * 1000;
|
||||
const u64 pclk = mode->clock * 1000;
|
||||
const u64 pclk = (u64)mode->clock * 1000;
|
||||
u64 input, output, watermark, num;
|
||||
struct tegra_sor_params params;
|
||||
u32 num_syms_per_line;
|
||||
|
@ -854,14 +854,16 @@ static const struct hid_device_id apple_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_RDESC_JIS },
|
||||
@ -880,7 +882,8 @@ static const struct hid_device_id apple_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
|
||||
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
|
||||
APPLE_RDESC_JIS },
|
||||
@ -921,31 +924,31 @@ static const struct hid_device_id apple_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
|
||||
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
|
||||
|
@ -415,6 +415,7 @@
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817
|
||||
#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
|
||||
#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
|
||||
#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
|
||||
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
|
||||
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
|
||||
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
|
||||
|
@ -372,6 +372,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
|
||||
|
@ -838,8 +838,7 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
|
||||
hdev->product, &serial);
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
|
||||
dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
|
||||
|
||||
name = hidpp_unifying_get_name(hidpp);
|
||||
@ -932,6 +931,54 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0003: Device Information */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003
|
||||
|
||||
#define CMD_GET_DEVICE_INFO 0x00
|
||||
|
||||
static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial)
|
||||
{
|
||||
struct hidpp_report response;
|
||||
u8 feature_type;
|
||||
u8 feature_index;
|
||||
int ret;
|
||||
|
||||
ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION,
|
||||
&feature_index,
|
||||
&feature_type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = hidpp_send_fap_command_sync(hidpp, feature_index,
|
||||
CMD_GET_DEVICE_INFO,
|
||||
NULL, 0, &response);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* See hidpp_unifying_get_serial() */
|
||||
*serial = *((u32 *)&response.rap.params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hidpp_serial_init(struct hidpp_device *hidpp)
|
||||
{
|
||||
struct hid_device *hdev = hidpp->hid_dev;
|
||||
u32 serial;
|
||||
int ret;
|
||||
|
||||
ret = hidpp_get_serial(hidpp, &serial);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial);
|
||||
dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x0005: GetDeviceNameType */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -4194,6 +4241,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||
|
||||
if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
|
||||
hidpp_unifying_init(hidpp);
|
||||
else if (hid_is_usb(hidpp->hid_dev))
|
||||
hidpp_serial_init(hidpp);
|
||||
|
||||
connected = hidpp_root_get_protocol_version(hidpp) == 0;
|
||||
atomic_set(&hidpp->connected, connected);
|
||||
|
@ -1963,18 +1963,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
|
||||
static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,
|
||||
struct hid_field *field, struct hid_usage *usage)
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
||||
struct wacom_features *features = &wacom_wac->features;
|
||||
unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
|
||||
|
||||
switch (equivalent_usage) {
|
||||
case HID_DG_BATTERYSTRENGTH:
|
||||
case WACOM_HID_WD_BATTERY_LEVEL:
|
||||
case WACOM_HID_WD_BATTERY_CHARGING:
|
||||
features->quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
|
||||
@ -1995,18 +1984,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
}
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
case WACOM_HID_WD_BATTERY_LEVEL:
|
||||
value = value * 100 / (field->logical_maximum - field->logical_minimum);
|
||||
wacom_wac->hid_data.battery_capacity = value;
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
case WACOM_HID_WD_BATTERY_CHARGING:
|
||||
wacom_wac->hid_data.bat_charging = value;
|
||||
wacom_wac->hid_data.ps_connected = value;
|
||||
wacom_wac->hid_data.bat_connected = 1;
|
||||
wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;
|
||||
wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2022,18 +2014,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev,
|
||||
{
|
||||
struct wacom *wacom = hid_get_drvdata(hdev);
|
||||
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
|
||||
struct wacom_features *features = &wacom_wac->features;
|
||||
|
||||
if (features->quirks & WACOM_QUIRK_BATTERY) {
|
||||
int status = wacom_wac->hid_data.bat_status;
|
||||
int capacity = wacom_wac->hid_data.battery_capacity;
|
||||
bool charging = wacom_wac->hid_data.bat_charging;
|
||||
bool connected = wacom_wac->hid_data.bat_connected;
|
||||
bool powered = wacom_wac->hid_data.ps_connected;
|
||||
int status = wacom_wac->hid_data.bat_status;
|
||||
int capacity = wacom_wac->hid_data.battery_capacity;
|
||||
bool charging = wacom_wac->hid_data.bat_charging;
|
||||
bool connected = wacom_wac->hid_data.bat_connected;
|
||||
bool powered = wacom_wac->hid_data.ps_connected;
|
||||
|
||||
wacom_notify_battery(wacom_wac, status, capacity, charging,
|
||||
connected, powered);
|
||||
}
|
||||
wacom_notify_battery(wacom_wac, status, capacity, charging,
|
||||
connected, powered);
|
||||
}
|
||||
|
||||
static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
|
||||
|
@ -31,7 +31,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct resource *res;
|
||||
struct priv *priv;
|
||||
int ret;
|
||||
int ret, table_size;
|
||||
unsigned long flags;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL);
|
||||
@ -90,7 +90,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
if (ret < 0)
|
||||
goto out_mcb_bus;
|
||||
|
||||
dev_dbg(&pdev->dev, "Found %d cells\n", ret);
|
||||
table_size = ret;
|
||||
|
||||
if (table_size < CHAM_HEADER_SIZE) {
|
||||
/* Release the previous resources */
|
||||
devm_iounmap(&pdev->dev, priv->base);
|
||||
devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
|
||||
|
||||
/* Then, allocate it again with the actual chameleon table size */
|
||||
res = devm_request_mem_region(&pdev->dev, priv->mapbase,
|
||||
table_size,
|
||||
KBUILD_MODNAME);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Failed to request PCI memory\n");
|
||||
ret = -EBUSY;
|
||||
goto out_mcb_bus;
|
||||
}
|
||||
|
||||
priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size);
|
||||
if (!priv->base) {
|
||||
dev_err(&pdev->dev, "Cannot ioremap\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_mcb_bus;
|
||||
}
|
||||
}
|
||||
|
||||
mcb_bus_add_devices(priv->bus);
|
||||
|
||||
|
@ -8028,16 +8028,16 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
|
||||
} else if (resync > max_sectors) {
|
||||
resync = max_sectors;
|
||||
} else {
|
||||
resync -= atomic_read(&mddev->recovery_active);
|
||||
if (resync < MD_RESYNC_ACTIVE) {
|
||||
/*
|
||||
* Resync has started, but the subtraction has
|
||||
* yielded one of the special values. Force it
|
||||
* to active to ensure the status reports an
|
||||
* active resync.
|
||||
*/
|
||||
res = atomic_read(&mddev->recovery_active);
|
||||
/*
|
||||
* Resync has started, but the subtraction has overflowed or
|
||||
* yielded one of the special values. Force it to active to
|
||||
* ensure the status reports an active resync.
|
||||
*/
|
||||
if (resync < res || resync - res < MD_RESYNC_ACTIVE)
|
||||
resync = MD_RESYNC_ACTIVE;
|
||||
}
|
||||
else
|
||||
resync -= res;
|
||||
}
|
||||
|
||||
if (resync == MD_RESYNC_NONE) {
|
||||
|
@ -1325,7 +1325,9 @@ void cx23885_free_buffer(struct cx23885_dev *dev, struct cx23885_buffer *buf)
|
||||
{
|
||||
struct cx23885_riscmem *risc = &buf->risc;
|
||||
|
||||
dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
|
||||
if (risc->cpu)
|
||||
dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu, risc->dma);
|
||||
memset(risc, 0, sizeof(*risc));
|
||||
}
|
||||
|
||||
static void cx23885_tsport_reg_dump(struct cx23885_tsport *port)
|
||||
|
@ -342,6 +342,7 @@ static int queue_setup(struct vb2_queue *q,
|
||||
|
||||
static int buffer_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
int ret;
|
||||
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
struct cx23885_dev *dev = vb->vb2_queue->drv_priv;
|
||||
struct cx23885_buffer *buf =
|
||||
@ -358,12 +359,12 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
||||
|
||||
switch (dev->field) {
|
||||
case V4L2_FIELD_TOP:
|
||||
cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, 0, UNSET,
|
||||
buf->bpl, 0, dev->height);
|
||||
break;
|
||||
case V4L2_FIELD_BOTTOM:
|
||||
cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, UNSET, 0,
|
||||
buf->bpl, 0, dev->height);
|
||||
break;
|
||||
@ -391,21 +392,21 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
||||
line0_offset = 0;
|
||||
line1_offset = buf->bpl;
|
||||
}
|
||||
cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl, line0_offset,
|
||||
line1_offset,
|
||||
buf->bpl, buf->bpl,
|
||||
dev->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_TB:
|
||||
cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl,
|
||||
0, buf->bpl * (dev->height >> 1),
|
||||
buf->bpl, 0,
|
||||
dev->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_BT:
|
||||
cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
ret = cx23885_risc_buffer(dev->pci, &buf->risc,
|
||||
sgt->sgl,
|
||||
buf->bpl * (dev->height >> 1), 0,
|
||||
buf->bpl, 0,
|
||||
@ -418,7 +419,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
|
||||
buf, buf->vb.vb2_buf.index,
|
||||
dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc,
|
||||
(unsigned long)buf->risc.dma);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void buffer_finish(struct vb2_buffer *vb)
|
||||
|
@ -697,7 +697,7 @@ static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num)
|
||||
netup_unidvb_dma_enable(dma, 0);
|
||||
msleep(50);
|
||||
cancel_work_sync(&dma->work);
|
||||
del_timer(&dma->timeout);
|
||||
del_timer_sync(&dma->timeout);
|
||||
}
|
||||
|
||||
static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev)
|
||||
|
@ -437,6 +437,7 @@ static void tw68_buf_queue(struct vb2_buffer *vb)
|
||||
*/
|
||||
static int tw68_buf_prepare(struct vb2_buffer *vb)
|
||||
{
|
||||
int ret;
|
||||
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||
struct vb2_queue *vq = vb->vb2_queue;
|
||||
struct tw68_dev *dev = vb2_get_drv_priv(vq);
|
||||
@ -452,30 +453,30 @@ static int tw68_buf_prepare(struct vb2_buffer *vb)
|
||||
bpl = (dev->width * dev->fmt->depth) >> 3;
|
||||
switch (dev->field) {
|
||||
case V4L2_FIELD_TOP:
|
||||
tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
0, UNSET, bpl, 0, dev->height);
|
||||
break;
|
||||
case V4L2_FIELD_BOTTOM:
|
||||
tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
UNSET, 0, bpl, 0, dev->height);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_TB:
|
||||
tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
0, bpl * (dev->height >> 1),
|
||||
bpl, 0, dev->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_SEQ_BT:
|
||||
tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
bpl * (dev->height >> 1), 0,
|
||||
bpl, 0, dev->height >> 1);
|
||||
break;
|
||||
case V4L2_FIELD_INTERLACED:
|
||||
default:
|
||||
tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
ret = tw68_risc_buffer(dev->pci, buf, dma->sgl,
|
||||
0, bpl, bpl, bpl, dev->height >> 1);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tw68_buf_finish(struct vb2_buffer *vb)
|
||||
@ -485,7 +486,8 @@ static void tw68_buf_finish(struct vb2_buffer *vb)
|
||||
struct tw68_dev *dev = vb2_get_drv_priv(vq);
|
||||
struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
|
||||
|
||||
dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma);
|
||||
if (buf->cpu)
|
||||
dma_free_coherent(&dev->pci->dev, buf->size, buf->cpu, buf->dma);
|
||||
}
|
||||
|
||||
static int tw68_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
|
@ -735,6 +735,13 @@ int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
||||
}
|
||||
|
||||
if (*nplanes) {
|
||||
if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
if (*nplanes != q_data->fmt->num_planes)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (*nplanes != 1)
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < *nplanes; i++) {
|
||||
if (sizes[i] < q_data->sizeimage[i])
|
||||
return -EINVAL;
|
||||
|
@ -66,7 +66,9 @@ static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
|
||||
struct vsp1_entity *prev, unsigned int prev_pad,
|
||||
struct vsp1_entity *next, unsigned int next_pad)
|
||||
{
|
||||
struct v4l2_subdev_format format;
|
||||
struct v4l2_subdev_format format = {
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!uif) {
|
||||
@ -82,8 +84,6 @@ static int vsp1_du_insert_uif(struct vsp1_device *vsp1,
|
||||
prev->sink = uif;
|
||||
prev->sink_pad = UIF_PAD_SINK;
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
format.pad = prev_pad;
|
||||
|
||||
ret = v4l2_subdev_call(&prev->subdev, pad, get_fmt, NULL, &format);
|
||||
@ -118,8 +118,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
|
||||
struct vsp1_entity *uif,
|
||||
unsigned int brx_input)
|
||||
{
|
||||
struct v4l2_subdev_selection sel;
|
||||
struct v4l2_subdev_format format;
|
||||
struct v4l2_subdev_selection sel = {
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
struct v4l2_subdev_format format = {
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
const struct v4l2_rect *crop;
|
||||
int ret;
|
||||
|
||||
@ -129,8 +133,6 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
|
||||
*/
|
||||
crop = &vsp1->drm->inputs[rpf->entity.index].crop;
|
||||
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
format.pad = RWPF_PAD_SINK;
|
||||
format.format.width = crop->width + crop->left;
|
||||
format.format.height = crop->height + crop->top;
|
||||
@ -147,8 +149,6 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
|
||||
__func__, format.format.width, format.format.height,
|
||||
format.format.code, rpf->entity.index);
|
||||
|
||||
memset(&sel, 0, sizeof(sel));
|
||||
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
sel.pad = RWPF_PAD_SINK;
|
||||
sel.target = V4L2_SEL_TGT_CROP;
|
||||
sel.r = *crop;
|
||||
|
@ -184,15 +184,14 @@ vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
|
||||
int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
|
||||
struct v4l2_subdev_state *sd_state)
|
||||
{
|
||||
struct v4l2_subdev_format format;
|
||||
unsigned int pad;
|
||||
|
||||
for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) {
|
||||
memset(&format, 0, sizeof(format));
|
||||
|
||||
format.pad = pad;
|
||||
format.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
|
||||
: V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
struct v4l2_subdev_format format = {
|
||||
.pad = pad,
|
||||
.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
|
||||
: V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
|
||||
v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &format);
|
||||
}
|
||||
|
@ -763,7 +763,10 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
|
||||
struct fimc_dev *fimc = ctx->fimc_dev;
|
||||
struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
|
||||
struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
|
||||
struct v4l2_subdev_format sfmt;
|
||||
struct v4l2_subdev_format sfmt = {
|
||||
.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE
|
||||
: V4L2_SUBDEV_FORMAT_TRY,
|
||||
};
|
||||
struct v4l2_mbus_framefmt *mf = &sfmt.format;
|
||||
struct media_entity *me;
|
||||
struct fimc_fmt *ffmt;
|
||||
@ -774,9 +777,7 @@ static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
|
||||
if (WARN_ON(!sd || !tfmt))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&sfmt, 0, sizeof(sfmt));
|
||||
sfmt.format = *tfmt;
|
||||
sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
|
||||
|
||||
me = fimc_pipeline_get_head(&sd->entity);
|
||||
|
||||
|
@ -1499,7 +1499,9 @@ static int vpfe_enum_size(struct file *file, void *priv,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
struct vpfe_device *vpfe = video_drvdata(file);
|
||||
struct v4l2_subdev_frame_size_enum fse;
|
||||
struct v4l2_subdev_frame_size_enum fse = {
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
struct v4l2_subdev *sd = vpfe->current_subdev->sd;
|
||||
struct vpfe_fmt *fmt;
|
||||
int ret;
|
||||
@ -1514,11 +1516,9 @@ static int vpfe_enum_size(struct file *file, void *priv,
|
||||
|
||||
memset(fsize->reserved, 0x0, sizeof(fsize->reserved));
|
||||
|
||||
memset(&fse, 0x0, sizeof(fse));
|
||||
fse.index = fsize->index;
|
||||
fse.pad = 0;
|
||||
fse.code = fmt->code;
|
||||
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -2146,7 +2146,6 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
|
||||
{
|
||||
struct vpfe_device *vpfe = container_of(notifier->v4l2_dev,
|
||||
struct vpfe_device, v4l2_dev);
|
||||
struct v4l2_subdev_mbus_code_enum mbus_code;
|
||||
struct vpfe_subdev_info *sdinfo;
|
||||
struct vpfe_fmt *fmt;
|
||||
int ret = 0;
|
||||
@ -2173,9 +2172,11 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
|
||||
|
||||
vpfe->num_active_fmt = 0;
|
||||
for (j = 0, i = 0; (ret != -EINVAL); ++j) {
|
||||
memset(&mbus_code, 0, sizeof(mbus_code));
|
||||
mbus_code.index = j;
|
||||
mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||
struct v4l2_subdev_mbus_code_enum mbus_code = {
|
||||
.index = j,
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
|
||||
ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
|
||||
NULL, &mbus_code);
|
||||
if (ret)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user