drivers/gfx/nvidia: Add driver for NVIDIA Optimus
Add a driver for systems with NVIDIA Optimus (hybrid) graphics using GC6 3.0. The driver provides ACPI support for dynamically powering on and off the GPU, and a function for enabling the GPU power in romstage. Tested on system76/gaze15. Change-Id: I2dec7aa2c8db7994f78a7cc1220502676e248465 Signed-off-by: Jeremy Soller <jeremy@system76.com> Signed-off-by: Tim Crawford <tcrawford@system76.com>
This commit is contained in:
		
							
								
								
									
										10
									
								
								src/drivers/gfx/nvidia/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/drivers/gfx/nvidia/Kconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					config DRIVERS_GFX_NVIDIA
 | 
				
			||||||
 | 
						bool
 | 
				
			||||||
 | 
						default n
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Support for NVIDIA Optimus with GC6 3.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config DRIVERS_GFX_NVIDIA_BRIDGE
 | 
				
			||||||
 | 
						hex "PCI bridge for the GPU device"
 | 
				
			||||||
 | 
						default 0x01
 | 
				
			||||||
 | 
						depends on DRIVERS_GFX_NVIDIA
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/drivers/gfx/nvidia/Makefile.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/drivers/gfx/nvidia/Makefile.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					# SPDX-License-Identifier: GPL-2.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					romstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += romstage.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ramstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += nvidia.c
 | 
				
			||||||
							
								
								
									
										202
									
								
								src/drivers/gfx/nvidia/acpi/gpu.asl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								src/drivers/gfx/nvidia/acpi/gpu.asl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Device (\_SB.PCI0.PEGP) {
 | 
				
			||||||
 | 
						Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PowerResource (PWRR, 0, 0) {
 | 
				
			||||||
 | 
							Name (_STA, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Method (_ON) {
 | 
				
			||||||
 | 
								Debug = "PEGP.PWRR._ON"
 | 
				
			||||||
 | 
								If (_STA != 1) {
 | 
				
			||||||
 | 
									\_SB.PCI0.PEGP.DEV0._ON ()
 | 
				
			||||||
 | 
									_STA = 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Method (_OFF) {
 | 
				
			||||||
 | 
								Debug = "PEGP.PWRR._OFF"
 | 
				
			||||||
 | 
								If (_STA != 0) {
 | 
				
			||||||
 | 
									\_SB.PCI0.PEGP.DEV0._OFF ()
 | 
				
			||||||
 | 
									_STA = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Name (_PR0, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
				
			||||||
 | 
						Name (_PR2, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
				
			||||||
 | 
						Name (_PR3, Package () { \_SB.PCI0.PEGP.PWRR })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Device (\_SB.PCI0.PEGP.DEV0) {
 | 
				
			||||||
 | 
						Name(_ADR, 0x00000000)
 | 
				
			||||||
 | 
						Name (_STA, 0xF)
 | 
				
			||||||
 | 
						Name (LTRE, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Memory mapped PCI express registers
 | 
				
			||||||
 | 
						// Not sure what this stuff is, but it is used to get into GC6
 | 
				
			||||||
 | 
					        // TODO: use GPU config to generate address
 | 
				
			||||||
 | 
						OperationRegion (RPCX, SystemMemory, CONFIG_MMCONF_BASE_ADDRESS + 0x8000, 0x1000)
 | 
				
			||||||
 | 
						Field (RPCX, ByteAcc, NoLock, Preserve) {
 | 
				
			||||||
 | 
							PVID,   16,
 | 
				
			||||||
 | 
							PDID,   16,
 | 
				
			||||||
 | 
							CMDR,   8,
 | 
				
			||||||
 | 
							Offset (0x19),
 | 
				
			||||||
 | 
							PRBN,   8,
 | 
				
			||||||
 | 
							Offset (0x84),
 | 
				
			||||||
 | 
							D0ST,   2,
 | 
				
			||||||
 | 
							Offset (0xAA),
 | 
				
			||||||
 | 
							CEDR,   1,
 | 
				
			||||||
 | 
							Offset (0xAC),
 | 
				
			||||||
 | 
								,   4,
 | 
				
			||||||
 | 
							CMLW,   6,
 | 
				
			||||||
 | 
							Offset (0xB0),
 | 
				
			||||||
 | 
							ASPM,   2,
 | 
				
			||||||
 | 
								,   2,
 | 
				
			||||||
 | 
							P0LD,   1,
 | 
				
			||||||
 | 
							RTLK,   1,
 | 
				
			||||||
 | 
							Offset (0xC9),
 | 
				
			||||||
 | 
								,   2,
 | 
				
			||||||
 | 
							LREN,   1,
 | 
				
			||||||
 | 
							Offset (0x11A),
 | 
				
			||||||
 | 
								,   1,
 | 
				
			||||||
 | 
							VCNP,   1,
 | 
				
			||||||
 | 
							Offset (0x214),
 | 
				
			||||||
 | 
							Offset (0x216),
 | 
				
			||||||
 | 
							P0LS,   4,
 | 
				
			||||||
 | 
							Offset (0x248),
 | 
				
			||||||
 | 
								,   7,
 | 
				
			||||||
 | 
							Q0L2,   1,
 | 
				
			||||||
 | 
							Q0L0,   1,
 | 
				
			||||||
 | 
							Offset (0x504),
 | 
				
			||||||
 | 
							Offset (0x506),
 | 
				
			||||||
 | 
							PCFG,   2,
 | 
				
			||||||
 | 
							Offset (0x508),
 | 
				
			||||||
 | 
							TREN,   1,
 | 
				
			||||||
 | 
							Offset (0xC20),
 | 
				
			||||||
 | 
								,   4,
 | 
				
			||||||
 | 
							P0AP,   2,
 | 
				
			||||||
 | 
							Offset (0xC38),
 | 
				
			||||||
 | 
								,   3,
 | 
				
			||||||
 | 
							P0RM,   1,
 | 
				
			||||||
 | 
							Offset (0xC74),
 | 
				
			||||||
 | 
							P0LT,   4,
 | 
				
			||||||
 | 
							Offset (0xD0C),
 | 
				
			||||||
 | 
								,   20,
 | 
				
			||||||
 | 
							LREV,   1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Method (_ON) {
 | 
				
			||||||
 | 
							Debug = "PEGP.DEV0._ON"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							If (_STA != 0xF) {
 | 
				
			||||||
 | 
								Debug = "  If DGPU_PWR_EN low"
 | 
				
			||||||
 | 
								If (! GTXS (DGPU_PWR_EN)) {
 | 
				
			||||||
 | 
									Debug = "    DGPU_PWR_EN high"
 | 
				
			||||||
 | 
									STXS (DGPU_PWR_EN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Debug = "    Sleep 16"
 | 
				
			||||||
 | 
									Sleep (16)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  DGPU_RST_N high"
 | 
				
			||||||
 | 
								STXS(DGPU_RST_N)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Sleep 10"
 | 
				
			||||||
 | 
								Sleep (10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Q0L0 = 1"
 | 
				
			||||||
 | 
								Q0L0 = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Sleep 16"
 | 
				
			||||||
 | 
								Sleep (16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  While Q0L0"
 | 
				
			||||||
 | 
								Local0 = 0
 | 
				
			||||||
 | 
								While (Q0L0) {
 | 
				
			||||||
 | 
									If ((Local0 > 4)) {
 | 
				
			||||||
 | 
										Debug = "    While Q0L0 timeout"
 | 
				
			||||||
 | 
										Break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Sleep (16)
 | 
				
			||||||
 | 
									Local0++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  P0RM = 0"
 | 
				
			||||||
 | 
								P0RM = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  P0AP = 0"
 | 
				
			||||||
 | 
								P0AP = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = Concatenate("  LREN = ", ToHexString(LTRE))
 | 
				
			||||||
 | 
								LREN = LTRE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  CEDR = 1"
 | 
				
			||||||
 | 
								CEDR = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  CMDR |= 7"
 | 
				
			||||||
 | 
								CMDR |= 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  _STA = 0xF"
 | 
				
			||||||
 | 
								_STA = 0xF
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Method (_OFF) {
 | 
				
			||||||
 | 
							Debug = "PEGP.DEV0._OFF"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							If (_STA != 0x5) {
 | 
				
			||||||
 | 
								Debug = Concatenate("  LTRE = ", ToHexString(LREN))
 | 
				
			||||||
 | 
								LTRE = LREN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Q0L2 = 1"
 | 
				
			||||||
 | 
								Q0L2 = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Sleep 16"
 | 
				
			||||||
 | 
								Sleep (16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  While Q0L2"
 | 
				
			||||||
 | 
								Local0 = Zero
 | 
				
			||||||
 | 
								While (Q0L2) {
 | 
				
			||||||
 | 
									If ((Local0 > 4)) {
 | 
				
			||||||
 | 
										Debug = "    While Q0L2 timeout"
 | 
				
			||||||
 | 
										Break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Sleep (16)
 | 
				
			||||||
 | 
									Local0++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  P0RM = 1"
 | 
				
			||||||
 | 
								P0RM = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  P0AP = 3"
 | 
				
			||||||
 | 
								P0AP = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  Sleep 10"
 | 
				
			||||||
 | 
								Sleep (10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  DGPU_RST_N low"
 | 
				
			||||||
 | 
								CTXS(DGPU_RST_N)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  While DGPU_GC6 low"
 | 
				
			||||||
 | 
								Local0 = Zero
 | 
				
			||||||
 | 
								While (! GRXS(DGPU_GC6)) {
 | 
				
			||||||
 | 
									If ((Local0 > 4)) {
 | 
				
			||||||
 | 
										Debug = "    While DGPU_GC6 low timeout"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										Debug = "    DGPU_PWR_EN low"
 | 
				
			||||||
 | 
										CTXS (DGPU_PWR_EN)
 | 
				
			||||||
 | 
										Break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Sleep (16)
 | 
				
			||||||
 | 
									Local0++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Debug = "  _STA = 0x5"
 | 
				
			||||||
 | 
								_STA = 0x5
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/drivers/gfx/nvidia/chip.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/drivers/gfx/nvidia/chip.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _DRIVERS_GFX_NVIDIA_CHIP_H_
 | 
				
			||||||
 | 
					#define _DRIVERS_GFX_NVIDIA_CHIP_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct drivers_gfx_nvidia_config {
 | 
				
			||||||
 | 
						/* TODO: Set GPIOs in devicetree? */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _DRIVERS_GFX_NVIDIA_CHIP_H_ */
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/drivers/gfx/nvidia/gpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/drivers/gfx/nvidia/gpu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef _DRIVERS_GFX_NVIDIA_GPU_H_
 | 
				
			||||||
 | 
					#define _DRIVERS_GFX_NVIDIA_GPU_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct nvidia_gpu_config {
 | 
				
			||||||
 | 
						/* GPIO for GPU_PWR_EN */
 | 
				
			||||||
 | 
						unsigned int power_gpio;
 | 
				
			||||||
 | 
						/* GPIO for GPU_RST# */
 | 
				
			||||||
 | 
						unsigned int reset_gpio;
 | 
				
			||||||
 | 
						/* Enable or disable GPU power */
 | 
				
			||||||
 | 
						bool enable;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void nvidia_set_power(const struct nvidia_gpu_config *config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* _DRIVERS_NVIDIA_GPU_H_ */
 | 
				
			||||||
							
								
								
									
										67
									
								
								src/drivers/gfx/nvidia/nvidia.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/drivers/gfx/nvidia/nvidia.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "chip.h"
 | 
				
			||||||
 | 
					#include <console/console.h>
 | 
				
			||||||
 | 
					#include <device/device.h>
 | 
				
			||||||
 | 
					#include <device/pci.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NVIDIA_SUBSYSTEM_ID_OFFSET 0x40
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvidia_read_resources(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printk(BIOS_DEBUG, "%s: %s\n", __func__, dev_path(dev));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pci_dev_read_resources(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Find all BARs on GPU, mark them above 4g if prefetchable
 | 
				
			||||||
 | 
						for (int bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) {
 | 
				
			||||||
 | 
							struct resource *res = probe_resource(dev, bar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (res) {
 | 
				
			||||||
 | 
								if (res->flags & IORESOURCE_PREFETCH) {
 | 
				
			||||||
 | 
									printk(BIOS_INFO, "  BAR at 0x%02x marked above 4g\n", bar);
 | 
				
			||||||
 | 
									res->flags |= IORESOURCE_ABOVE_4G;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									printk(BIOS_DEBUG, "  BAR at 0x%02x not prefetch\n", bar);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								printk(BIOS_DEBUG, "  BAR at 0x%02x not found\n", bar);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvidia_set_subsystem(struct device *dev, unsigned int vendor, unsigned int device)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pci_write_config32(dev, NVIDIA_SUBSYSTEM_ID_OFFSET,
 | 
				
			||||||
 | 
							((device & 0xffff) << 16) | (vendor & 0xffff));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct pci_operations nvidia_device_ops_pci = {
 | 
				
			||||||
 | 
						.set_subsystem = nvidia_set_subsystem,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct device_operations nvidia_device_ops = {
 | 
				
			||||||
 | 
						.read_resources   = nvidia_read_resources,
 | 
				
			||||||
 | 
						.set_resources    = pci_dev_set_resources,
 | 
				
			||||||
 | 
						.enable_resources = pci_dev_enable_resources,
 | 
				
			||||||
 | 
					#if CONFIG(HAVE_ACPI_TABLES)
 | 
				
			||||||
 | 
						.write_acpi_tables = pci_rom_write_acpi_tables,
 | 
				
			||||||
 | 
						.acpi_fill_ssdt    = pci_rom_ssdt,
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						.init             = pci_dev_init,
 | 
				
			||||||
 | 
						.ops_pci          = &nvidia_device_ops_pci,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void nvidia_enable(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!dev->enabled || dev->path.type != DEVICE_PATH_PCI)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev->ops = &nvidia_device_ops;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct chip_operations drivers_gfx_nvidia_ops = {
 | 
				
			||||||
 | 
						CHIP_NAME("NVIDIA Optimus graphics device")
 | 
				
			||||||
 | 
						.enable_dev = nvidia_enable
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										35
									
								
								src/drivers/gfx/nvidia/romstage.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/drivers/gfx/nvidia/romstage.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0-only */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <console/console.h>
 | 
				
			||||||
 | 
					#include <delay.h>
 | 
				
			||||||
 | 
					#include <device/device.h>
 | 
				
			||||||
 | 
					#include <device/pci.h>
 | 
				
			||||||
 | 
					#include <gpio.h>
 | 
				
			||||||
 | 
					#include "chip.h"
 | 
				
			||||||
 | 
					#include "gpu.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void nvidia_set_power(const struct nvidia_gpu_config *config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!config->power_gpio || !config->reset_gpio) {
 | 
				
			||||||
 | 
							printk(BIOS_ERR, "%s: GPU_PWR_EN and GPU_RST# must be set\n", __func__);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk(BIOS_DEBUG, "%s: GPU_PWR_EN = %d\n",
 | 
				
			||||||
 | 
							__func__, config->power_gpio);
 | 
				
			||||||
 | 
						printk(BIOS_DEBUG, "%s: GPU_RST# = %d\n",
 | 
				
			||||||
 | 
							__func__, config->reset_gpio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gpio_set(config->reset_gpio, 0);
 | 
				
			||||||
 | 
						mdelay(4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (config->enable) {
 | 
				
			||||||
 | 
							gpio_set(config->power_gpio, 1);
 | 
				
			||||||
 | 
							mdelay(4);
 | 
				
			||||||
 | 
							gpio_set(config->reset_gpio, 1);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							gpio_set(config->power_gpio, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mdelay(4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user