arch/powerpc/platforms/85xx/p1022_ds.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/85xx/p1022_ds.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/85xx/p1022_ds.c
Extension
.c
Size
14870 bytes
Lines
564
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fsl_law {
	u32	lawbar;
	u32	reserved1;
	u32	lawar;
	u32	reserved[5];
};

#define LAWBAR_MASK	0x00F00000
#define LAWBAR_SHIFT	12

#define LAWAR_EN	0x80000000
#define LAWAR_TGT_MASK	0x01F00000
#define LAW_TRGT_IF_LBC	(0x04 << 20)

#define LAWAR_MASK	(LAWAR_EN | LAWAR_TGT_MASK)
#define LAWAR_MATCH	(LAWAR_EN | LAW_TRGT_IF_LBC)

#define BR_BA		0xFFFF8000

/*
 * Map a BRx value to a physical address
 *
 * The localbus BRx registers only store the lower 32 bits of the address.  To
 * obtain the upper four bits, we need to scan the LAW table.  The entry which
 * maps to the localbus will contain the upper four bits.
 */
static phys_addr_t lbc_br_to_phys(const void *ecm, unsigned int count, u32 br)
{
#ifndef CONFIG_PHYS_64BIT
	/*
	 * If we only have 32-bit addressing, then the BRx address *is* the
	 * physical address.
	 */
	return br & BR_BA;
#else
	const struct fsl_law *law = ecm + 0xc08;
	unsigned int i;

	for (i = 0; i < count; i++) {
		u64 lawbar = in_be32(&law[i].lawbar);
		u32 lawar = in_be32(&law[i].lawar);

		if ((lawar & LAWAR_MASK) == LAWAR_MATCH)
			/* Extract the upper four bits */
			return (br & BR_BA) | ((lawbar & LAWBAR_MASK) << 12);
	}

	return 0;
#endif
}

/**
 * p1022ds_set_monitor_port: switch the output to a different monitor port
 */
static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
{
	struct device_node *guts_node;
	struct device_node *lbc_node = NULL;
	struct device_node *law_node = NULL;
	struct ccsr_guts __iomem *guts;
	struct fsl_lbc_regs *lbc = NULL;
	void *ecm = NULL;
	u8 __iomem *lbc_lcs0_ba = NULL;
	u8 __iomem *lbc_lcs1_ba = NULL;
	phys_addr_t cs0_addr, cs1_addr;
	u32 br0, or0, br1, or1;
	const __be32 *iprop;
	unsigned int num_laws;
	u8 b;

	/* Map the global utilities registers. */
	guts_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
	if (!guts_node) {
		pr_err("p1022ds: missing global utilities device node\n");
		return;
	}

	guts = of_iomap(guts_node, 0);
	if (!guts) {
		pr_err("p1022ds: could not map global utilities device\n");
		goto exit;
	}

	lbc_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
	if (!lbc_node) {
		pr_err("p1022ds: missing localbus node\n");
		goto exit;
	}

	lbc = of_iomap(lbc_node, 0);

Annotation

Implementation Notes