Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * arch/sh/drivers/superhyway/ops-sh4-202.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * SuperHyway bus support for SH4-202
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2005  Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/superhyway.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/addrspace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define PHYS_EMI_CBLOCK		P4SEGADDR(0x1ec00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define PHYS_EMI_DBLOCK		P4SEGADDR(0x08000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define PHYS_FEMI_CBLOCK	P4SEGADDR(0x1f800000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define PHYS_FEMI_DBLOCK	P4SEGADDR(0x00000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define PHYS_EPBR_BLOCK		P4SEGADDR(0x1de00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PHYS_DMAC_BLOCK		P4SEGADDR(0x1fa00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PHYS_PBR_BLOCK		P4SEGADDR(0x1fc00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static struct resource emi_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		.start	= PHYS_EMI_CBLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		.end	= PHYS_EMI_CBLOCK + 0x00300000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		.start	= PHYS_EMI_DBLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		.end	= PHYS_EMI_DBLOCK + 0x08000000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static struct superhyway_device emi_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	.name		= "emi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	.num_resources	= ARRAY_SIZE(emi_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	.resource	= emi_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static struct resource femi_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		.start	= PHYS_FEMI_CBLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		.end	= PHYS_FEMI_CBLOCK + 0x00100000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		.start	= PHYS_FEMI_DBLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		.end	= PHYS_FEMI_DBLOCK + 0x08000000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static struct superhyway_device femi_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	.name		= "femi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	.num_resources	= ARRAY_SIZE(femi_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	.resource	= femi_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static struct resource epbr_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		.start	= P4SEGADDR(0x1e7ffff8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		.end	= P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		.start	= PHYS_EPBR_BLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		.end	= PHYS_EPBR_BLOCK + 0x00a00000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static struct superhyway_device epbr_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	.name		= "epbr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	.num_resources	= ARRAY_SIZE(epbr_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.resource	= epbr_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) static struct resource dmac_resource = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	.start	= PHYS_DMAC_BLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	.end	= PHYS_DMAC_BLOCK + 0x00100000 - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static struct superhyway_device dmac_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	.name		= "dmac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	.num_resources	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	.resource	= &dmac_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static struct resource pbr_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	[0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.start	= P4SEGADDR(0x1ffffff8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.end	= P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.start	= PHYS_PBR_BLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		.end	= PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		.flags	= IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static struct superhyway_device pbr_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.name		= "pbr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.num_resources	= ARRAY_SIZE(pbr_resources),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	.resource	= pbr_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct superhyway_device *sh4202_devices[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	&emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	u32 vcrh, vcrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 * XXX: Even though the SH4-202 Evaluation Device documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 * indicates that VCRL is mapped first with VCRH at a + 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 * offset, the opposite seems to be true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	 * Some modules (PBR and ePBR for instance) also appear to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	 * VCRL/VCRH flipped in the documentation, but on the SH4-202
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * itself it appears that these are all consistently mapped with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * VCRH preceding VCRL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * Do not trust the documentation, for it is evil.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	vcrh = __raw_readl(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	vcrl = __raw_readl(base + sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	tmp = ((u64)vcrh << 32) | vcrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	memcpy(vcr, &tmp, sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	u64 tmp = *(u64 *)&vcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	__raw_writel((tmp >> 32) & 0xffffffff, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	__raw_writel(tmp & 0xffffffff, base + sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static struct superhyway_ops sh4202_superhyway_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	.read_vcr	= sh4202_read_vcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	.write_vcr	= sh4202_write_vcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct superhyway_bus superhyway_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ &sh4202_superhyway_ops, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int __init superhyway_scan_bus(struct superhyway_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return superhyway_add_devices(bus, sh4202_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				      ARRAY_SIZE(sh4202_devices));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)