/* * Copyright (C) ST-Ericsson SA 2011 * Author: Maxime Coquelin for ST-Ericsson. * License terms: GNU General Public License (GPL), version 2 * * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. */ #ifndef _LINUX_PASR_H #define _LINUX_PASR_H #include #include #ifdef CONFIG_PASR #define PASR_MAX_SECTION_NR_PER_DIE 8 #define PASR_MAX_DIE_NR 4 extern u64 section_size; extern unsigned int section_bit; /** * struct pasr_section - Represent either a DDR Bank or Segment depending on * the DDR configuration (Bank-Row-Column or Row-Bank-Coloumn) * * @start: Start address of the segment. * @pair: Pointer on another segment in case of dependency (e.g. interleaving). * Masking of the dependant segments have to be done accordingly. * @free_size: Represents the free memory size in the segment. * @lock: Protect the free_size counter * @die: Pointer to the Die the segment is part of. */ struct pasr_section { phys_addr_t start; struct pasr_section *pair; u64 free_size; spinlock_t *lock; struct pasr_die *die; }; /** * struct pasr_die - Represent a DDR die * * @start: Start address of the die. * @end: End address of the die. * @idx: Index of the die. * @nr_sections: Number of Bank or Segment in the die. * @section: Table of the die's segments. * @mem_reg: Represents the PASR mask of the die. It is either MR16 or MR17, * depending on the addressing configuration (RBC or BRC). * @apply_mask: Callback registred by the platform's PASR driver to apply the * calculated PASR mask. * @cookie: Private data for the platform's PASR driver. */ struct pasr_die { phys_addr_t start; phys_addr_t end; int idx; int nr_sections; struct pasr_section section[PASR_MAX_SECTION_NR_PER_DIE]; u16 mem_reg; /* Either MR16 or MR17 */ void (*apply_mask)(u16 *mem_reg, void *cookie); void *cookie; }; /** * struct pasr_map - Represent the DDR physical map * * @nr_dies: Number of DDR dies. * @die: Table of the dies. */ struct pasr_map { int nr_dies; struct pasr_die die[PASR_MAX_DIE_NR]; }; #define for_each_pasr_section(i, j, map, s) \ for (i = 0; i < map.nr_dies; i++) \ for (s = &map.die[i].section[0], j = 0; \ j < map.die[i].nr_sections; \ j++, s = &map.die[i].section[j]) /** * pasr_register_mask_function() * * @die_addr: Physical base address of the die. * @function: Callback function for applying the DDR PASR mask. * @cookie: Private data called with the callback function. * * This function is to be called by the platform specific PASR driver in * charge of application of the PASR masks. */ int pasr_register_mask_function(phys_addr_t die_addr, void *function, void *cookie); /** * pasr_put() * * @paddr: Physical address of the freed memory chunk. * @size: Size of the freed memory chunk. * * This function is to be placed in the allocators when memory chunks are * inserted in the free memory pool. * This function has only to be called for unused memory, otherwise retention * cannot be guaranteed. */ void pasr_put(phys_addr_t paddr, u64 size); /** * pasr_get() * * @paddr: Physical address of the allocated memory chunk. * @size: Size of the allocated memory chunk. * * This function is to be placed in the allocators when memory chunks are * removed from the free memory pool. * If pasr_put() is used by the allocator, using this function is mandatory to * guarantee retention. */ void pasr_get(phys_addr_t paddr, u64 size); static inline void pasr_kput(struct page *page, int order) { if (order == MAX_ORDER - 1) pasr_put(page_to_phys(page), PAGE_SIZE << (MAX_ORDER - 1)); } static inline void pasr_kget(struct page *page, int order) { if (order == MAX_ORDER - 1) pasr_get(page_to_phys(page), PAGE_SIZE << (MAX_ORDER - 1)); } int __init early_pasr_setup(void); int __init late_pasr_setup(void); int __init pasr_init_core(struct pasr_map *); #else static inline int pasr_register_mask_function(phys_addr_t die_addr, void *function, void *cookie) { return 0; } #define pasr_kput(page, order) do {} while (0) #define pasr_kget(page, order) do {} while (0) #define pasr_put(paddr, size) do {} while (0) #define pasr_get(paddr, size) do {} while (0) #endif /* CONFIG_PASR */ #endif /* _LINUX_PASR_H */