Peel and chop the onion. If using fresh broccoli, cut off and discard the stems, and cut up the florets into bite-sized pieces. If using frozen broccoli florets, cut them into smaller pieces.
In a large pot, melt the butter over medium heat. Add the onions and cook for three or four minutes, until they begin to soften. Sprinkle the flour over the onions and stir to mix, cooking for one minute. Slowly whisk in the milk and half and half.
Add in the broccoli and stir in the salt, pepper, garlic powder, and red pepper flakes. Cover the pot until it starts to simmer. Remove the lid, lower the heat, and let the broccoli simmer for 30 minutes, or until it is tender, stirring occasionally. While the broccoli is cooking, shred the cheddar and grate the Parmesan, if needed.
When the broccoli is tender, add 2 ¼ cups cheddar to the pot a handful at a time, stirring after each addition until the cheese melts. Stir in the Parmesan.
Use a potato masher to break up the broccoli a bit for a slightly chunky soup. If you want a smoother soup, use an immersion blender or regular blender. (See notes.)
In your pot, whisk chicken stock into the broccoli-cheddar soup over low heat. The soup is ready when it's heated through.
Serve the soup topped with the reserved shredded cheddar and additional red pepper flakes at the table. Store leftovers in the refrigerator for up to four days.
Notes
We prefer the soup a little chunky and find that a potato masher produces the best texture. If you want a smoother soup but don't have an immersion blender, you can puree it in a regular blender. You'll have to do it in two batches to fit.