Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  hdac_i915.c - routines for sync between HD-A core and i915 display driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <sound/hdaudio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <sound/hda_i915.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sound/hda_register.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define IS_HSW_CONTROLLER(pci) (((pci)->device == 0x0a0c) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 				((pci)->device == 0x0c0c) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 				((pci)->device == 0x0d0c) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 				((pci)->device == 0x160c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * @bus: HDA core bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * BCLK = CDCLK * M / N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * The values will be lost when the display power well is disabled and need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * be restored to avoid abnormal playback speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * Call this function at initializing and changing power well, as well as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * at ELD notifier for the hotplug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct drm_audio_component *acomp = bus->audio_component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct pci_dev *pci = to_pci_dev(bus->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	int cdclk_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	unsigned int bclk_m, bclk_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return; /* only for i915 binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (!IS_HSW_CONTROLLER(pci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return; /* only HSW/BDW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	switch (cdclk_freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	case 337500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		bclk_m = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		bclk_n = 225;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	case 450000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	default: /* default CDCLK 450MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		bclk_m = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		bclk_n = 75;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	case 540000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		bclk_m = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		bclk_n = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	case 675000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		bclk_m = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		bclk_n = 225;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /* returns true if the devices can be connected for audio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static bool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	struct pci_bus *bus_a = i915->bus, *bus_b = hdac->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/* directly connected on the same bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (bus_a == bus_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * on i915 discrete GPUs with embedded HDA audio, the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * devices are connected via 2nd level PCI bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	bus_a = bus_a->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	bus_b = bus_b->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (!bus_a || !bus_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	bus_a = bus_a->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	bus_b = bus_b->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (bus_a && bus_a == bus_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int i915_component_master_match(struct device *dev, int subcomponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 				       void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct pci_dev *hdac_pci, *i915_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	struct hdac_bus *bus = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (!dev_is_pci(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	hdac_pci = to_pci_dev(bus->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	i915_pci = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (!strcmp(dev->driver->name, "i915") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	    subcomponent == I915_COMPONENT_AUDIO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	    connectivity_check(i915_pci, hdac_pci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* check whether intel graphics is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static bool i915_gfx_present(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	static const struct pci_device_id ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		  .class = PCI_BASE_CLASS_DISPLAY << 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		  .class_mask = 0xff << 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return pci_dev_present(ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * snd_hdac_i915_init - Initialize i915 audio component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * @bus: HDA core bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * This function is supposed to be used only by a HD-audio controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * driver that needs the interaction with i915 graphics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * This function initializes and sets up the audio component to communicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * with i915 graphics driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * Returns zero for success or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int snd_hdac_i915_init(struct hdac_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct drm_audio_component *acomp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (!i915_gfx_present())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	err = snd_hdac_acomp_init(bus, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				  i915_component_master_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				  sizeof(struct i915_audio_component) - sizeof(*acomp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	acomp = bus->audio_component;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (!acomp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (!acomp->ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		if (!IS_ENABLED(CONFIG_MODULES) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		    !request_module("i915")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			/* 60s timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			wait_for_completion_timeout(&acomp->master_bind_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 						    msecs_to_jiffies(60 * 1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (!acomp->ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		dev_info(bus->dev, "couldn't bind with audio component\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		snd_hdac_acomp_exit(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) EXPORT_SYMBOL_GPL(snd_hdac_i915_init);