parisc: Add PDC PAT cell_info() and pd_get_pdc_revisions() functions

Add wrappers for the PDC_PAT_CELL_GET_INFO and
PDC_PAT_PD_GET_PDC_INTERF_REV PAT PDC subfunctions.

Both provide access to the PAT capability bitfield which can guide us if
simultaneous PTLBs are allowed on the bus, and if firmware will
rendezvous all processors within PDCE_Check in case of an HPMC.

Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Helge Deller 2018-10-19 22:06:36 +02:00
parent 32c1ceeabd
commit fe8376dbbd
2 changed files with 98 additions and 13 deletions

View File

@ -173,6 +173,16 @@
/* PDC PAT PD */
#define PDC_PAT_PD 74L /* Protection Domain Info */
#define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */
#define PDC_PAT_PD_GET_PDC_INTERF_REV 1L /* Get PDC Interface Revisions */
#define PDC_PAT_CAPABILITY_BIT_PDC_SERIALIZE (1UL << 0)
#define PDC_PAT_CAPABILITY_BIT_PDC_POLLING (1UL << 1)
#define PDC_PAT_CAPABILITY_BIT_PDC_NBC (1UL << 2) /* non-blocking calls */
#define PDC_PAT_CAPABILITY_BIT_PDC_UFO (1UL << 3)
#define PDC_PAT_CAPABILITY_BIT_PDC_IODC_32 (1UL << 4)
#define PDC_PAT_CAPABILITY_BIT_PDC_IODC_64 (1UL << 5)
#define PDC_PAT_CAPABILITY_BIT_PDC_HPMC_RENDEZ (1UL << 6)
#define PDC_PAT_CAPABILITY_BIT_SIMULTANEOUS_PTLB (1UL << 7)
/* PDC_PAT_PD_GET_ADDR_MAP entry types */
#define PAT_MEMORY_DESCRIPTOR 1
@ -305,18 +315,29 @@ struct pdc_pat_pd_addr_map_entry {
** PDC_PAT_CELL_GET_INFO return block
*/
typedef struct pdc_pat_cell_info_rtn_block {
unsigned long cpu_info;
unsigned long cell_info;
unsigned long cell_location;
unsigned long reo_location;
unsigned long mem_size;
unsigned long dimm_status;
unsigned long pdc_rev;
unsigned long fabric_info0;
unsigned long fabric_info1;
unsigned long fabric_info2;
unsigned long fabric_info3;
unsigned long reserved[21];
unsigned long capabilities; /* see PDC_PAT_CAPABILITY_BIT_* */
unsigned long reserved0[2];
unsigned long cell_info; /* 0x20 */
unsigned long cell_phys_location;
unsigned long cpu_info;
unsigned long cpu_speed;
unsigned long io_chassis_phys_location;
unsigned long cell_io_information;
unsigned long reserved1[2];
unsigned long io_slot_info_size; /* 0x60 */
struct {
unsigned long header, info0, info1;
unsigned long phys_loc, hw_path;
} io_slot[16];
unsigned long cell_mem_size; /* 0x2e8 */
unsigned long cell_dimm_info_size;
unsigned long dimm_info[16];
unsigned long fabric_info_size; /* 0x3f8 */
struct { /* 0x380 */
unsigned long fabric_info_xbc_port;
unsigned long rc_attached_to_xbc;
} xbc[8*4];
} pdc_pat_cell_info_rtn_block_t;
@ -334,12 +355,19 @@ typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;
extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr);
extern int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
unsigned long *actcnt, unsigned long offset,
unsigned long cell_number);
extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc,
unsigned long mod, unsigned long view_type, void *mem_addr);
extern int pdc_pat_cell_num_to_loc(void *, unsigned long);
extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, unsigned long hpa);
extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset);
extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
unsigned long count, unsigned long offset);
extern int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
unsigned long *pat_rev, unsigned long *pdc_cap);
extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val);
extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val);

View File

@ -1325,6 +1325,36 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
return retval;
}
/**
* pdc_pat_cell_info - Retrieve the cell's information.
* @info: The pointer to a struct pdc_pat_cell_info_rtn_block.
* @actcnt: The number of bytes which should be written to info.
* @offset: offset of the structure.
* @cell_number: The cell number which should be asked, or -1 for current cell.
*
* This PDC call returns information about the given cell (or all cells).
*/
int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
unsigned long *actcnt, unsigned long offset,
unsigned long cell_number)
{
int retval;
unsigned long flags;
struct pdc_pat_cell_info_rtn_block result;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_INFO,
__pa(pdc_result), __pa(&result), *actcnt,
offset, cell_number);
if (!retval) {
*actcnt = pdc_result[0];
memcpy(info, &result, *actcnt);
}
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/**
* pdc_pat_cpu_get_number - Retrieve the cpu number.
* @cpu_info: The return buffer.
@ -1412,6 +1442,33 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
return retval;
}
/**
* pdc_pat_pd_get_PDC_interface_revisions - Retrieve PDC interface revisions.
* @legacy_rev: The legacy revision.
* @pat_rev: The PAT revision.
* @pdc_cap: The PDC capabilities.
*
*/
int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
unsigned long *pat_rev, unsigned long *pdc_cap)
{
int retval;
unsigned long flags;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_PDC_INTERF_REV,
__pa(pdc_result));
if (retval == PDC_OK) {
*legacy_rev = pdc_result[0];
*pat_rev = pdc_result[1];
*pdc_cap = pdc_result[2];
}
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/**
* pdc_pat_io_pci_cfg_read - Read PCI configuration space.
* @pci_addr: PCI configuration space address for which the read request is being made.