Arch Linux NVIDIA Prime laptop guide 2017 (using nvidia package with fairly new laptops.)

This is a guide as well as more of a reference for myself and friends who need it in the future.

1. Setup modules for initramfs:
sudo nano /etc/mkinitcpio.conf

where it says MODULES= add these like this:
MODULES="nvidia nvidia_modeset"

2. Find your nvidia BusID:
sudo lspci -k | grep -A 2 -E "(VGA|3D)"

Output should be something like:


00:02.0 VGA compatible controller: Intel Corporation HD Graphics 530 (rev 06)
  Subsystem: Dell Device 0706
  Kernel driver in use: i915
--
02:00.0 3D controller: NVIDIA Corporation GM107M [GeForce GTX 960M] (rev a2)
  Subsystem: Dell Device 0706
  Kernel driver in use: nvidia

Here, our BusID for NVIDIA is 2:0:0.

3. Create xorg config.:
sudo nano /etc/X11/xorg.conf


Section "Module"
        Load "modesetting"
EndSection

Section "Device"
        Identifier "nvidia"
        Driver "nvidia"
        BusID "PCI:2:0:0"
        Option "AllowEmptyInitialConfiguration"
EndSection

4. Create a bash script that makes xrandr output to your integrated display using nvidia.
First install xrandr if you don’t have it:
sudo pacman -S xorg-xrandr

Now create the script to make nvidia output to the modesetting device.
sudo nano /etc/X11/xinit/xinitrc.d/nvidia-script.sh


#!/bin/sh
xrandr --setprovideroutputsource modesetting NVIDIA-0
xrandr --auto

sudo chmod a+x /etc/X11/xinit/xinitrc.d/nvidia-script.sh

5. Set your Display Manager’s autostart to run xrandr on bootup. This will make your NVIDIA card output to your integrated display.

First, find which display manager you’re using:


cat /etc/systemd/system/display-manager.service | grep '/usr/bin'

it should display something like this:

ExecStart=/usr/bin/lightdm

For gdm (Gnome Display manager):
Nothing necessary, GDM will execute scripts in xinitrc.d

For lightdm:
LightDM only executes scripts in xinitrc.d for the session after login. We need to make it execute the script for the login screen as well:
sudo nano /etc/lightdm/lightdm.conf
find
[Seat:*]
and somewhere underneath it should be:
#display-setup-script=
change it to:


display-setup-script=/etc/X11/xinit/xinitrc.d/nvidia-script.sh

Make sure you remove the # sign.

6. Install the nvidia drivers,=
sudo pacman -S nvidia-dkms nvidia-utils lib32-nvidia-utils opencl-nvidia lib32-opencl-nvidia nvidia-settings

we use nvidia-dkms so that it is interchangeable with different kernels.

7. Create a pacman hook so that you do not have to run mkinitcpio after every kernel update:


/etc/pacman.d/hooks/nvidia.hook
[Trigger]
Operation=Install
Operation=Upgrade
Operation=Remove
Type=Package
Target=nvidia-dkms

[Action]
Depends=mkinitcpio
When=PostTransaction
Exec=/usr/bin/mkinitcpio -P

REBOOT!

NOTES REGARDING DRM AND TEARING:
To get rid of tearing, you need to enable nvidia-drm. This periodically breaks, just be warned. If you do an update and get a black screen, you’ll want a usb stick with arch on it so you can edit these files in case drm breaks. To enable drm:

sudo nano /boot/loader/entries/arch.conf

at the end of your options line, add:

nvidia-drm.modeset=1

save, close. then:

sudo nano /etc/mkinitcpio.conf

add nvidia_drm and nvidia_uvm to modules. it should look like this:

MODULES="nvidia nvidia_modeset nvidia_drm nvidia_uvm"

Again, this sometimes breaks during driver updates. if it does, just remember to remove them from /boot/loader/entries/arch.conf and /etc/mkinitcpio.conf

TROUBLESHOOTING:
-If you’re not sure the nvidia drivers installed, type modprobe nvidia in terminal. If you get no errors, they are installed.
-If at any time you get a blank black screen, ctrl+alt+f4 will drop you to tty terminal so that you can edit things you may have missed or done improperly.
-If at any time you get a looping screen (such as lightdm trying to load a misspelled script), boot from an Arch USB stick, then mount your root partition and arch-chroot into it, proceed to re-apply the steps above.
-If you are able to drop to tty/command screen, you can test your nvidia-script via startx. You can test your lightdm/gdm with sudo systemctl restart gdm/lightdm.