Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ps4 linux 5 #680

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
c0e6b74
Update Kconfig
Razor246 May 9, 2019
b4e82fe
Update msi.h
Razor246 May 9, 2019
7eb0b79
Create ps4.h
Razor246 May 9, 2019
0bf4440
Update ps4.h
Razor246 May 9, 2019
b6a77e1
Update ps4.h
Razor246 May 9, 2019
d121a37
Update ps4.h
Razor246 May 9, 2019
93cb52c
Update setup.h
Razor246 May 9, 2019
90336b1
Update bootparam.h
Razor246 May 9, 2019
f688adf
Update msi.c
Razor246 May 9, 2019
db61c00
Update head64.c
Razor246 May 9, 2019
5504aff
Update Makefile
Razor246 May 9, 2019
9ebe313
Create Makefile
Razor246 May 9, 2019
2ba20ad
Create Makefile
Razor246 May 9, 2019
706b2e1
Create calibrate.c
Razor246 May 9, 2019
5f0864b
Create ps4.c
Razor246 May 9, 2019
b512522
Update Makefile
Razor246 May 9, 2019
c55c40c
Update ahci.c
Razor246 May 9, 2019
9a0e8b2
Update ahci.c
Razor246 May 9, 2019
2365c19
Update drm_irq.c
Razor246 May 9, 2019
0bb092d
Update msi.c
Razor246 May 9, 2019
e15c727
Update msi.c
Razor246 May 9, 2019
0810d11
Update msi.c
Razor246 May 9, 2019
37e8673
Update msi.c
Razor246 May 9, 2019
6b69437
Update drm_irq.c
Razor246 May 9, 2019
5e3af20
Merge pull request #1 from Razor246/ps4-5.1.0
Razor246 May 9, 2019
0ed2977
Update drm_pci.c
Razor246 May 9, 2019
626a8b2
Update drm_pci.c
Razor246 May 9, 2019
74009bd
Update Makefile
Razor246 May 9, 2019
a5afb87
Update atombios_dp.c
Razor246 May 9, 2019
44c70c8
Update atombios_encoders.c
Razor246 May 9, 2019
be1edeb
Update cik.c
Razor246 May 9, 2019
60cce2b
Update drm_pci.c
Razor246 May 10, 2019
3f23b1b
Update drm_pci.c
Razor246 May 10, 2019
2ebbe53
Update drm_irq.c
Razor246 May 10, 2019
e663a52
Update cik_sdma.c
Razor246 May 12, 2019
b8e3864
Create ps4_bridge.c
Razor246 May 12, 2019
d559296
Update radeon.h
Razor246 May 12, 2019
13f384d
Merge pull request #2 from Razor246/ps4-5.1.0
Razor246 May 12, 2019
59e7fe4
Update radeon_asic.c
Razor246 May 12, 2019
c3ecbcb
Update radeon_audio.c
Razor246 May 12, 2019
257df46
Update drm_irq.c
Razor246 May 12, 2019
b3b4caa
Update drm_irq.c
Razor246 May 12, 2019
b64379e
Merge pull request #3 from Razor246/ps4-5.1.0
Razor246 May 12, 2019
0a09b9c
Merge pull request #4 from torvalds/master
Razor246 May 12, 2019
b71c985
Update radeon_connectors.c
Razor246 May 12, 2019
df91991
Update radeon_connectors.c
Razor246 May 12, 2019
cc174ff
Update radeon_device.c
Razor246 May 12, 2019
48e10f3
Update radeon_display.c
Razor246 May 12, 2019
92d7574
Merge pull request #5 from Razor246/ps4-5.1.0
Razor246 May 12, 2019
509064b
Update radeon_drv.c
Razor246 May 13, 2019
fbab54b
Update radeon_encoders.c
Razor246 May 13, 2019
b011dc8
Update radeon_family.h
Razor246 May 13, 2019
9ae33fc
Update radeon_ib.c
Razor246 May 13, 2019
2233480
Update radeon_pm.c
Razor246 May 13, 2019
9e16805
Update radeon_ucode.h
Razor246 May 13, 2019
dc43d2f
Update radeon_uvd.c
Razor246 May 13, 2019
f5ec338
Update radeon_vce.c
Razor246 May 13, 2019
d70853a
Merge pull request #6 from Razor246/ps4-5.1.0
Razor246 May 13, 2019
87d6a75
Merge pull request #7 from torvalds/master
Razor246 May 13, 2019
c73ea1e
Update amd_iommu_init.c
Razor246 May 13, 2019
132c235
Update sdhci-pci-core.c
Razor246 May 13, 2019
951b6ef
Update sdhci-pci.h
Razor246 May 13, 2019
65e61a9
Merge pull request #8 from Razor246/ps4-5.1.0
Razor246 May 13, 2019
1d15846
Merge pull request #10 from Razor246/master
Razor246 May 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,14 @@ config X86_NUMACHIP
enable more than ~168 cores.
If you don't have one of these, you should say N here.

config X86_PS4
bool "Sony PlayStation 4"
depends on X86_64
depends on X86_EXTENDED_PLATFORM
depends on PCI
---help---
Select to include support for the Sony PlayStation 4 game console.

config X86_VSMP
bool "ScaleMP vSMP"
select HYPERVISOR_GUEST
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
msi_alloc_info_t *arg);

void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg);

#endif /* _ASM_X86_MSI_H */
60 changes: 60 additions & 0 deletions arch/x86/include/asm/ps4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* ps4.h: Sony PS4 platform setup code
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#ifndef _ASM_X86_PS4_H
#define _ASM_X86_PS4_H

#ifdef CONFIG_X86_PS4

#include <linux/irqdomain.h>

#define PS4_DEFAULT_TSC_FREQ 1594000000

#define EMC_TIMER_BASE 0xd0281000
#define EMC_TIMER_VALUE 0x28

extern unsigned long ps4_calibrate_tsc(void);

/*
* The PS4 Aeolia southbridge device is a composite device containing some
* standard-ish, some not-so-standard, and some completely custom functions,
* all using special MSI handling. This function does the equivalent of
* pci_enable_msi_range and friends, for those devices. Only works after the
* Aeolia MSR routing function device (function 4) has been probed.
* Returns 1 or count, depending on IRQ allocation constraints, or negative on
* error. Assigned IRQ(s) start at dev->irq.
*/
extern int apcie_assign_irqs(struct pci_dev *dev, int nvec);
extern void apcie_free_irqs(unsigned int virq, unsigned int nr_irqs);

extern int apcie_status(void);
extern int apcie_icc_cmd(u8 major, u16 minor, const void *data,
u16 length, void *reply, u16 reply_length);


#else

static inline int apcie_assign_irqs(struct pci_dev *dev, int nvec)
{
return -ENODEV;
}
static inline void apcie_free_irqs(unsigned int virq, unsigned int nvec)
{
}
static inline int apcie_status(void)
{
return -ENODEV;
}
static inline int apcie_icc_cmd(u8 major, u16 minor, const void *data,
u16 length, void *reply, u16 reply_length)
{
return -ENODEV;
}

#endif
#endif
6 changes: 6 additions & 0 deletions arch/x86/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ extern void x86_ce4100_early_setup(void);
static inline void x86_ce4100_early_setup(void) { }
#endif

#ifdef CONFIG_X86_PS4
extern void x86_ps4_early_setup(void);
#else
static inline void x86_ps4_early_setup(void) { }
#endif

#ifndef _SETUP

#include <asm/espfix.h>
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/uapi/asm/bootparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ enum x86_hardware_subarch {
X86_SUBARCH_XEN,
X86_SUBARCH_INTEL_MID,
X86_SUBARCH_CE4100,
X86_SUBARCH_PS4,
X86_NR_SUBARCHS,
};

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

static struct irq_domain *msi_default_domain;

static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
{
struct irq_cfg *cfg = irqd_cfg(data);

Expand Down
7 changes: 7 additions & 0 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,5 +467,12 @@ void __init x86_64_start_reservations(char *real_mode_data)
break;
}

/* Call the subarch specific early setup function */
switch (boot_params.hdr.hardware_subarch) {
case X86_SUBARCH_PS4:
x86_ps4_early_setup();
break;
}

start_kernel();
}
1 change: 1 addition & 0 deletions arch/x86/platform/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ obj-y += intel/
obj-y += intel-mid/
obj-y += intel-quark/
obj-y += olpc/
obj-y += ps4/
obj-y += scx200/
obj-y += sfi/
obj-y += ts5500/
Expand Down
1 change: 1 addition & 0 deletions arch/x86/platform/PS4/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-$(CONFIG_X86_PS4) += ps4.o calibrate.o
116 changes: 116 additions & 0 deletions arch/x86/platform/PS4/calibrate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* calibrate.c: Sony PS4 TSC/LAPIC calibration
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/

#define pr_fmt(fmt) "ps4: " fmt

#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/msr.h>
#include <asm/ps4.h>
#include <asm/delay.h>
#include <asm/apic.h>

/* The PS4 southbridge (Aeolia) has an EMC timer that ticks at 32.768kHz,
* which seems to be an appropriate clock reference for calibration. Both TSC
* and the LAPIC timer are based on the core clock frequency and thus can be
* calibrated together. */
static void __iomem *emc_timer = NULL;

static __init inline u32 emctimer_read32(unsigned int reg)
{
return ioread32(emc_timer + reg);
}

static __init inline void emctimer_write32(unsigned int reg, u32 val)
{
iowrite32(val, emc_timer + reg);
}

static __init inline u32 emctimer_read(void)
{
u32 t1, t2;
t1 = emctimer_read32(EMC_TIMER_VALUE);
while (1) {
t2 = emctimer_read32(EMC_TIMER_VALUE);
if (t1 == t2)
return t1;
t1 = t2;
}
}

static __init unsigned long ps4_measure_tsc_freq(void)
{
unsigned long ret = 0;
u32 t1, t2;
u64 tsc1, tsc2;

// This is part of the Aeolia pcie device, but it's too early to
// do this in a driver.
emc_timer = ioremap(EMC_TIMER_BASE, 0x100);
if (!emc_timer)
goto fail;

// reset/start the timer
emctimer_write32(0x84, emctimer_read32(0x84) & (~0x01));
// udelay is not calibrated yet, so this is likely wildly off, but good
// enough to work.
udelay(300);
emctimer_write32(0x00, emctimer_read32(0x00) | 0x01);
emctimer_write32(0x84, emctimer_read32(0x84) | 0x01);

t1 = emctimer_read();
tsc1 = tsc2 = rdtsc();

while (emctimer_read() == t1) {
// 0.1s timeout should be enough
tsc2 = rdtsc();
if ((tsc2 - tsc1) > (PS4_DEFAULT_TSC_FREQ/10)) {
pr_warn("EMC timer is broken.\n");
goto fail;
}
}
pr_info("EMC timer started in %lld TSC ticks\n", tsc2 - tsc1);

// Wait for a tick boundary
t1 = emctimer_read();
while ((t2 = emctimer_read()) == t1);
tsc1 = rdtsc();

// Wait for 1024 ticks to elapse (31.25ms)
// We don't need to wait very long, as we are looking for transitions.
// At this value, a TSC uncertainty of ~50 ticks corresponds to 1ppm of
// clock accuracy.
while ((emctimer_read() - t2) < 1024);
tsc2 = rdtsc();

// TSC rate is 32 times the elapsed time
ret = (tsc2 - tsc1) * 32;

pr_info("Calibrated TSC frequency: %ld kHz\n", ret);
fail:
if (emc_timer) {
iounmap(emc_timer);
emc_timer = NULL;
}
return ret;
}

unsigned long __init ps4_calibrate_tsc(void)
{
unsigned long tsc_freq = ps4_measure_tsc_freq();

if (!tsc_freq) {
pr_warn("Unable to measure TSC frequency, assuming default.\n");
tsc_freq = PS4_DEFAULT_TSC_FREQ;
}

lapic_timer_frequency = (tsc_freq + 8 * HZ) / (16 * HZ);

return (tsc_freq + 500) / 1000;
}
76 changes: 76 additions & 0 deletions arch/x86/platform/PS4/ps4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* ps4.c: Sony PS4 platform setup code
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/

#define pr_fmt(fmt) "ps4: " fmt

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/scatterlist.h>
#include <linux/sfi.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/notifier.h>

#include <asm/setup.h>
#include <asm/mpspec_def.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/io.h>
#include <asm/i8259.h>
#include <asm/apb_timer.h>
#include <asm/reboot.h>
#include <asm/msr.h>
#include <asm/ps4.h>

static bool is_ps4;
bool apcie_initialized;

/*
* The RTC is part of the Aeolia PCI device and will be implemented there as
* an RTC class device; stub these out.
*/
static void dummy_get_wallclock(struct timespec *now)
{
now->tv_sec = now->tv_nsec = 0;
}
static int dummy_set_wallclock(const struct timespec *now)
{
return -ENODEV;
}

/*
* Provide a way for generic drivers to query for the availability of the
* PS4 apcie driver/device, which is a dependency for them.
*/
int apcie_status(void)
{
if (!is_ps4)
return -ENODEV;
return apcie_initialized;
}
EXPORT_SYMBOL_GPL(apcie_status);

void icc_reboot(void);

/*
* PS4 specific x86_init function overrides and early setup calls.
*/
void __init x86_ps4_early_setup(void)
{
pr_info("x86_ps4_early_setup: PS4 early setup\n");
is_ps4 = true;
x86_platform.calibrate_tsc = ps4_calibrate_tsc;
x86_platform.get_wallclock = dummy_get_wallclock;
x86_platform.set_wallclock = dummy_set_wallclock;

legacy_pic = &null_legacy_pic;
machine_ops.emergency_restart = icc_reboot;
}
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ obj-$(CONFIG_SPI) += spi/
obj-$(CONFIG_SPMI) += spmi/
obj-$(CONFIG_HSI) += hsi/
obj-$(CONFIG_SLIMBUS) += slimbus/
obj-$(CONFIG_X86_PS4) += ps4/
obj-y += net/
obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
Expand Down
Loading