18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_MACHDEP_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_MACHDEP_H
48c2ecf20Sopenharmony_ci#ifdef __KERNEL__
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/seq_file.h>
78c2ecf20Sopenharmony_ci#include <linux/init.h>
88c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
98c2ecf20Sopenharmony_ci#include <linux/export.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <asm/setup.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/* We export this macro for external modules like Alsa to know if
148c2ecf20Sopenharmony_ci * ppc_md.feature_call is implemented or not
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci#define CONFIG_PPC_HAS_FEATURE_CALLS
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct pt_regs;
198c2ecf20Sopenharmony_cistruct pci_bus;
208c2ecf20Sopenharmony_cistruct device_node;
218c2ecf20Sopenharmony_cistruct iommu_table;
228c2ecf20Sopenharmony_cistruct rtc_time;
238c2ecf20Sopenharmony_cistruct file;
248c2ecf20Sopenharmony_cistruct pci_controller;
258c2ecf20Sopenharmony_cistruct kimage;
268c2ecf20Sopenharmony_cistruct pci_host_bridge;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistruct machdep_calls {
298c2ecf20Sopenharmony_ci	char		*name;
308c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64
318c2ecf20Sopenharmony_ci#ifdef CONFIG_PM
328c2ecf20Sopenharmony_ci	void		(*iommu_save)(void);
338c2ecf20Sopenharmony_ci	void		(*iommu_restore)(void);
348c2ecf20Sopenharmony_ci#endif
358c2ecf20Sopenharmony_ci#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
368c2ecf20Sopenharmony_ci	unsigned long	(*memory_block_size)(void);
378c2ecf20Sopenharmony_ci#endif
388c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC64 */
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	void		(*dma_set_mask)(struct device *dev, u64 dma_mask);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	int		(*probe)(void);
438c2ecf20Sopenharmony_ci	void		(*setup_arch)(void); /* Optional, may be NULL */
448c2ecf20Sopenharmony_ci	/* Optional, may be NULL. */
458c2ecf20Sopenharmony_ci	void		(*show_cpuinfo)(struct seq_file *m);
468c2ecf20Sopenharmony_ci	void		(*show_percpuinfo)(struct seq_file *m, int i);
478c2ecf20Sopenharmony_ci	/* Returns the current operating frequency of "cpu" in Hz */
488c2ecf20Sopenharmony_ci	unsigned long  	(*get_proc_freq)(unsigned int cpu);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	void		(*init_IRQ)(void);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/* Return an irq, or 0 to indicate there are none pending. */
538c2ecf20Sopenharmony_ci	unsigned int	(*get_irq)(void);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* PCI stuff */
568c2ecf20Sopenharmony_ci	/* Called after allocating resources */
578c2ecf20Sopenharmony_ci	void		(*pcibios_fixup)(void);
588c2ecf20Sopenharmony_ci	void		(*pci_irq_fixup)(struct pci_dev *dev);
598c2ecf20Sopenharmony_ci	int		(*pcibios_root_bridge_prepare)(struct pci_host_bridge
608c2ecf20Sopenharmony_ci				*bridge);
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	/* finds all the pci_controllers present at boot */
638c2ecf20Sopenharmony_ci	void 		(*discover_phbs)(void);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	/* To setup PHBs when using automatic OF platform driver for PCI */
668c2ecf20Sopenharmony_ci	int		(*pci_setup_phb)(struct pci_controller *host);
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	void __noreturn	(*restart)(char *cmd);
698c2ecf20Sopenharmony_ci	void __noreturn (*halt)(void);
708c2ecf20Sopenharmony_ci	void		(*panic)(char *str);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	long		(*time_init)(void); /* Optional, may be NULL */
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	int		(*set_rtc_time)(struct rtc_time *);
758c2ecf20Sopenharmony_ci	void		(*get_rtc_time)(struct rtc_time *);
768c2ecf20Sopenharmony_ci	time64_t	(*get_boot_time)(void);
778c2ecf20Sopenharmony_ci	unsigned char 	(*rtc_read_val)(int addr);
788c2ecf20Sopenharmony_ci	void		(*rtc_write_val)(int addr, unsigned char val);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	void		(*calibrate_decr)(void);
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	void		(*progress)(char *, unsigned short);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/* Interface for platform error logging */
858c2ecf20Sopenharmony_ci	void 		(*log_error)(char *buf, unsigned int err_type, int fatal);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	unsigned char 	(*nvram_read_val)(int addr);
888c2ecf20Sopenharmony_ci	void		(*nvram_write_val)(int addr, unsigned char val);
898c2ecf20Sopenharmony_ci	ssize_t		(*nvram_write)(char *buf, size_t count, loff_t *index);
908c2ecf20Sopenharmony_ci	ssize_t		(*nvram_read)(char *buf, size_t count, loff_t *index);
918c2ecf20Sopenharmony_ci	ssize_t		(*nvram_size)(void);
928c2ecf20Sopenharmony_ci	void		(*nvram_sync)(void);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* Exception handlers */
958c2ecf20Sopenharmony_ci	int		(*system_reset_exception)(struct pt_regs *regs);
968c2ecf20Sopenharmony_ci	int 		(*machine_check_exception)(struct pt_regs *regs);
978c2ecf20Sopenharmony_ci	int		(*handle_hmi_exception)(struct pt_regs *regs);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/* Early exception handlers called in realmode */
1008c2ecf20Sopenharmony_ci	int		(*hmi_exception_early)(struct pt_regs *regs);
1018c2ecf20Sopenharmony_ci	long		(*machine_check_early)(struct pt_regs *regs);
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	/* Called during machine check exception to retrive fixup address. */
1048c2ecf20Sopenharmony_ci	bool		(*mce_check_early_recovery)(struct pt_regs *regs);
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	/* Motherboard/chipset features. This is a kind of general purpose
1078c2ecf20Sopenharmony_ci	 * hook used to control some machine specific features (like reset
1088c2ecf20Sopenharmony_ci	 * lines, chip power control, etc...).
1098c2ecf20Sopenharmony_ci	 */
1108c2ecf20Sopenharmony_ci	long	 	(*feature_call)(unsigned int feature, ...);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	/* Get legacy PCI/IDE interrupt mapping */
1138c2ecf20Sopenharmony_ci	int		(*pci_get_legacy_ide_irq)(struct pci_dev *dev, int channel);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	/* Get access protection for /dev/mem */
1168c2ecf20Sopenharmony_ci	pgprot_t	(*phys_mem_access_prot)(struct file *file,
1178c2ecf20Sopenharmony_ci						unsigned long pfn,
1188c2ecf20Sopenharmony_ci						unsigned long size,
1198c2ecf20Sopenharmony_ci						pgprot_t vma_prot);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/*
1228c2ecf20Sopenharmony_ci	 * Function for waiting for work with reduced power in idle loop;
1238c2ecf20Sopenharmony_ci	 * called with interrupts disabled.
1248c2ecf20Sopenharmony_ci	 */
1258c2ecf20Sopenharmony_ci	void		(*power_save)(void);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	/* Function to enable performance monitor counters for this
1288c2ecf20Sopenharmony_ci	   platform, called once per cpu. */
1298c2ecf20Sopenharmony_ci	void		(*enable_pmcs)(void);
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	/* Set DABR for this platform, leave empty for default implementation */
1328c2ecf20Sopenharmony_ci	int		(*set_dabr)(unsigned long dabr,
1338c2ecf20Sopenharmony_ci				    unsigned long dabrx);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	/* Set DAWR for this platform, leave empty for default implementation */
1368c2ecf20Sopenharmony_ci	int		(*set_dawr)(int nr, unsigned long dawr,
1378c2ecf20Sopenharmony_ci				    unsigned long dawrx);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC32	/* XXX for now */
1408c2ecf20Sopenharmony_ci	/* A general init function, called by ppc_init in init/main.c.
1418c2ecf20Sopenharmony_ci	   May be NULL. */
1428c2ecf20Sopenharmony_ci	void		(*init)(void);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	void		(*kgdb_map_scc)(void);
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	/*
1478c2ecf20Sopenharmony_ci	 * optional PCI "hooks"
1488c2ecf20Sopenharmony_ci	 */
1498c2ecf20Sopenharmony_ci	/* Called at then very end of pcibios_init() */
1508c2ecf20Sopenharmony_ci	void (*pcibios_after_init)(void);
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC32 */
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	/* Called in indirect_* to avoid touching devices */
1558c2ecf20Sopenharmony_ci	int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	/* Called after PPC generic resource fixup to perform
1588c2ecf20Sopenharmony_ci	   machine specific fixups */
1598c2ecf20Sopenharmony_ci	void (*pcibios_fixup_resources)(struct pci_dev *);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	/* Called for each PCI bus in the system when it's probed */
1628c2ecf20Sopenharmony_ci	void (*pcibios_fixup_bus)(struct pci_bus *);
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	/* Called after scan and before resource survey */
1658c2ecf20Sopenharmony_ci	void (*pcibios_fixup_phb)(struct pci_controller *hose);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	/*
1688c2ecf20Sopenharmony_ci	 * Called after device has been added to bus and
1698c2ecf20Sopenharmony_ci	 * before sysfs has been created.
1708c2ecf20Sopenharmony_ci	 */
1718c2ecf20Sopenharmony_ci	void (*pcibios_bus_add_device)(struct pci_dev *pdev);
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	resource_size_t (*pcibios_default_alignment)(void);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV
1768c2ecf20Sopenharmony_ci	void (*pcibios_fixup_sriov)(struct pci_dev *pdev);
1778c2ecf20Sopenharmony_ci	resource_size_t (*pcibios_iov_resource_alignment)(struct pci_dev *, int resno);
1788c2ecf20Sopenharmony_ci	int (*pcibios_sriov_enable)(struct pci_dev *pdev, u16 num_vfs);
1798c2ecf20Sopenharmony_ci	int (*pcibios_sriov_disable)(struct pci_dev *pdev);
1808c2ecf20Sopenharmony_ci#endif /* CONFIG_PCI_IOV */
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	/* Called to shutdown machine specific hardware not already controlled
1838c2ecf20Sopenharmony_ci	 * by other drivers.
1848c2ecf20Sopenharmony_ci	 */
1858c2ecf20Sopenharmony_ci	void (*machine_shutdown)(void);
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci#ifdef CONFIG_KEXEC_CORE
1888c2ecf20Sopenharmony_ci	void (*kexec_cpu_down)(int crash_shutdown, int secondary);
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	/* Called to do what every setup is needed on image and the
1918c2ecf20Sopenharmony_ci	 * reboot code buffer. Returns 0 on success.
1928c2ecf20Sopenharmony_ci	 * Provide your own (maybe dummy) implementation if your platform
1938c2ecf20Sopenharmony_ci	 * claims to support kexec.
1948c2ecf20Sopenharmony_ci	 */
1958c2ecf20Sopenharmony_ci	int (*machine_kexec_prepare)(struct kimage *image);
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	/* Called to perform the _real_ kexec.
1988c2ecf20Sopenharmony_ci	 * Do NOT allocate memory or fail here. We are past the point of
1998c2ecf20Sopenharmony_ci	 * no return.
2008c2ecf20Sopenharmony_ci	 */
2018c2ecf20Sopenharmony_ci	void (*machine_kexec)(struct kimage *image);
2028c2ecf20Sopenharmony_ci#endif /* CONFIG_KEXEC_CORE */
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci#ifdef CONFIG_SUSPEND
2058c2ecf20Sopenharmony_ci	/* These are called to disable and enable, respectively, IRQs when
2068c2ecf20Sopenharmony_ci	 * entering a suspend state.  If NULL, then the generic versions
2078c2ecf20Sopenharmony_ci	 * will be called.  The generic versions disable/enable the
2088c2ecf20Sopenharmony_ci	 * decrementer along with interrupts.
2098c2ecf20Sopenharmony_ci	 */
2108c2ecf20Sopenharmony_ci	void (*suspend_disable_irqs)(void);
2118c2ecf20Sopenharmony_ci	void (*suspend_enable_irqs)(void);
2128c2ecf20Sopenharmony_ci#endif
2138c2ecf20Sopenharmony_ci	int (*suspend_disable_cpu)(void);
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
2168c2ecf20Sopenharmony_ci	ssize_t (*cpu_probe)(const char *, size_t);
2178c2ecf20Sopenharmony_ci	ssize_t (*cpu_release)(const char *, size_t);
2188c2ecf20Sopenharmony_ci#endif
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci#ifdef CONFIG_ARCH_RANDOM
2218c2ecf20Sopenharmony_ci	int (*get_random_seed)(unsigned long *v);
2228c2ecf20Sopenharmony_ci#endif
2238c2ecf20Sopenharmony_ci};
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ciextern void e500_idle(void);
2268c2ecf20Sopenharmony_ciextern void power4_idle(void);
2278c2ecf20Sopenharmony_ciextern void ppc6xx_idle(void);
2288c2ecf20Sopenharmony_ciextern void book3e_idle(void);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci/*
2318c2ecf20Sopenharmony_ci * ppc_md contains a copy of the machine description structure for the
2328c2ecf20Sopenharmony_ci * current platform. machine_id contains the initial address where the
2338c2ecf20Sopenharmony_ci * description was found during boot.
2348c2ecf20Sopenharmony_ci */
2358c2ecf20Sopenharmony_ciextern struct machdep_calls ppc_md;
2368c2ecf20Sopenharmony_ciextern struct machdep_calls *machine_id;
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci#define __machine_desc __section(".machine.desc")
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci#define define_machine(name)					\
2418c2ecf20Sopenharmony_ci	extern struct machdep_calls mach_##name;		\
2428c2ecf20Sopenharmony_ci	EXPORT_SYMBOL(mach_##name);				\
2438c2ecf20Sopenharmony_ci	struct machdep_calls mach_##name __machine_desc =
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci#define machine_is(name) \
2468c2ecf20Sopenharmony_ci	({ \
2478c2ecf20Sopenharmony_ci		extern struct machdep_calls mach_##name \
2488c2ecf20Sopenharmony_ci			__attribute__((weak));		 \
2498c2ecf20Sopenharmony_ci		machine_id == &mach_##name; \
2508c2ecf20Sopenharmony_ci	})
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ciextern void probe_machine(void);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_PMAC
2558c2ecf20Sopenharmony_ci/*
2568c2ecf20Sopenharmony_ci * Power macintoshes have either a CUDA, PMU or SMU controlling
2578c2ecf20Sopenharmony_ci * system reset, power, NVRAM, RTC.
2588c2ecf20Sopenharmony_ci */
2598c2ecf20Sopenharmony_citypedef enum sys_ctrler_kind {
2608c2ecf20Sopenharmony_ci	SYS_CTRLER_UNKNOWN = 0,
2618c2ecf20Sopenharmony_ci	SYS_CTRLER_CUDA = 1,
2628c2ecf20Sopenharmony_ci	SYS_CTRLER_PMU = 2,
2638c2ecf20Sopenharmony_ci	SYS_CTRLER_SMU = 3,
2648c2ecf20Sopenharmony_ci} sys_ctrler_t;
2658c2ecf20Sopenharmony_ciextern sys_ctrler_t sys_ctrler;
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_PMAC */
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_cistatic inline void log_error(char *buf, unsigned int err_type, int fatal)
2708c2ecf20Sopenharmony_ci{
2718c2ecf20Sopenharmony_ci	if (ppc_md.log_error)
2728c2ecf20Sopenharmony_ci		ppc_md.log_error(buf, err_type, fatal);
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci#define __define_machine_initcall(mach, fn, id) \
2768c2ecf20Sopenharmony_ci	static int __init __machine_initcall_##mach##_##fn(void) { \
2778c2ecf20Sopenharmony_ci		if (machine_is(mach)) return fn(); \
2788c2ecf20Sopenharmony_ci		return 0; \
2798c2ecf20Sopenharmony_ci	} \
2808c2ecf20Sopenharmony_ci	__define_initcall(__machine_initcall_##mach##_##fn, id);
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci#define machine_early_initcall(mach, fn)	__define_machine_initcall(mach, fn, early)
2838c2ecf20Sopenharmony_ci#define machine_core_initcall(mach, fn)		__define_machine_initcall(mach, fn, 1)
2848c2ecf20Sopenharmony_ci#define machine_core_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 1s)
2858c2ecf20Sopenharmony_ci#define machine_postcore_initcall(mach, fn)	__define_machine_initcall(mach, fn, 2)
2868c2ecf20Sopenharmony_ci#define machine_postcore_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 2s)
2878c2ecf20Sopenharmony_ci#define machine_arch_initcall(mach, fn)		__define_machine_initcall(mach, fn, 3)
2888c2ecf20Sopenharmony_ci#define machine_arch_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 3s)
2898c2ecf20Sopenharmony_ci#define machine_subsys_initcall(mach, fn)	__define_machine_initcall(mach, fn, 4)
2908c2ecf20Sopenharmony_ci#define machine_subsys_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 4s)
2918c2ecf20Sopenharmony_ci#define machine_fs_initcall(mach, fn)		__define_machine_initcall(mach, fn, 5)
2928c2ecf20Sopenharmony_ci#define machine_fs_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 5s)
2938c2ecf20Sopenharmony_ci#define machine_rootfs_initcall(mach, fn)	__define_machine_initcall(mach, fn, rootfs)
2948c2ecf20Sopenharmony_ci#define machine_device_initcall(mach, fn)	__define_machine_initcall(mach, fn, 6)
2958c2ecf20Sopenharmony_ci#define machine_device_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 6s)
2968c2ecf20Sopenharmony_ci#define machine_late_initcall(mach, fn)		__define_machine_initcall(mach, fn, 7)
2978c2ecf20Sopenharmony_ci#define machine_late_initcall_sync(mach, fn)	__define_machine_initcall(mach, fn, 7s)
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
3008c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_MACHDEP_H */
301