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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *   Octeon Bootbus flash setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 2007, 2008 Cavium Networks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/semaphore.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mtd/mtd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/mtd/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mtd/partitions.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/octeon/octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static struct map_info flash_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static struct mtd_info *mymtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static const char *part_probe_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	"cmdlinepart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #ifdef CONFIG_MTD_REDBOOT_PARTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	"RedBoot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static map_word octeon_flash_map_read(struct map_info *map, unsigned long ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	map_word r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	down(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	r = inline_map_read(map, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	up(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static void octeon_flash_map_write(struct map_info *map, const map_word datum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 				   unsigned long ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	down(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	inline_map_write(map, datum, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	up(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static void octeon_flash_map_copy_from(struct map_info *map, void *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 				       unsigned long from, ssize_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	down(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	inline_map_copy_from(map, to, from, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	up(&octeon_bootbus_sem);
^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 void octeon_flash_map_copy_to(struct map_info *map, unsigned long to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				     const void *from, ssize_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	down(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	inline_map_copy_to(map, to, from, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	up(&octeon_bootbus_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * Module/ driver initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * Returns Zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static int octeon_flash_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	union cvmx_mio_boot_reg_cfgx region_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u32 cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	r = of_property_read_u32(np, "reg", &cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return r;
^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) 	 * Read the bootbus region 0 setup to determine the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * address of the flash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (region_cfg.s.en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		 * The bootloader always takes the flash and sets its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		 * address so the entire flash fits below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		 * 0x1fc00000. This way the flash aliases to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		 * 0x1fc00000 for booting. Software can access the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		 * full flash at the true address, while core boot can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		 * access 4MB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		/* Use this name so old part lines work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		flash_map.name = "phys_mapped_flash";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		flash_map.phys = region_cfg.s.base << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		flash_map.size = 0x1fc00000 - flash_map.phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		/* 8-bit bus (0 + 1) or 16-bit bus (1 + 1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		flash_map.bankwidth = region_cfg.s.width + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		flash_map.virt = ioremap(flash_map.phys, flash_map.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		pr_notice("Bootbus flash: Setting flash for %luMB flash at "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			  "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		WARN_ON(!map_bankwidth_supported(flash_map.bankwidth));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		flash_map.read = octeon_flash_map_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		flash_map.write = octeon_flash_map_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		flash_map.copy_from = octeon_flash_map_copy_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		flash_map.copy_to = octeon_flash_map_copy_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		mymtd = do_map_probe("cfi_probe", &flash_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (mymtd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			mymtd->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			mtd_device_parse_register(mymtd, part_probe_types,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 						  NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			pr_err("Failed to register MTD device for flash\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static const struct of_device_id of_flash_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.compatible	= "cfi-flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) MODULE_DEVICE_TABLE(of, of_flash_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static struct platform_driver of_flash_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		.name = "octeon-of-flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.of_match_table = of_flash_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	.probe		= octeon_flash_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int octeon_flash_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return platform_driver_register(&of_flash_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) late_initcall(octeon_flash_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) MODULE_LICENSE("GPL");